Audio Encoding conversion problems with PCM 32-bit yo PCM 16-bit
<p>I am using C# in Universal Windows App to write a Watson Speech-to-text service.
For now instead of using the Watson service, I write to the file and then read it in the Audacity to confirm it is in the right format since Watson service wasn't returning correct responses to me, and the following explains why.</p>

<p>For some reason when I create 16-bit PCM encoding properties, and read buffer, I am only able to read data as 32-bit PCM, and it's working well, but if I read it in 16-bit PCM it is in slow motion, and all the speech is basically corrupted.</p>

<p>I don't really know what exactly needs to be done to convert from 32-bit to 16-bit, but here's what I have in my C# application:</p>

<pre><code>//Creating PCM Encoding properties
var pcmEncoding = AudioEncodingProperties.CreatePcm(16000, 1, 16);
var result = await AudioGraph.CreateAsync(
    new AudioGraphSettings(AudioRenderCategory.Speech)
    {
        DesiredRenderDeviceAudioProcessing = AudioProcessing.Raw,
        AudioRenderCategory = AudioRenderCategory.Speech,
        EncodingProperties = pcmEncoding
    }
);
graph = result.Graph;

//Initialize microphone
var microphone = await DeviceInformation.CreateFromIdAsync(MediaDevice.GetDefaultAudioCaptureId(AudioDeviceRole.Default));
var micInputResult = await graph.CreateDeviceInputNodeAsync(MediaCategory.Speech, pcmEncoding, microphone);

//Create frame output node
frameOutputNode = graph.CreateFrameOutputNode(pcmEncoding);

//Callback function to fire when buffer is filled with data
graph.QuantumProcessed += (s, a) =&gt; ProcessFrameOutput(frameOutputNode.GetFrame());
frameOutputNode.Start();

//Make the microphone write into the frame node
micInputResult.DeviceInputNode.AddOutgoingConnection(frameOutputNode);
micInputResult.DeviceInputNode.Start();

graph.Start();
</code></pre>

<p>Initialization step is done at this stage. Now, actually reading from the buffer and writing to the file is only working if I use 32-bit PCM encoding with the following function (commented out is the PCM 16-bit code that is resulting in a slow motion speech output):</p>

<pre><code>private void ProcessFrameOutput(AudioFrame frame)
{
    //Making a copy of the audio frame buffer
    var audioBuffer = frame.LockBuffer(AudioBufferAccessMode.Read);
    var buffer = Windows.Storage.Streams.Buffer.CreateCopyFromMemoryBuffer(audioBuffer);
    buffer.Length = audioBuffer.Length;

    using (var dataReader = DataReader.FromBuffer(buffer))
    {
        dataReader.ByteOrder = ByteOrder.LittleEndian;

        byte[] byteData = new byte[buffer.Length];
        int pos = 0;

        while (dataReader.UnconsumedBufferLength &gt; 0)
        {
            /*Reading Float -&gt; Int 32*/
            /*With this code I can import raw wav file into the Audacity
              using Signed 32-bit PCM Encoding, and it is working well*/
            var singleTmp = dataReader.ReadSingle();
            var int32Tmp = (Int32)(singleTmp * Int32.MaxValue);
            byte[] chunkBytes = BitConverter.GetBytes(int32Tmp);
            byteData[pos++] = chunkBytes[0];
            byteData[pos++] = chunkBytes[1];
            byteData[pos++] = chunkBytes[2];
            byteData[pos++] = chunkBytes[3];

            /*Reading Float -&gt; Int 16 (Slow Motion)*/
            /*With this code I can import raw wav file into the Audacity
              using Signed 16-bit PCM Encoding, but when I play it, it's in
              a slow motion*/
            //var singleTmp = dataReader.ReadSingle();
            //var int16Tmp = (Int16)(singleTmp * Int16.MaxValue);
            //byte[] chunkBytes = BitConverter.GetBytes(int16Tmp);
            //byteData[pos++] = chunkBytes[0];
            //byteData[pos++] = chunkBytes[1];
        }

        WriteBytesToFile(byteData);
    }
}
</code></pre>

<p>Can anyone think of a reason why this is happening? Is it because Int32 PCM is larger in size and when I use Int16, it extends it and makes the sound longer? Or am I not sampling it properly?</p>

<p>Note: I tried reading Bytes directly from the buffer, and then using that as a raw data, but it's not encoded as PCM that way.
Reading Int16/32 from the buffer directly also doesn't work.
In the above example I am only using Frame Output node. IF I create a file output node that automatically writes to the raw file, it works really well as 16-bit PCM, so something is wrong in my callback function that causes it to be in a slow motion.</p>

<p>Thanks</p>