Преобразование 16-битного короткого в 32-битное с плавающей точкой

В примере генератора тона для iOS: http://www.cocoawithlove.com/2010/10/ios-tone-generator-introduction-to.html

Я пытаюсь преобразовать короткий массив в Float32 в iOS.

        Float32 *buffer = (Float32 *)ioData->mBuffers[channel].mData;
        short* outputShortBuffer = static_cast<short*>(outputBuffer);

        for (UInt32 frame = 0, j=0; frame < inNumberFrames; frame++, j=j+2)
        {
            buffer[frame] =  outputShortBuffer[frame];
        }

По некоторым причинам я слышу дополнительный шум при воспроизведении из динамика. Я думаю, что есть проблема с преобразованием из короткого в Float32?

2 ответа

Решение

Да, есть.

Учтите, что диапазон значений для выборок с плавающей запятой -1.0 <= Xn <= 1.0 и для signed short является -32767 <= Xn <= +32767, Простое приведение приведет к отсечению практически всех образцов.

Итак, принимая это во внимание:

    Float32 *buffer = (Float32 *)ioData->mBuffers[channel].mData;
    short* outputShortBuffer = static_cast<short*>(outputBuffer);

    for (UInt32 frame = 0, j=0; frame < inNumberFrames; frame++, j=j+2)
    {
        buffer[frame] =  ((float) outputShortBuffer[frame]) / 32767.0f;
    }

[Примечание: это не оптимальный способ сделать это].

Тем не менее, вы уверены, что ваши кадры моно? В противном случае это также может быть причиной повреждения звука, поскольку вы будете копировать только один канал.

Кроме того, почему, если ваш выходной буфер floatВы не используете их повсюду?

Вот быстрая версия.

          let floatBuffer = UnsafeMutableBufferPointer<Float32>(start: buffer.floatChannelData![0], count: frameLength)
    data.withUnsafeBytes { (bytes: UnsafeRawBufferPointer) in
        let int16Buffer = bytes.bindMemory(to: Int16.self)
        let float32Buffer = UnsafeMutableBufferPointer(start: floatBuffer.baseAddress, count: floatBuffer.count)
        (0..<frameLength).forEach { float32Buffer[$0] = Float32(int16Buffer[$0]) / 32767.0 }
    }
Другие вопросы по тегам