Converting QAudioFormat::SampleFormat::FLoat to QAudioFormat::SampleFormat::Int32

42 views Asked by At

I am writing a QT multimedia audio test application. As part of the application, I need to process each audio sample from the microphone directly. The audio source device signals QAudioBuffer's at regular capture intervals containing audio data in different formats, I am having trouble converging the QAudioFormat::SampleFormat::FLoat format to QAudioFormat::SampleFormat::Int32 but I am not sure how. The float values are 32 bit IEEE floats. The code below shows my in place conversion to 24 bit PCM audio. Note that I am actually converting to big endian as the datagrams containing the audio data are for RTP packets which need to be in big endian order.

// sample conversion
void
in_place_reorder(std::span<uint8_t> buffer, const QAudioFormat& rFormat)
{
    if constexpr (std::endian::native == std::endian::little) {
        switch (rFormat.sampleFormat()) {
        case QAudioFormat::Float:
            {
                // IEEE 32 bit float
                const auto audio_float = std::span<float>{
                    reinterpret_cast<float*>(buffer.data()),
                    buffer.size_bytes() >> 2
                };
                auto audio_int32 = std::span<uint32_t>{
                    reinterpret_cast<uint32_t*>(buffer.data()),
                    buffer.size_bytes() >> 2
                };

                for (auto i=0u; i<audio_float.size(); ++i) {
                    const auto temp = audio_float[i] * (1<<23);
                    //temp *= (1 << 23);
                    audio_int32[i] = std::byteswap(
                        static_cast<int32_t>(temp));
                }
            }
            break;
        case QAudioFormat::Int32:
            {
                // signed pcm32 or float (32 bit)
                auto audio = std::span<uint32_t>{
                    reinterpret_cast<uint32_t*>(buffer.data()),
                    buffer.size_bytes()>>2
                };
                // convert 32 bit audio to 24 bit (with MSByte set to 0's)
                for (auto& next : audio) {
                    // native math before byte swapping
                    next >>= 8;
                    next = std::byteswap(next);
                }
            }
            break;
        case QAudioFormat::Unknown:
            {
                // APT-X audio 3 byte packed
                for (auto i = 0u; i < buffer.size_bytes(); i+=3) {
                    std::swap(buffer[i], buffer[i + 2]);
                }
            }
            break;
        case QAudioFormat::SampleFormat::Int16:
            {
                auto audio = std::span<uint16_t>{
                    reinterpret_cast<uint16_t*>(buffer.data()),
                    buffer.size_bytes()>>1
                };
                for (auto& next : audio) {
                    next = std::byteswap(next);
                }
            }
            break;
        case QAudioFormat::UInt8:
        case QAudioFormat::NSampleFormats:
        default:
            break;
        }
    }
};
0

There are 0 answers