How to process an audio data from KiwiSDR on C#?

edited June 12 in KiwiSDR Discussion

Hi everyone. I want to create a desktop application on c#. Now I can connect to the remote KiwiSDR and receive audio data, but i cant to process it correctly. What is audio format returned by Kiwi? Can anyone help me? My code below...

private ClientWebSocket socket;

public async Task ConnectAsync(string ip,RichTextBox rtb,KiwiAudioPlayer audioPlayer)

{

  using var httpClient = new HttpClient();

  socket = new ClientWebSocket();

  var uri = new Uri("ws://172.12.54.44:8073/12345678/SND");

  socket = new ClientWebSocket();

  await socket.ConnectAsync(uri, CancellationToken.None);

  // After connect

  await SendCommand("SET auth t=kiwi p= ");

  await SendCommand("SET AR OK in=12000 out=44100");

  await SendCommand("SET squelch=0 max=0");

  await SendCommand("SET genattn=0");

  await SendCommand("SET gen=0 mix=-1");

  await SendCommand("SET ident_user=kiwibob");

  await SendCommand("SET mod=usb low_cut=0 high_cut=5000 freq=10100.000");

  await SendCommand("SET agc=1 hang=0 thresh=-100 slope=6 decay=1000 manGain=20");

//should i use commands below???

  //await SendCommand("SET samps=1");

  //await SendCommand("SET compression=0");


  await SendCommand("SET keepalive");


  _ = StartKeepAliveLoop(); // запуск без очікування

  var buffer = new byte[1024];

  while (true)

  {

    var result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

    if (result.MessageType == WebSocketMessageType.Close)

    {

      await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);

      break;

    }

    if (result.MessageType == WebSocketMessageType.Binary)

    {

      //Here is my audio data (i suppose)

      byte[] audioData = buffer.Take(result.Count).ToArray();

      audioPlayer.AddAudio(audioData);

    }

  }

}



And my code for WaveOut:


 class KiwiAudioPlayer

 {

   private BufferedWaveProvider provider;

   private WaveOutEvent waveOut;

   public KiwiAudioPlayer()

   {

     provider = new BufferedWaveProvider(new WaveFormat(12000, 16, 1));

     provider.BufferLength = 12000 * 2 * 10; // довший буфер

     provider.DiscardOnBufferOverflow = true;

     waveOut = new WaveOutEvent();

     waveOut.Init(provider);

     waveOut.Play();

   }

   public void AddAudio(byte[] muLawBuffer)

   {       

     provider.AddSamples(muLawBuffer, 0, muLawBuffer.Length);

   }

   public void Stop()

   {

     waveOut?.Stop();

     waveOut?.Dispose();

   }

 }

Thank U!

Comments

  • jksjks
    edited June 12

    I don't know anything about C#

    Have a look at kiwiclient / kiwirecorder, written in Python. It does everything you need: https://github.com/jks-prv/kiwiclient

    If you turn off audio compression you won't have to deal with the PCM coding.

    bobby
  • Thank you vary much, but i still want to release it on C#.

  • You can still use C#. But the kiwiclient / kiwirecorder code will show you exactly what you have to do to use the Kiwi API and process the audio stream that is transported over the web socket.

  • You mean that kiwirecorder file consist a solution to my problem? So...I will check it and if it resolve i will answer you

  • I resolve it!Uhhhuuu....)

    here is my c# code

    correct settings

    await SendCommand("SET auth t=kiwi p= ");

    await SendCommand("SET AR OK in=12000 out=12000");

    await SendCommand("SET squelch=0 max=0");

    await SendCommand("SET genattn=0");

    await SendCommand("SET gen=0 mix=-1");

    await SendCommand("SET ident_user=kiwibob");

    await SendCommand("SET mod=usb low_cut=0 high_cut=6000 freq=10100.000");

    await SendCommand("SET agc=1 hang=0 thresh=-110 slope=6 decay=1000 manGain=50");

    await SendCommand("SET compression=0");

    await SendCommand("SET keepalive");


    code for process byte array, received from KiwiSDR

     var buffer = new byte[4096];

     while (true)

     {

       var result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);


       if (result.MessageType == WebSocketMessageType.Close)

       {

         await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);

         break;

       }


       if (result.MessageType == WebSocketMessageType.Binary)

       {


         if (Encoding.ASCII.GetString(buffer, 0, 3) == "SND")

         {

           int audioLength = result.Count - 16;

           if (audioLength <= 0) return;


           byte[] audioBytes = new byte[audioLength];

           Array.Copy(buffer, 16, audioBytes, 0, audioLength);


           // Convert from Big Endian to Little Endian

           for (int i = 0; i < audioBytes.Length; i += 2)

           {

             byte tmp = audioBytes[i];

             audioBytes[i] = audioBytes[i + 1];

             audioBytes[i + 1] = tmp;

           }


           audioPlayer.provider.AddSamples(audioBytes, 0, audioBytes.Length);

         }

         

       }


    Settings for WaveOut

    class KiwiAudioPlayer

    {

      public BufferedWaveProvider provider;

      private WaveOutEvent waveOut;



      public KiwiAudioPlayer()

      {

        var waveFormat = new WaveFormat(12000,16, 1); // 12kHz, 16-bit, Mono

        provider = new BufferedWaveProvider(waveFormat)

        {    

          DiscardOnBufferOverflow = true

        };


        waveOut = new WaveOutEvent();

        waveOut.Init(provider);

        waveOut.Play();

      }


      public void AddAudioBytes(byte[] audioBytes)

      {

        provider.AddSamples(audioBytes, 0, audioBytes.Length);

      }


      public void Stop()

      {

        waveOut?.Stop();

        waveOut?.Dispose();

      }

    }

    Thank U!

    F5AFY
  • Well, as I said initially, I don't know C#. So I cannot say if this code will work or not. You just need to try it and debug it.

    I didn't know Python when I started working on kiwiclient / kiwirecorder, which was not written by me initially. I only modified it as I learned how it worked (as did many other people, most notably Christoph who is the author of the Kiwi TDoA algorithm).

Sign In or Register to comment.