将24位USB音频流转换为32位流

时间:2017-01-05 17:41:54

标签: audio usb signal-processing

我正在尝试将24位USB音频流转换为32位流,这样我的微控制器外设就可以很快地与流一起播放(它只能像大多数mcus一样处理16或32位数据......)。 p>

以下代码是我从mcu的公司得到的...没有按预期工作,我最终得到了真正扭曲的音频。

// Function takes usb stream and processes the data for our peripherals
// @data         - usb stream data
// @byte_count   - size of stream 
void process_usb_stream(uint8_t *data, uint16_t byte_count) {
     // Etc code that gets buffers ready to read the stream...
     // Conversion here!
     int32_t *buffer;
     int sample_count = 0;
     for (int i = 0; i < byte_count; i += 3) {
         buffer[sample_count++] = data[i] | data[i+1] << 8 | data[i+2] << 16;
     }
     // Send buffer to peripherals for them to use...
}

将数据从24位流转换为32位流的任何帮助都会非常棒!这方面的工作对我来说很难:(

2 个答案:

答案 0 :(得分:1)

这是DSP的东西,如果,也在http://dsp.stackexchange.com

上发布这个问题

在DSP中,改变位深度的过程称为 scaling

  • 16位分辨率具有65536个值
  • 24位分辨率为16777216 可能的值
  • 32位具有4294967296个值,因此因子为256

根据https://electronics.stackexchange.com/questions/229268/what-is-name-of-process-used-to-change-sample-bit-depth/229271 从24位减少到16位称为按比例缩小,并通过将每个值除以256来完成。

这可以通过按位逐位移位8来完成 y = x >> 8。当以这种方式缩小时,LSB丢失

扩展到32位更复杂,有几种方法可以做到这一点。它可以通过将值的每个位乘以2⁰和2⁸之间的值来工作。

将24位值推入32位寄存器,然后将每位左移一个介于2⁰和2⁸之间的值:

data32[31] = data32[23] << 8;
data32[22] = data32[14] << 8;
...
data32[0] = data32[0];

并插入你没有得到的位(线性插值)

也许在http://dsp.stackexchange.com

上有更好的扩展算法问题

另请参阅http://blog.bjornroche.com/2013/05/the-abcs-of-pcm-uncompressed-digital.html了解扩展问题......

答案 1 :(得分:1)

data[...]是一个uint8_t。您需要在转换前强制转换,因为data[...]<<8data[...]<<16未定义。它们要么是0,要么不变,这两者都不是你想要的。

此外,您需要再移动8位以获得全范围,并将符号位置于正确的位置。

此外,您将数据视为小端格式。确保它是。我认为这是正确的,所以这样的事情有效:

 int32_t *buffer;
 int sample_count = 0;
 for (int i = 0; i+3 <= byte_count; ) {
     int32_t v = ((int32_t)data[i++])<<8;
     v |= ((int32_t)data[i++])<<16;
     v |= ((int32_t)data[i++])<<24;
     buffer[sample_count++] = v;
 }

最后请注意,这假设byte_count可以被3整除 - 确保它是真的!