正在运行的函数暂停父函数

发布于 2024-08-06 01:15:50 字数 4657 浏览 3 评论 0原文

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

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

我指的代码是lattus函数和noise函数。

以下是我的程序的完整源代码:

#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
}

hey there, just practising and I had a question. I have a program (source below) that prints out a wave in text. when the wave hits the outside of the terminal I have it make a noise with a function called noise(). but when that function is called it pauses the animation until it completes making the noise, then the animation starts again.

I was wondering if anyone knew of a way for the two functions to happen at the same time. should I fork() it or is there a better way?

the code I'm refering to is the lattus function and the noise function.

bellow is the full source to my program:

#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
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

故事↓在人 2024-08-13 01:15:50

显然 ao_play 处于阻塞状态,因此您需要一个线程或分叉进程。我不知道分叉的延迟(对于您的目的而言,它可能相当低),但线程显然更适合。

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

Clearly ao_play is blocking, so you'd need a thread or forked process. I don't know the latency of forking (it's probably pretty low for your purposes), but threads are clearly a better fit.

You'd eventually want to consider mixing if new "play sound" events can overlap with the active sound's duration. Especially if overlapping sounds are possible, I'd have a dedicated fork or thread that is the only one to call ao_play, and send messages to it, rather than launching a new fork or thread each time.

诗酒趁年少 2024-08-13 01:15:50

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

I would suggest threading using pthreads and using a condition variable to sync your audio to the edge collision.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文