C++:将 float[] 转换为 unsigned char* 或 BYTE*

标签 c++ pcm wasapi

我正在开发一个项目,我需要将 PCM 16 位 2 声道声音转换为 IEEE Float 32 位 2 声道。

为此,我使用了以下代码:

void CAudioConverter::ConvI16ToF32(BYTE* pcmFrom, BYTE* floatTo, int length)
{
    short* src = reinterpret_cast<short*>(pcmFrom);
    float* dst = reinterpret_cast<float*>(floatTo);
    for (int n = 0; n < length; n++)
    {
        dst[n] = static_cast<float>(src[n]) / 32768.0f;
    }
}

我已经初始化了变量 __pcm32_bytesPerFrame :

WAVEFORMATEX* closestFormat;
ws->default_pb_dev->GetMixFormat(&closestFormat);
__pcm32_bytesPerFrame = closestFormat->nAvgBytesPerSec * (prm->samples_per_frame * 1000 / (prm->clock_rate * closestFormat->nChannels)) / 1000;

strm->pb_max_frame_count 是:

hr = ws->default_pb_dev->GetBufferSize(&ws->pb_max_frame_count);

我在专用线程中有一个 while 循环,它执行类似以下操作:

hr = strm->default_pb_dev->GetCurrentPadding(&padding);
incoming_frame = __pcm32_bytesPerFrame / 4;
frame_to_render = strm->pb_max_frame_count - padding;
if (frame_to_render >= incoming_frame)
{ 
    frame_to_render = incoming_frame;
} else {
    /* Don't get new frame because there's no space */
    frame_to_render = 0;
}

if (frame_to_render > 0)
{
    pjmedia_frame frame;

hr = strm->pb_client->GetBuffer(frame_to_render, &cur_pb_buf);
if (FAILED(hr)) {
    continue;
}

void* destBuffer = (void*)malloc(strm->bytes_per_frame*frame_to_render*sizeof(pj_uint16_t));

if (strm->fmt_id == PJMEDIA_FORMAT_L16) {



/* PCM mode */
    frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
    frame.size = strm->bytes_per_frame;
    frame.timestamp.u64 = strm->pb_timestamp.u64;
    frame.bit_info = 0;
    frame.buf = destBuffer;
}

status = (*strm->pb_cb)(strm->user_data, &frame);

CAudioConverter* conv = new CAudioConverter();
conv->ConvI16ToF32((BYTE*)destBuffer, cur_pb_buf, frame_to_render);

hr = strm->pb_client->ReleaseBuffer(frame_to_render, 0);
(...)

但是,要将声音发送到 WASAPI 捕获缓冲区,我需要一个 BYTE*。 如何填充我的“floatTo”参数?

有什么想法吗?

谢谢

最佳答案

这个怎么样:

void CAudioConverter::ConvI16ToF32(BYTE* pcmFrom, BYTE* floatTo, int length)
{
    short* src = reinterpret_cast<short*>(pcmFrom);
    float* dst = reinterpret_cast<float*>(floatTo);
    for (int n = 0; n < length; n++)
    {
        dst[n] = static_cast<float>(src[n]) / 32768.0f;
    }   
}

另外确保 length 指示 pcmFromfloatTo 中的元素数,而不是分配的字节数。在你的情况下,pcmFrom 应该分配了 length*2 字节,而 floatTo 需要 length*4 字节的空间。

关于C++:将 float[] 转换为 unsigned char* 或 BYTE*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22663480/

相关文章:

c++ - 当我使用线程时,Breakpad 无法在目标上创建小型转储

c++ - Windows GUI 以及控制台应用程序

c++ - 带有内存定位文件的 FFmpeg avformat_open_input

java - 以 double 格式转换有符号整数(2 字节,16 位)。使用Java

windows - 如何在Windows 7中更改音频输出设备的默认共享模式采样率?

c++ - 成员是私有(private)的,C++ 中的运算符重载

python - Distutils:构建共享一个方法的多个Python扩展模块(用Swig编写)

WAV 音频格式 : MPEG3 to PCM

c++ - WASAPI 何时添加了对 AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM 的支持?

c# - 录制和混合音频时,NAudio的BufferedWaveProvider变满