C++ 将SDL F32字节转换为样本[-1.0-1.0]会产生静态噪声

C++ 将SDL F32字节转换为样本[-1.0-1.0]会产生静态噪声,c++,floating-point,sdl-2,C++,Floating Point,Sdl 2,我正在尝试将SDL2音频设备的麦克风输入转换为浮点采样。目前我得到的是静态-不是一致的静态-而是响应麦克风输入的静态 所以,当麦克风未被通话时,不会有静电干扰。使用麦克风时,静态会跟随短语和动态变化。我觉得我真的很接近让它工作,但我做了一些(可能是明显的)错误 我正在SDL中设置音频设备,如下所示: SDL_AudioSpec as; as.freq = aSamplerate; as.format = AUDIO_F32; as.channels = 1; as.samples = aBuff

我正在尝试将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);
  • gActiveAudioSpec是从SDL返回的“正确”规范
  • audioHoldingPattern实际上是回调上我的音频缓冲区的保留模式(如下所示)。我需要这样的东西,因为我正在使用一个库(SoLoud),它请求缓冲区,而不是接受缓冲区。最新的缓冲区保存在这里,直到它被发送回SoLoud
这就是我在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);
}
unsigned int-MicrophoneInstance::getAudio(float*aBuffer,unsigned int-aSamplesToRead,unsigned int-aBufferSize)
{       
int size=aBufferSize;
浮动*信号=重新解释(音频保持模式);
memcpy(aBuffer、signal、aBufferSize);
返回(无符号整数)sizeof(信号);
}
  • aBuffer是SoLoud提供的用于复制的缓冲区

请帮忙

您的帖子中没有足够的信息来帮助您。设置SDL音频上下文时,您已经指定了预期的音频格式(可能是16位、小尾端、带符号)。它可以是像S16LE或U16LE或

一旦您在代码中找到了这一点,您将需要首先将接收到的缓冲区转换为请求的格式,然后以浮点形式计算值

例如,如果音频缓冲区格式为S16LE(有符号16位little endian),并且您在little endian机器上(很可能),那么您将执行以下操作:

   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
   }

Int16示例;//数据范围为+32767-32768或~+/-1