2011-10-06 13 views
9

¿Cómo puedo generar sonido de una frecuencia particular en C/C++. Ejecuto Ubuntu 10.04 y uso gcc. Hay una función void sound(int frequency) en TurboC para Windows. ¿Hay un equivalente para gcc?Generando sonido de una frecuencia particular usando gcc en ubuntu?

+0

'sox' debe ser una palabra para buscar, ya que es una forma de generar sonido en Linux. De la Wikipedia: "En los sistemas de tipo Unix, SoX (como el comando de reproducción) comúnmente se proporciona como el reproductor de archivos de audio del sistema". – heltonbiker

+0

Votación para cerrar como herramienta rec, ya que este tipo de cosas está fuera de los ámbitos estándar ISO C/C++ actuales, por lo que se reduce a "qué biblioteca se puede usar". Versión de SDL: http://stackoverflow.com/questions/10110905/simple-wave-generator-with-sdl-in-c –

Respuesta

11

A continuación se muestra un código que utiliza la biblioteca de PortAudio para generar una onda de audio cuadrada de frecuencia determinada. En Linux compilar con gcc buzzer.c -o buzzer -lportaudio. Debe compilar bien para Windows también. No sé cómo se comporta exactamente el sound(int frequency), pero a continuación debería poder simular el uso de zumbadores antiguos. Es posible que necesite un paquete portaudio-devel (o equivalente para Ubuntu, portaudio-dev?) Y para Pulse Audio tal vez una versión más nueva de PortAudio que se encuentre en su repositorio. Compilarlo no es un problema. Puede utilizar el siguiente código en los términos de la licencia WTFPL. :-) (se deriva de un ejemplo de PortAudio)

#include <stdio.h> 
#include <math.h> 
#include "portaudio.h" 
#include <stdint.h> 
#include <unistd.h> // for usleep() 

#define SAMPLE_RATE (44100) 
#define FRAMES_PER_BUFFER (64) 

typedef struct 
{ 
    uint32_t total_count; 
    uint32_t up_count; 

    uint32_t counter; 
    uint32_t prev_freq; 
    uint32_t freq; 
} paTestData; 

//volatile int freq = 0; 

/* This routine will be called by the PortAudio engine when audio is needed. 
** It may called at interrupt level on some machines so don't do anything 
** that could mess up the system like calling malloc() or free(). 
*/ 
static int patestCallback(const void *inputBuffer, void *outputBuffer, 
          unsigned long framesPerBuffer, 
          const PaStreamCallbackTimeInfo* timeInfo, 
          PaStreamCallbackFlags statusFlags, 
          void *userData) 
{ 
    paTestData *data = (paTestData*)userData; 
    uint8_t *out = (uint8_t*)outputBuffer; 
    unsigned long i; 
    uint32_t freq = data->freq; 

    (void) timeInfo; /* Prevent unused variable warnings. */ 
    (void) statusFlags; 
    (void) inputBuffer; 

    for(i=0; i<framesPerBuffer; i++) 
    { 
     if(data->up_count > 0 && data->total_count == data->up_count) { 
      *out++ = 0x00; 
      continue; 
     } 
     data->total_count++; 

     if(freq != data->prev_freq) { 
      data->counter = 0; 
     } 

     if(freq) { 
      int overflow_max = SAMPLE_RATE/freq; 
      uint32_t data_cnt = data->counter % overflow_max; 
      if(data_cnt > overflow_max/2) 
       *out++ = 0xff; 
      else { 
       *out++ = 0x00; 
      } 
      data->counter++; 
     } 
     else { 
      data->counter = 0; 
      *out++ = 0; 
     } 
     data->prev_freq = freq; 
    } 

    return paContinue; 
} 

static PaStream *stream; 
static paTestData data; 


void buzzer_set_freq(int frequency) 
{ 
    data.up_count = 0; // do not stop! 
    data.freq = frequency; 
} 

void buzzer_beep(int frequency, int msecs) 
{ 
    data.total_count = 0; 
    data.up_count = SAMPLE_RATE * msecs/1000; 
    data.freq = frequency; 
} 

int buzzer_start(void) 
{ 
    PaStreamParameters outputParameters; 

    PaError err; 
    int i; 

    err = Pa_Initialize(); 
    if(err != paNoError) goto error; 

    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ 
    outputParameters.channelCount = 1;  /* stereo output */ 
    outputParameters.sampleFormat = paUInt8; /* 32 bit floating point output */ 
    outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency; 
    outputParameters.hostApiSpecificStreamInfo = NULL; 

    err = Pa_OpenStream(
     &stream, 
     NULL, /* no input */ 
     &outputParameters, 
     SAMPLE_RATE, 
     FRAMES_PER_BUFFER, 
     paClipOff,  /* we won't output out of range samples so don't bother clipping them */ 
     patestCallback, 
     &data); 
    if(err != paNoError) goto error; 

    err = Pa_StartStream(stream); 
    if(err != paNoError) goto error; 

    return err; 
error: 
    Pa_Terminate(); 
    fprintf(stderr, "An error occured while using the portaudio stream\n"); 
    fprintf(stderr, "Error number: %d\n", err); 
    fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err)); 
    return err; 

} 

int buzzer_stop() 
{ 
    PaError err = 0; 
    err = Pa_StopStream(stream); 
    if(err != paNoError) goto error; 

    err = Pa_CloseStream(stream); 
    if(err != paNoError) goto error; 

    Pa_Terminate(); 

    return err; 
error: 
    Pa_Terminate(); 
    fprintf(stderr, "An error occured while using the portaudio stream\n"); 
    fprintf(stderr, "Error number: %d\n", err); 
    fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err)); 
    return err; 
} 
void msleep(int d){ 
    usleep(d*1000); 
} 
int main(void) 
{ 

    // notes frequency chart: http://www.phy.mtu.edu/~suits/notefreqs.html 

    buzzer_start(); 
    buzzer_set_freq(261); 
    msleep(250); 
    buzzer_set_freq(293); 
    msleep(250); 
    buzzer_set_freq(329); 
    msleep(250); 
    buzzer_set_freq(349); 
    msleep(250); 
    buzzer_set_freq(392); 
    msleep(250); 
    buzzer_set_freq(440); 
    msleep(250); 
    buzzer_set_freq(494); 
    msleep(250); 
    buzzer_beep(523, 200); 
    msleep(250); 

    buzzer_stop(); 

    return 0; 
} 
+0

LOL en la licencia. Esta es la primera vez que lo veo. Por cierto buen ejemplo (un poco largo) –

+0

no importa cuánto tiempo está cuando está listo para usar y funciona de inmediato - no es necesario repararlo – NickSoft

+0

He estado buscando siempre algo como esto. ¡Gracias! –

Cuestiones relacionadas