Converting 16-bit short to 32 bit float

1.6k views Asked by At

In the tone generator example for iOS:http://www.cocoawithlove.com/2010/10/ios-tone-generator-introduction-to.html

I am trying to convert a short array to Float32 in 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];
        }

For some reasons, I am hearing an added noise when played back from the speaker. I think that there is a problem with conversion from short to Float32?

2

There are 2 answers

1
marko On BEST ANSWER

Yes, there is.

Consider that the value-range for floating point samples is -1.0 <= Xn <= 1.0 and for signed short is -32767 <= Xn <= +32767. Merely casting will result in clipping on virtually all samples.

So taking this into account:

    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;
    }

[Note: this is not the optimal way of doing this].

However, are you sure your frames are mono? If not this might also be a cause of audio corruption as you'll only be copying one channel.

As an aside, why, if your output buffer is floats are you not using them throughout?

0
possen On

Here is a swift version.

    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 }
    }