2009-09-19 4 views
0

안녕하세요, 그냥 연습하고 질문이있었습니다. 나는 텍스트의 물결을 출력하는 프로그램 (아래 소스)을 가지고있다. 파도가 터미널 외부에 닿았을 때 나는 noise()라고 불리는 함수로 소리를 낸다. 하지만이 함수를 호출하면 노이즈가 완료 될 때까지 애니메이션이 일시 중지되고 애니메이션이 다시 시작됩니다.실행중인 기능이 부모 기능을 일시 중지

누군가 두 기능이 동시에 발생하는 방법을 알고 있는지 궁금합니다. 내가 그것을 포크()해야합니까, 아니면 더 좋은 방법이 있습니까?

내가 추천하는 코드는 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 
} 

답변

1

분명히 ao_play이 차단 중이므로 스레드 또는 분기 프로세스가 필요합니다. 나는 포킹의 대기 시간을 알지 못하지만 (아마도 당신의 목적을 위해서는 매우 낮을 것입니다.) 스레드는 분명히 더 적합합니다.

새로운 "사운드 재생"이벤트가 활성 사운드의 지속 시간과 겹칠 수 있다면 믹싱을 고려하는 것이 좋습니다. 특히 오버랩 사운드가 가능하다면 ao_play를 호출하고 매번 새로운 포크 나 스레드를 시작하는 대신 메시지를 보내는 유일한 포크 나 쓰레드가 있습니다.

+0

링크를 찾아 주셔서 감사합니다. 아프다. 감사. – austin

+0

나는 질문이있다, 나는 pthreads 일하고있다 그러나 나는 실마리가 어떻게 기능 사이에서 메시지를 보내기에 관하여 갈 것입니다 ... 나는 그것을 어떻게 달성합니까? – austin

+0

pthread 조건 변수가 메시지입니다. 오디오 스레드는 신호를 받기까지 대기합니다 (메시지 수신). 그리기 스레드는 메시지를 보내는 스레드입니다. – mocj

1

내가 pthreads을 사용하고 에지 충돌에 오디오를 동기화 조건 변수를 사용하여 - 쓰레드를 제안 :

울부 짖는 소리는 내 프로그램의 전체 소스입니다.

+0

덕분에 바로 연결되는 – austin

관련 문제