正在运行的函数暂停父函数
嘿,刚刚练习,我有一个问题。我有一个程序(来源如下)可以以文本形式打印出波形。当波击中终端外部时,我用一个名为“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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
显然
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.
我建议使用 pthreads 进行线程化,并使用条件变量将音频同步到边缘碰撞。
I would suggest threading using pthreads and using a condition variable to sync your audio to the edge collision.