How to convert or play AAC-LC file in windows forms, with C#?

62 Views Asked by At

I am using OpenAIs Text to speech API endpoint and I generate an AAC file like that.

When I save the file normally, I can play it with Windows media player, so the file itself is fine.

For the past week I have been trying to play this file from memory in windows forms application, using C# .NetCore3.1.

I have already managed to play the MP3 and Opus formats provided by OpenAI, using NAudio for MP3 conversion and playing wavs and Concentus for Opus to wav conversion.

Using the program MediaInfo I found out that the AAC file provided by OpenAI is:

  • Format: AAC LC
  • Format Version: Version 2
  • Codec ID: 2
  • Bit rate mode: Variable
  • Channels: 1
  • Sampling rate: 24.0 kHz
  • Frame rate: 23.438 FPS (1024 SPF)
  • Compression mode: Lossy

To play the AAC file, I have tried numerous things. The most basic attempt was with NAudio, which plays the file, but its very quickly as if it is sped up:

// AudioBytes is where the bytes from OpenAI are stored
AudioStream = new MemoryStream(AudioBytes);
var streamMediaFoundationReader = new StreamMediaFoundationReader(AudioStream);
var newFormat = new WaveFormat(24000, 1);
AccReader = new WaveFormatConversionStream(newFormat, streamMediaFoundationReader);

// I play the file using waveOut.Play, in a button event
waveOut = new WaveOut();
waveOut.Init(AccReader);

I tried changing the sampling rates to other values, but it did not work. I tried without touching the default sampling rate as well.


I also tried this: https://github.com/jimm98y/SharpJaad

To convert the file into wav and play it with NAudio, but I deleted the code so I can't show my attempt. The error I got when I tried it however was: "invalid huffman codebook: 12"

I have no idea what that means, I traced it to this file, but I couldn't figure out the problem:

https://github.com/jimm98y/SharpJaad/blob/2b3a29a230735565c328ea6373490482a45bbb8a/src/SharpJaad.AAC/Syntax/ICStream.cs#L118

I assume that this decoder does not support the exact format of this AAC file.


My latest attempt was with CSCore as follows:

private void LoadAac()
{
    // Convert AAC to PCM
    var inputMemoryStream = new MemoryStream(AudioBytes);
    IWaveSource aacSource = new AacDecoder(inputMemoryStream);
    aacSource = aacSource.ChangeSampleRate(24000); // i have tried without changing this as well
    aacSource = aacSource.ToMono(); // i have tried without changing this as well

    var outputMemoryStream = new MemoryStream();
    aacSource.WriteToWaveStream(outputMemoryStream);

    // Play PCM using NAudio 
    outputMemoryStream.Position = 0;
    AccReader = new RawSourceWaveStream(outputMemoryStream, 
        new NAudio.Wave.WaveFormat(aacSource.WaveFormat.SampleRate, aacSource.WaveFormat.BitsPerSample, aacSource.WaveFormat.Channels));
    waveOut = new NAudio.Wave.WaveOut();
    waveOut.Init(AccReader);
}

But this did not play a sound at all.

I tried using CSCore's native audio player too, but it did not work either.

When I debugged this, I found out that the WriteToWaveStream only copied 44 bytes, while the aacSource is much larger (as it should be). I tried the WriteToFile method provided by CSCore as well and it produced a tiny file too (44 bytes).

I do not quite understand why this is, apart from maybe CSCore does not support this type of AAC file as well?

I tried some shenanigans to force move the Position of the AacDecoder stream and write in my stream repeatedly, but that didn't work, it made some speed up and corrupted sound.


Here is a link to sample audio I am trying to play/convert: https://jmp.sh/s/LN8JSQedvzUrIUEoTskC

I am going to look into Ffmpeg solutions now, but I would appreciate any help or ideas.

0

There are 0 best solutions below