[英]Converting SDL F32 Bytes to samples [-1.0 - 1.0] results in static noise
我正在嘗試將來自 SDL2 音頻設備的麥克風輸入轉換為浮點樣本。 目前我得到了靜態 -不是一致的靜態- 而是響應麥克風輸入的靜態。
因此,當麥克風不被通話時,不會聽到靜電聲。 當麥克風是時,靜態跟隨短語和動態變化。 我覺得我真的快要讓它工作了,但我做錯了(可能很明顯)。
我在 SDL 中設置音頻設備如下:
SDL_AudioSpec as;
as.freq = aSamplerate;
as.format = AUDIO_F32;
as.channels = 1;
as.samples = aBuffer;
as.callback = _sdl_cb;
as.userdata = (void*)aSoloud;
gAudioDeviceID = SDL_OpenAudioDevice(NULL, 1, &as, &gActiveAudioSpec, SDL_AUDIO_ALLOW_ANY_CHANGE & ~(SDL_AUDIO_ALLOW_FORMAT_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE));
if (gAudioDeviceID == 0)
{
as.format = AUDIO_S16;
gAudioDeviceID = SDL_OpenAudioDevice(NULL, 1, &as, &gActiveAudioSpec, SDL_AUDIO_ALLOW_ANY_CHANGE & ~(SDL_AUDIO_ALLOW_FORMAT_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE));
if (gAudioDeviceID == 0)
{
return UNKNOWN_ERROR;
}
}
//Calculate per sample bytes
int bytesPerSample = gActiveAudioSpec.channels * ( SDL_AUDIO_BITSIZE( gActiveAudioSpec.format ) / 8 );
gBufferByteSize = bytesPerSample * aBuffer;
audioHoldingPattern = new Uint8[ gBufferByteSize ];
memset( audioHoldingPattern, 0, gBufferByteSize );
SDL_PauseAudioDevice(gAudioDeviceID, 0);
這就是我在 SDL 回調中所做的:
static void _sdl_cb(void * userdata, Uint8 * pcm, int len){
if (SDL_GetAudioDeviceStatus(gAudioDeviceID) == SDL_AUDIO_PLAYING) {
memcpy( &audioHoldingPattern[0], pcm, len );
}
}
這就是 SoLoud 從以下位置請求新緩沖區的地方:
unsigned int MicrophoneInstance::getAudio(float* aBuffer, unsigned int aSamplesToRead, unsigned int aBufferSize)
{
int size = aBufferSize;
float *signal = reinterpret_cast<float*>(audioHoldingPattern);
memcpy(aBuffer, signal, aBufferSize);
return (unsigned int)sizeof(signal);
}
請幫忙!
您的帖子中沒有足夠的信息來幫助您。 當您設置 SDL 音頻上下文時,您已經指定了預期的音頻格式(可能是 16 位、小端、有符號)。 它可以是像 S16LE 或 U16LE 或...
一旦您在代碼中發現了這一點,您首先需要將接收到的緩沖區轉換為所要求的格式,然后以浮點形式計算該值。
例如,如果音頻緩沖區格式是 S16LE(有符號的 16 位小端)並且您使用的是小端機器(很可能),那么您將執行以下操作:
Int16 sample; // Range of data is +32767 -32768 or ~ +/- 1<<15 - 1
float scale = (float)(1.0 / (double)(1 << (sizeof(sample) - 1)));
for (int i = 0; i < len; i += sizeof(sample))
{
memcpy(&sample, &pcm[i], sizeof(sample)); // Use this so it'll work on machine that don't allow non-aligned access to char buffers
float s = sample * scale;
[...] // Do whatever you want with s
}
編輯:您的代碼有問題。 首先,您請求 32 位浮點樣本(行as.format = AUDIO_F32;
並首先調用SDL_OpenAudioDevice
)。 然后,如果它失敗了,你會像上面的例子一樣要求 S16(有符號的 16 位)。 問題是你沒有跟蹤你會得到什么格式(它是浮動的嗎?是 S16 嗎?)。
因此,要么使用 F32 格式刪除第一個調用,只保留 S16 格式(並使用上面的代碼進行轉換)。 或者,將接受的格式存儲在某處並根據接受的格式采取不同的行動。
在 F32 的情況下,您可以通過如下轉換將pcm
變量轉換為float*
: float * buffer = (float*)pcm;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.