0

我正在编写一个使用低延迟 ASIO 卡获取声音数据的应用程序。低延迟意味着我每批只能得到 128 个样本,采样率为 48k。从 ASIO 卡中,我得到 32 位有符号整数范围内的原始样本。

现在我想听从 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 可以播放的内容?

4

1 回答 1

0

问题是由于我使用的比特率与我被认为使用的不同。当我用正确的值修改 WAVEFORMATEX 时,它起作用了!

于 2012-06-06T22:33:34.150 回答