0

嘿那里,只是练习,我有一个问题。我有一个程序(下面的源代码)可以打印出文本中的波形。当波击中终端外部时,我让它用一个名为noise()的函数发出噪音。但是当调用该函数时,它会暂停动画,直到它完成发出噪音,然后动画再次开始。

我想知道是否有人知道两种功能同时发生的方法。我应该 fork() 它还是有更好的方法?

我指的代码是lattus函数和噪声函数。

下面是我的程序的完整来源:

#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <ao/ao.h>
#include <math.h>

#define BUF_SIZE 4096

int main (int argc, char *argv[]) {     //check for whitch effect to print
    int i = argc;
    for(i > 0; i--;) {
        switch(*argv[i]) {
            case '1':
                lattus();
                break;
            case '2':
                normal();
                break;
            case '3':
                noise(50);
                break;
            default:
                break;
        }
    }
}


char *randstring (char *buffer, int length) {       //genertate a random number
    int i = length;
    for(i >= 0; i--;) {
        buffer[i] = (rand() % 2) ? '1' : '0';
    }
    buffer[length] = 0;
    return buffer;
}

int normal(){           // normal drawing of 1's and 0's
    struct winsize w;
    ioctl(0, TIOCGWINSZ, &w);
    int width = w.ws_col;
    int height = w.ws_row;      //get terminal width and height
    char buffer[width*height + 1];  //create a buffer big enough to hold one draw to the screen
    int i = 25;
    while(i-- >= 0) {
        printf("%s\n", randstring(buffer, width*height));   //draw to screen
        usleep(50000);
    }
    system("clear");        //clear screen
}

int noise(int pitch) {
    int second = 1;
    int freq = (second * pitch);
    ao_device *device;
    ao_sample_format format;
    int default_driver;
    char *buffer;
    int buf_size;
    int sample;
    ao_initialize();
    default_driver = ao_default_driver_id();    
    format.bits = 16;
    format.channels = 2;
    format.rate = 44100;
    format.byte_format = AO_FMT_LITTLE;
    buf_size = format.bits/8 * format.channels * format.rate;
    int b = 10;
    device = ao_open_live(default_driver, &format, NULL /* no options */);
    buffer = calloc(buf_size, sizeof(char));
    for (b = 0; b < format.rate; b++) {
        sample = (int)(1 * 532768.0 * sin(2 * M_PI * freq * ((float) b/format.rate)));
        /* Put the same stuff in left and right channel */
        buffer[2 * b] = buffer[2*b+2] = sample & 0xff;
        buffer[2*b+1] = buffer[2*b+3] = (sample >> 8) & 0xff;
    }
    ao_play(device, buffer, buf_size);
    buffer = 0;
    ao_shutdown();
}

int lattus (void) {
    struct winsize w;
    ioctl(0, TIOCGWINSZ, &w);
    int width = w.ws_col;       //get the terminal width
    char *buffer1 = malloc(sizeof(char) * (width + 1)); //create 3 buffers for each segment
    char *buffer2 = malloc(sizeof(char) * (width + 1)); //each big enough to hold the width of the terminal
    char *buffer3 = malloc(sizeof(char) * (width + 1));
    int first = 1;          //how many before the space
    int second = width - 8;     //how many in the middle of the space
    int third = 1;          //how many at the end of the space
    int i = 1000;           //draw 1000 lines
    int on = 0;         //switch for growing and shrinking
    while(i-- >= 0) {
        usleep(9000);
        if(first == 1 && third == 1 && second == width - 8 || second == width - 9) {    //is it at min?
            if(second % 2 == 0) {       //is it an even number (had problems with buffer if it was odd)
                second = second - 2;
            } else {
                second = second - 3;
            }
            first ++;
            third ++;
            on = 0;     //keep growing
            noise(10);  //make lower noise
        } else if(first == (width - 8) / 2 && third == (width - 8) / 2 && second == 2) {    //untill it gets to max
            if(second % 2 == 0) {
                second = second + 2;
            } else {
                second = second + 1;
            }
            third --;
            first --;
            on = 1;     //start shrinking
            noise(30);  //make higher noise
        } else if(on == 0) {    //else if suppost to grow, grow
            second = second - 2;
            third ++;
            first ++;
        } else if(on == 1) {    //else if suppost to shrink shrink
            second = second + 2;
            third --;
            first --;
        } else {
            break;
        }
        printf("%s   %s   %s\n", randstring(buffer1, first), randstring(buffer2, second), randstring(buffer3, third));  //print it out
        //wait();
    }
    system("clear"); //clear screen
}
4

2 回答 2

1

我建议使用pthreads进行线程化并使用条件变量将您的音频同步到边缘碰撞。

于 2009-09-19T01:21:47.257 回答
1

显然ao_play是阻塞的,所以你需要一个线程或分叉进程。我不知道分叉的延迟(对于您的目的来说它可能相当低),但线程显然更适合。

如果新的“播放声音”事件可以与活动声音的持续时间重叠,您最终会考虑混合。特别是如果重叠声音是可能的,我将有一个专用的分支或线程,它是唯一调用 ao_play 并向其发送消息的分支,而不是每次都启动一个新的分支或线程。

于 2009-09-19T01:28:45.193 回答