Author Topic: [C#] Re-encoding audio without attaching an encoder to a decoding stream  (Read 186 times)


  • Posts: 22
Dear members,

As far as I know, if I want to decode a HSTREAM into PCM wave data and pass it to an encoder (like LAME), I need to do something like this:
Code: [Select]
async Task EncodeAsMp3ToStreamAsync(Stream TargetStream) {
   //This copies the encoded data received from the encoder to the given Stream.
      (handle, channel, buffer, length, user) => {
         byte[] ManagedBuffer = new byte[length];
         Marshal.Copy(buffer, ManagedBuffer, 0, length);

         TargetStream.Write(ManagedBuffer, 0, length);

   //This is the channel I want to decode and re-encode.
   int DecodingChannel = Bass.BASS_StreamCreateFile(this.Filename, 0, 0, BASSFlag.BASS_STREAM_DECODE);
   long DecodingChannelLength = Bass.BASS_ChannelGetLength(DecodingChannel);

   //Here I attach an encoder to the decoding stream...
   int Handle = BassEnc.BASS_Encode_Start(
      (new Lame()).GetCommandLine(),

   await Task.Run(() => {
      int BufferLength = 10240;
      byte[] Buffer = new byte[BufferLength];
      while (Bass.BASS_ChannelGetPosition(DecodingChannel) < DecodingChannelLength) {
        //... so the only thing I need to do is to read data from the decoding stream.
        Bass.BASS_ChannelGetData(DecodingChannel, Buffer, BufferLength);


I have several issues with this method, but the most important things are:
- This is not unit testable.
- It has a hardcoded dependency on BASS and the LAME encoder.
- Also violates the most of the SOLID principles.

So, I'd like to create two interfaces:
Code: [Select]
interface IDecoder {
   long Length { get; }
   long Position { get; }
   IEnumerable<byte> ReadPcmWaveData(int MaxBufferLength);

interface IEncoder {
   void WritePcmWaveData(IEnumerable<byte> PcmWaveData);

//This way I could create a method something like this:
async Task EncodeAsync(IDecoder Decoder, IEncoder Encoder) {
   await Task.Run(() => {
      while (Decoder.Position < Decoder.Length) {

My question is that how should I use BASS and BASSEnc so that I could encode like this?
« Last Edit: 20 Sep '17 - 09:19 by std66 »