2011-10-06 12 views
9

C/C++で特定の周波数のサウンドを生成する方法を教えてください。私はUbuntu 10.04を使い、gccを使います。 TurboC for Windowsにはvoid sound(int frequency)の機能があります。 gccに相当するものはありますか?ubuntuでgccを使って特定の周波数のサウンドを生成していますか?

+0

'sox'は、Linux上でサウンドを生成する方法であるため、探したい単語にする必要があります。 Wikipediaより:「Unixライクなシステムでは、SoX(再生コマンドとして)がシステムオーディオファイルプレーヤーとして一般的に提供されています。 – heltonbiker

+0

このようなものは現在のISO C/C++標準スコープの外にあるので、ツールレックとして閉じることに投票するので、「どのライブラリを使用できるか」になります。 SDLバージョン:http://stackoverflow.com/questions/10110905/simple-wave-generator-with-sdl-in-c –

答えて

11

以下は、指定された周波数の方形波を生成するPortAudioライブラリを利用したコードです。 Linuxの場合、gcc buzzer.c -o buzzer -lportaudioでコンパイルしてください。 Windowsの場合も同様にコンパイルする必要があります。私はsound(int frequency)がどのように正確に動作するのかわかりませんが、古いスタイルのブザーの使用をシミュレートできるはずです。 portaudio-devel(またはUbuntuの場合はportaudio-dev?)パッケージが必要かもしれませんし、Pulse Audioの場合、あなたのレポにあるPortAudioの新しいバージョンかもしれません。それをコンパイルすることは問題ではありません。以下のコードをWTFPLライセンスの条件で使用することができます。 :-)(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。これは私が初めて見る時です。 btw良い例(ちょっと長い) –

+0

すぐに使えるようになってすぐに動く時間は問題ありません。修理は必要ありません – NickSoft

+0

私はこのようなことを永遠に見てきました。ありがとう! –

関連する問題