2016-09-22 106 views
0

我目前正在嘗試學習音頻編程。我的目標是打開一個wav文件,提取所有內容並用RtAudio播放樣本。RtAudio - 從wav文件播放示例

我做了一個WaveLoader類,讓我提取樣本和元數據。我使用this指南來做到這一點,並且我使用010編輯器檢查了一切正確。這是010編輯器的快照,顯示結構和數據。

010 Editor

這也是我如何存儲WaveLoader類中的原始樣本:

 data = new short[wave_data.payloadSize]; // - Allocates memory size of chunk size 

     if (!fread(data, 1, wave_data.payloadSize, sound_file)) 
     { 
      throw ("Could not read wav data"); 
     } 

如果我打印出每個樣本獲得:1,-3,4,-5 ...這似乎確定。

問題是,我不知道如何玩他們。這是我做了什麼:

/* 
* Using PortAudio to play samples 
*/ 
bool Player::Play() 
{ 
    ShowDevices(); 
    rt.showWarnings(true); 

    RtAudio::StreamParameters oParameters; //, iParameters; 
    oParameters.deviceId = rt.getDefaultOutputDevice(); 
    oParameters.firstChannel = 0; 
    oParameters.nChannels = mAudio.channels; 

    //iParameters.deviceId = rt.getDefaultInputDevice(); 
    //iParameters.nChannels = 2; 

    unsigned int sampleRate = mAudio.sampleRate; 

    // Use a buffer of 512, we need to feed callback with 512 bytes everytime! 
    unsigned int nBufferFrames = 512; 

    RtAudio::StreamOptions options; 
    options.flags = RTAUDIO_SCHEDULE_REALTIME; 
    options.flags = RTAUDIO_NONINTERLEAVED; 

    //&parameters, NULL, RTAUDIO_FLOAT64,sampleRate, &bufferFrames, &mCallback, (void *)&rawData 

    try { 
     rt.openStream(&oParameters, NULL, RTAUDIO_SINT16, sampleRate, &nBufferFrames, &mCallback, (void*) &mAudio); 
     rt.startStream(); 
    } 
    catch (RtAudioError& e) { 
     std::cout << e.getMessage() << std::endl; 
     return false; 
    } 
    return true; 
} 

/* 
* RtAudio Callback 
* 
*/ 
int mCallback(void * outputBuffer, void * inputBuffer, unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void * userData) 
{ 
    unsigned int i = 0; 
    short *out = static_cast<short*>(outputBuffer); 
    auto *data = static_cast<Player::AUDIO_DATA*>(userData); 

    // if i is more than our data size, we are done! 
    if (i > data->dataSize) return 1; 

    // First time callback is called data->ptr is 0, this means that the offset is 0 
    // Second time data->ptr is 1, this means offset = nBufferFrames (512) * 1 = 512 
    unsigned int offset = nBufferFrames * data->ptr++; 

    printf("Offset: %i\n", offset); 
    // First time callback is called offset is 0, we are starting from 0 and looping nBufferFrames (512) times, this gives us 512 bytes 
    // Second time, the offset is 1, we are starting from 512 bytes and looping to 512 + 512 = 1024 
    for (i = offset; i < offset + nBufferFrames; ++i) 
    { 
     short sample = data->rawData[i]; // Get raw sample from our struct 
     *out++ = sample;    // Pass to output buffer for playback 

     printf("Current sample value: %i\n", sample);  // this is showing 1, -3, 4, -5 check 010 editor 
    } 

    printf("Current time: %f\n", streamTime); 
    return 0; 
} 

內的回調函數,當我打印出來的樣本值,我得到酷似010的編輯器?爲什麼沒有rtaudio播放它們。這裏有什麼問題?我是否需要將樣本值歸一化到-1和1之間?

編輯: 我試圖播放的wav文件:

  • CHUNKSIZE:16
  • 格式:1
  • 通道:1
  • 採樣率:48000
  • ByteRate:96000
  • BlockAlign:2
  • BitPerSample:16
  • 原始樣本的總規模:2217044個字節

回答

0

出於某種原因,當我通過輸入參數的OpenStream()

RtAudio::StreamParameters oParameters, iParameters; 
    oParameters.deviceId = rt.getDefaultOutputDevice(); 
    oParameters.firstChannel = 0; 
    //oParameters.nChannels = mAudio.channels; 
    oParameters.nChannels = mAudio.channels; 

    iParameters.deviceId = rt.getDefaultInputDevice(); 
    iParameters.nChannels = 1; 

    unsigned int sampleRate = mAudio.sampleRate; 

    // Use a buffer of 512, we need to feed callback with 512 bytes everytime! 
    unsigned int nBufferFrames = 512; 

    RtAudio::StreamOptions options; 
    options.flags = RTAUDIO_SCHEDULE_REALTIME; 
    options.flags = RTAUDIO_NONINTERLEAVED; 

    //&parameters, NULL, RTAUDIO_FLOAT64,sampleRate, &bufferFrames, &mCallback, (void *)&rawData 

    try { 
     rt.openStream(&oParameters, &iParameters, RTAUDIO_SINT16, sampleRate, &nBufferFrames, &mCallback, (void*) &mAudio); 
     rt.startStream(); 
    } 
    catch (RtAudioError& e) { 
     std::cout << e.getMessage() << std::endl; 
     return false; 
    } 
    return true; 

它是那麼的隨意,當我試圖播放它的工作原理我話筒。我離開輸入參數,我的wav文件突然播放。這是一個錯誤嗎?