2012-04-14 65 views
0

我正在寫一個應用程序,使用低延遲的ASIO卡獲取聲音數據。低等待時間意味着每批只有128個採樣,對於48k採樣率。從ASIO卡,我得到32位有符號整數範圍的原始樣本。waveOutWrite兼容ASIO?

現在我想聽通過ASIO卡發出的聲音,但不是在ASIO卡上,而是在Windows中的默認輸出設備上。我正在使用WAVE_FORMAT_PCM設置waveOutWrite,並使用與ASIO輸入相同的特性。每當我得到一個新的128個樣本的批次時,我都會這樣稱呼它。現在,因爲Wav格式不允許使用32位整數樣本,所以我將它們降級到16位。

HWAVEOUT waveOut; 

void startListening(){ 
    WAVEFORMATEX format; 
    format.wFormatTag = WAVE_FORMAT_PCM; 
    format.nChannels = 1; 
    format.nSamplesPerSec = sampleRate; 
    format.nAvgBytesPerSec = sampleRate * 2; 
    format.nBlockAlign = 2; 
    format.wBitsPerSample = 16; 
    format.cbSize = 0; 
    MMRESULT result = waveOutOpen(waveOut, WAVE_MAPPER, &format, 0, 0, CALLBACK_NULL); 
    if(result != MMSYSERR_NOERROR){ 
     return; 
    } 
} 

typedef struct{ 
    short *buffer; 
    int length; 
    HWAVEOUT waveOut; 
} ListenInfo; 

void newListeningData(void *buffer, int length){ 
    ListenInfo *listenInfo = new ListenInfo(); 
    listenInfo->buffer = new short[length]; 
    listenInfo->length = length; 
    listenInfo->waveOut = *waveOut; 
    if(bitrate == 32){ 
     int *bufferInt = (int *)buffer; 
     for(int i = 0; i < length; i++){ 
      listenInfo->buffer[i] = (bufferInt[i]); 
     } 
     CreateThread(NULL, 0, &(listen), listenInfo, 0, NULL); 
    } 
    else if(bitrate == 16){ 
     memcpy(listenInfo->buffer, (short *)buffer, length * 2); 
     CreateThread(NULL, 0, &(listen), listenInfo, 0, NULL); 
    } 
    else{ 
     printf("%d: Bitrate is not 16 or 32!\n", index); 
    } 
} 

DWORD WINAPI listen(__in LPVOID lpParameter){ 
    ListenInfo *info = (ListenInfo *)lpParameter; 
    WAVEHDR header; 
    memset(&header, 0, sizeof(WAVEHDR)); 
    header.dwBufferLength = info->length; 
    header.lpData = (char *)(info->buffer); 
    MMRESULT result = waveOutPrepareHeader(info->waveOut, &header, sizeof(WAVEHDR)); 
    result = waveOutWrite(info->waveOut, &header, sizeof(WAVEHDR)); 
    while(waveOutUnprepareHeader(info->waveOut, &header, sizeof(WAVEHDR)) == WAVERR_STILLPLAYING){ 
     Sleep(10); 
    } 
    delete[] info->buffer; 
    delete info; 
    return 0; 
} 

問題是,我只能聽到嚴重的剪輯和吱吱聲。聲音扭曲得無法辨認。我知道這不是同步錯誤,因爲我也將樣本保存到具有相同特徵的wav文件中,並且聲音以相同的方式失真。

如何將帶符號的32位樣本轉換爲waveOutWrite可以播放的內容?

+0

您正在複製32位樣本的兩個*最少*有效字節。你還最好檢查它是否不漂浮。 – 2012-04-22 20:34:31

+0

@Hans我意識到了排序,並且我知道我正以小端語言獲取數據。這裏應該沒問題。 – 2012-04-22 20:38:28

回答

0

這個問題是由於我使用了不同的比特率而導致我相信我正在使用這個事實。當我用正確的值修改WAVEFORMATEX時,它工作正常!