简体   繁体   中英

Convert esp8266 code(part of it) to c/c++ or c#

Hi im trying to repeat this wifi baby monitor project based on esp8266: baby monitor project But instead of receiving data on another esp8266, I want to receive data on pc. I'm ac # programmer and I've encountered an problem of understanding c/c++ pointers how arrays works here and receive udp.

this is esp8266 receiver source code which works without any problems, but data that it receives, passes them to DAC. And i cant figure out where i can read just values one by one which was readed by esp8266 transmiter from ADC. Also readed data from ADC is 12 bit and author of original code use all 16 bit with some compression to transfer more data, and this compression part is what i have difficulty to uderstand it

#include <Wire.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <WiFiUdp.h>
#include "ESP8266mDNS.h"
#include <ArduinoOTA.h>

//#include "wifi_params.h"


const int mySDA = D7;
const int mySCL = D6;

const int AMPLI_MUTE_PIN = D2;
const int AMPLI_SHUTDOWN_PIN = D1;

const int RIGHT_BTN = D3;
const int LEFT_BTN = D4;
const int LED1 = D8;

const int udp_recv_port = 45990;

WiFiUDP udp;
TwoWire i2c;

#define NB_DATA_BUFS 5
uint16_t data_buf[NB_DATA_BUFS][700]; // data buffer, N buffered

unsigned int current_play_data_buf; // current data buf being played
unsigned int play_data_buf_pos; // position in the ADC data buffer
unsigned int current_recv_data_buf; // current data buf being received

bool play_waiting = true;
bool amplifier_stopped = false;
long play_waiting_at;

bool left_btn_pressed;
bool right_btn_pressed;

#define ICACHE_RAM_ATTR     __attribute__((section(".iram.text")))
#define twi_sda mySDA
#define twi_scl mySCL
#define twi_dcount 0
#define twi_clockStretchLimit 10
#define SDA_LOW()   (GPES = (1 << twi_sda)) //Enable SDA (becomes output and since GPO is 0 for the pin, it will pull the line low)
#define SDA_HIGH()  (GPEC = (1 << twi_sda)) //Disable SDA (becomes input and since it has pullup it will go high)
#define SDA_READ()  ((GPI & (1 << twi_sda)) != 0)
#define SCL_LOW()   (GPES = (1 << twi_scl))
#define SCL_HIGH()  (GPEC = (1 << twi_scl))
#define SCL_READ()  ((GPI & (1 << twi_scl)) != 0)

static void twi_delay(unsigned char v) {
  unsigned int i;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
  unsigned int reg;
  for (i = 0; i<v; i++) reg = GPI;
#pragma GCC diagnostic pop
}

static inline ICACHE_RAM_ATTR bool twi_write_start(void) {
  SCL_HIGH();
  SDA_HIGH();
  if (SDA_READ() == 0) return false;
  SDA_LOW();
  return true;
}

static inline ICACHE_RAM_ATTR bool twi_write_stop(void) {
  uint32_t i = 0;
  SCL_LOW();
  SDA_LOW();
  SCL_HIGH();
  while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit); // Clock stretching
  SDA_HIGH();

  return true;
}

static inline ICACHE_RAM_ATTR bool twi_write_bit(bool bit) {
  uint32_t i = 0;
  SCL_LOW();
  if (bit) SDA_HIGH();
  else SDA_LOW();
  twi_delay(twi_dcount + 1);
  SCL_HIGH();
  while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit);// Clock stretching
  return true;
}

static inline ICACHE_RAM_ATTR bool twi_read_bit(void) {
  uint32_t i = 0;
  SCL_LOW();
  SDA_HIGH();
  twi_delay(twi_dcount + 2);
  SCL_HIGH();
  while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit);// Clock stretching
  bool bit = SDA_READ();
  return bit;
}

static inline ICACHE_RAM_ATTR bool twi_write_byte(unsigned char byte) {
  unsigned char bit;
  for (bit = 0; bit < 8; bit++) {
    twi_write_bit(byte & 0x80);
    byte <<= 1;
  }
  return !twi_read_bit();//NACK/ACK
}

static inline ICACHE_RAM_ATTR unsigned char twi_read_byte(bool nack) {
  unsigned char byte = 0;
  unsigned char bit;
  for (bit = 0; bit < 8; bit++) byte = (byte << 1) | twi_read_bit();
  twi_write_bit(nack);
  return byte;
}


unsigned char inline ICACHE_RAM_ATTR mytwi_writeTo(unsigned char address, unsigned char * buf, unsigned int len, unsigned char sendStop) {
  unsigned int i;
  if (!twi_write_start()) return 4;//line busy
  if (!twi_write_byte(((address << 1) | 0) & 0xFF)) {
    if (sendStop) twi_write_stop();
    return 2; //received NACK on transmit of address
  }
  for (i = 0; i<len; i++) {
    if (!twi_write_byte(buf[i])) {
      if (sendStop) twi_write_stop();
      return 3;//received NACK on transmit of data
    }
  }
  if (sendStop) twi_write_stop();
  i = 0;
  while (SDA_READ() == 0 && (i++) < 10) {
    SCL_LOW();
    SCL_HIGH();
  }
  return 0;
}



static inline ICACHE_RAM_ATTR uint8_t DAC(uint16_t value)
{
  /* value is 76543210 XXXXBA98
  per the datasheet for fast write:
  1 1 0 0 A2 A1 A0 0 <ACK> 0 0 PD1 PD0 D11 D10 D9 D8 <ACK> D7 D6 D5 D4 D3 D2 D1 D0 <ACK>
  */






  uint8_t buf[2] = { (value >> 8) & 0x0F, (value & 0xFF) };
  int ret = mytwi_writeTo(0x60, buf, 2, true);

  Serial.println(value);

  return ret;
}

void ICACHE_RAM_ATTR playsample_isr(void)
{
  if (play_waiting) {
    return;
  }

  DAC(data_buf[current_play_data_buf][play_data_buf_pos]);
  play_data_buf_pos++;
  if (play_data_buf_pos >= sizeof(data_buf[0]) / sizeof(data_buf[0][0])) {
    play_data_buf_pos = 0;
    current_play_data_buf++;
    if (current_play_data_buf == NB_DATA_BUFS) {
      current_play_data_buf = 0;
    }

    if (current_play_data_buf == current_recv_data_buf) {
      play_waiting = true;
      play_waiting_at = micros();
    }
  }
}

void ota_onstart(void)
{
  // Disable timer when an OTA happens
  timer1_detachInterrupt();
  timer1_disable();
}

void ota_onprogress(unsigned int sz, unsigned int total)
{
  Serial.print("OTA: "); Serial.print(sz); Serial.print("/"); Serial.print(total);
  Serial.print("="); Serial.print(100 * sz / total); Serial.println("%");
}

void ota_onerror(ota_error_t err)
{
  Serial.print("OTA ERROR:"); Serial.println((int)err);
}

void left_btn_intr()
{
  left_btn_pressed = 1;
}

void right_btn_intr()
{
  right_btn_pressed = 1;
}

void setup(void)
{
  Serial.begin(115200);
  Serial.println("I was built on " __DATE__ " at " __TIME__ "");

  i2c.begin(mySDA, mySCL);
  i2c.setClock(400000);

  WiFi.mode(WIFI_STA);
  WiFi.begin("valik 2", "299745buhlo");
  WiFi.setSleepMode(WIFI_MODEM_SLEEP);

  Serial.print("Connecting to wifi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.print("Cnnectd to ");
  Serial.println("valik 2");
  Serial.print("IP ");
  Serial.println(WiFi.localIP());

  ArduinoOTA.onStart(ota_onstart);
  ArduinoOTA.onError(ota_onerror);
  ArduinoOTA.onProgress(ota_onprogress);
  ArduinoOTA.setHostname("bb-recv");
  ArduinoOTA.begin();

  timer1_isr_init();
  timer1_attachInterrupt(playsample_isr);
  timer1_enable(TIM_DIV16, TIM_EDGE, TIM_LOOP);
  timer1_write(clockCyclesPerMicrosecond() / 16 * 50); //50us = 20 kHz sampling freq

  udp.begin(udp_recv_port);

  pinMode(AMPLI_MUTE_PIN, OUTPUT);
  pinMode(AMPLI_SHUTDOWN_PIN, OUTPUT);
  digitalWrite(AMPLI_SHUTDOWN_PIN, 0);
  digitalWrite(AMPLI_MUTE_PIN, 0);

  pinMode(LEFT_BTN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(LEFT_BTN), left_btn_intr, FALLING);
  pinMode(RIGHT_BTN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(RIGHT_BTN), right_btn_intr, FALLING);

  pinMode(LED1, OUTPUT);
  digitalWrite(LED1, 0);

}

int do_undelta7(const uint8_t *val, int sz, uint16_t *out)
{
  // Implement delta 7 decompression.
  // First bit = 0 <=> uncompressed 15 bits following 
  // First bit = 1 <=> 7 bits follow representing delta
  // must switch to big endian...
  uint16_t last = 0;
  uint8_t *ptr = (uint8_t *)&out[0];
  const uint8_t *start = ptr;
  for (int i = 0; i < sz; i++) {
    uint16_t *ptr16 = (uint16_t *)ptr;
    const int8_t firstbyte = val[i];
    if (firstbyte & 0x80) {
      // Delta7 compressed
      // byte is CSMMMMMM
      int8_t delta = firstbyte & 0x3F;
      if (firstbyte & 0x40) {
        delta = -delta;
      }
      const uint16_t value = last + delta;
      *ptr16 = value;
      ptr += 2;

      last = value;
    }
    else {
      // uncompressed -- switch bytes back to LE
      *ptr++ = val[i + 1];
      *ptr++ = val[i];
      last = val[i + 1] | val[i] << 8;
      i++;
    }
  }

  return ptr - start;

}

void loop(void)
{
  ArduinoOTA.handle();
  int sz = udp.parsePacket();
  //Serial.println(current_play_data_buf);
  if (sz) {
    uint8_t buf[sz];
    udp.read(&buf[0], sz);
    current_recv_data_buf++;
    if (current_recv_data_buf == NB_DATA_BUFS) {
      current_recv_data_buf = 0;
      if (current_recv_data_buf == current_play_data_buf && !play_waiting) {
        Serial.println("buffer overflow when receiving");
      }
    }
    do_undelta7(buf, sz, &data_buf[current_recv_data_buf][0]);

    if (play_waiting) {
      Serial.print("Restarting play, was waiting (us)"); Serial.println(micros() - play_waiting_at);
      // Re-enable *then* unmute in that order to avoid pops
      digitalWrite(AMPLI_SHUTDOWN_PIN, 1);
      digitalWrite(AMPLI_MUTE_PIN, 1);
      play_waiting = false;
      amplifier_stopped = false;
      digitalWrite(LED1, 1);
    }

    Serial.println("");
  }

  // If not playing anything, but amplifier is still up
  if (!amplifier_stopped && play_waiting) {
    if ((micros() - play_waiting_at) > 2000 * 1000) {
      // If nothing has been played for two seconds, shut down the amplifier 
      Serial.println("Shutting down amplifier!");
      digitalWrite(AMPLI_SHUTDOWN_PIN, 0);
      digitalWrite(AMPLI_MUTE_PIN, 0);
      amplifier_stopped = true;
      digitalWrite(LED1, 0);
    }
  }

  if (left_btn_pressed) {
    left_btn_pressed = 0;
    digitalWrite(AMPLI_MUTE_PIN, 0);
    digitalWrite(AMPLI_SHUTDOWN_PIN, 0);
  }

  if (right_btn_pressed) {
    digitalWrite(AMPLI_SHUTDOWN_PIN, 1);
    digitalWrite(AMPLI_MUTE_PIN, 1);
    udp.beginPacket(udp.remoteIP(), 45990);
    udp.write("sendnow");
    udp.endPacket();
    right_btn_pressed = 0;
  }

  // If the amplifier is stopped, add a delay for power saving
  if (amplifier_stopped) {
    delay(10);
  }

}

This is my attempt to translate code to c++ for windows. But i encountered problem where programm just freeze without any errors and without closing.

    #include "stdafx.h"
#include <winsock2.h>
#include <stdio.h>
#include <cstdint>
#include <ctime>
#pragma comment (lib, "ws2_32.lib")

#define NB_DATA_BUFS 5
uint16_t data_buf[NB_DATA_BUFS][700]; // data buffer, N buffered

unsigned int current_play_data_buf; // current data buf being played
unsigned int play_data_buf_pos; // position in the ADC data buffer
unsigned int current_recv_data_buf; // current data buf being received

bool play_waiting = true;
bool amplifier_stopped = false;
long play_waiting_at;

bool left_btn_pressed;
bool right_btn_pressed;
void InitWinsock()
{
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
}

int do_undelta7(const uint8_t *val, int sz, uint16_t *out)
{
    // Implement delta 7 decompression.
    // First bit = 0 <=> uncompressed 15 bits following 
    // First bit = 1 <=> 7 bits follow representing delta
    // must switch to big endian...
    uint16_t last = 0;
    uint8_t *ptr = (uint8_t *)&out[0];
    const uint8_t *start = ptr;
    for (int i = 0; i < sz; i++) {
        uint16_t *ptr16 = (uint16_t *)ptr;
        const int8_t firstbyte = val[i];
        if (firstbyte & 0x80) {
            // Delta7 compressed
            // byte is CSMMMMMM
            int8_t delta = firstbyte & 0x3F;
            if (firstbyte & 0x40) {
                delta = -delta;
            }
            const uint16_t value = last + delta;
            *ptr16 = value;
            ptr += 2;
            last = value;

        }
        else {
            // uncompressed -- switch bytes back to LE
            *ptr++ = val[i + 1];
            *ptr++ = val[i];
            last = val[i + 1] | val[i] << 8;

            i++;
        }
    }

    return ptr - start;

}



void DAC(uint16_t value)
{
    /* value is 76543210 XXXXBA98
    per the datasheet for fast write:
    1 1 0 0 A2 A1 A0 0 <ACK> 0 0 PD1 PD0 D11 D10 D9 D8 <ACK> D7 D6 D5 D4 D3 D2 D1 D0 <ACK>
    */

    uint8_t buf[2] = { (value >> 8) & 0x0F, (value & 0xFF) };

    printf("%u\n", value & 0xFFF);

}

int _tmain(int argc, _TCHAR* argv[])
{
    SOCKET socketC;

    InitWinsock();
    struct sockaddr_in serverInfo;
    int len = 2000;
    serverInfo.sin_family = AF_INET;
    serverInfo.sin_port = htons(45990);
    serverInfo.sin_addr.s_addr = inet_addr("192.168.1.105");

    socketC = socket(AF_INET, SOCK_DGRAM, 0);

    char buffers[16];
    ZeroMemory(buffers, sizeof(buffers));
    sendto(socketC, buffers, sizeof(IReleaseMarshalBuffers), 0, (sockaddr*)&serverInfo, len);



    while (1)
    {

        sockaddr_in from;
        const int paketSize = sizeof(from);

        int r = paketSize;

        char buffer[paketSize];
        sprintf(buffer, "%.7s", "sendnow");

        if (strcmp(buffer, "exit") == 0)
            break;

        recvfrom(socketC, buffer, sizeof(buffer), 0, (sockaddr*)&serverInfo, &len);


                uint8_t buf[sizeof(buffer)];
                uint8_t * bufeerPntr = (uint8_t*)buffer;
                uint8_t * bufPntr = (uint8_t*)buffer;

                for(int i=0;i<sizeof(buffer);i++)
                {
                    buf[i] = buffer[i];
                }

                //udp.read(&buf[0], sizeof(buffer));
                current_recv_data_buf++;
                if (current_recv_data_buf == NB_DATA_BUFS) {
                    current_recv_data_buf = 0;
                    if (current_recv_data_buf == current_play_data_buf && !play_waiting) {
                        printf("buffer overflow when receiving\n");
                    }
                }
                do_undelta7(buf, sizeof(buffer), &data_buf[current_recv_data_buf][0]);

            }

    closesocket(socketC);

    return 0;
}

This is my attempt to translate decoding part to c# (c# is much easier for me to understand) but i forced to use pointers and strange * and & things which i have difficulty to understand:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class UDPListener
{
    private const int listenPort = 45990;
    public static int Main()
    {
        bool done = false;
        UdpClient listener = new UdpClient(listenPort);
        IPEndPoint groupEP = new IPEndPoint(IPAddress.Parse("192.168.1.3"), listenPort);
        string received_data;
        int BUFSIZE = 700;
        byte[] receive_byte_array;
        uint current_recv_data_buf = 1;



        while (!done)
        {
            Console.WriteLine("Waiting for broadcast");
            receive_byte_array = listener.Receive(ref groupEP);
            Console.WriteLine("Received a broadcast from {0}", groupEP.ToString());

            received_data = Encoding.ASCII.GetString(receive_byte_array, 0, receive_byte_array.Length);

            unsafe
            {

                UInt16*[,] data_buf = new UInt16*[5, 700];
                int sz = receive_byte_array.Length;
                if (sz > 0)
                {
                    byte[] buf = new byte[receive_byte_array.Length];

                    UInt16* f = stackalloc UInt16[2000];

                    //udp.read(&buf[0], sz);
                    buf = receive_byte_array;
                    current_recv_data_buf++;

                    UInt16 last = 0;

                        UInt16* @out1 = stackalloc UInt16[800];

                        for (int i = 0; i < 800; i++)
                        {
                            @out1[i] = (char)i;
                        }


                        //UIntPtr* ptr = (UIntPtr*)&@out[0];
                        UIntPtr* ptr = (UIntPtr*)&@out1[0];

                        UIntPtr* start = ptr;
                        for (int i = 0; i < sz; i++)
                        {
                            UIntPtr* ptr16 = ptr;
                            byte firstbyte = buf[i];

                            if ((firstbyte & 0x80) != 0)
                            {
                                // Delta7 compressed
                                // byte is CSMMMMMM
                                byte delta = (byte)(firstbyte & 0x3F);
                                if ((firstbyte & 0x40) != 0)
                                {
                                    delta = (byte)(0 - delta);
                                }

                                UInt16 value = (UInt16)(last + delta);

                                *ptr16 = (UIntPtr)value;
                                ptr += 2;

                                last = value;
                            }
                            else
                            {
                                *ptr++ = (UIntPtr)buf[i + 1];

                                *ptr++ = (UIntPtr)buf[i];
                                last = (UInt16)(buf[i + 1] | buf[i] << 8);
                                i++;
                            }
                        }
                    for (int i = 0; i < 91; i++)
                    {
                        System.Console.WriteLine(@out1[i]);
                    }


                    string b = "";
                }
            }
        }

        listener.Close();
        return 0;
    }
} // end of class UDPListener

udp.read(&buf[0], sz); copies the received UDP packet into buffer buf . The function do_undelta7 then makes a decompression of the data in the input buffer to output buffer data_buf[current_recv_data_buf] . data_buf is array of buffers. The interrupt playsample_isr plays the content of the buffers in data_buf .

i missed an unsigned byte in do_undelta7 so now it's decoding well c#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Media;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using NAudio.Wave;


public class UDPListener
{
    uint current_recv_data_buf;
    static int NB_DATA_BUFS = 5;
    static UInt16[] data_buf = new UInt16[700];

    uint current_play_data_buf; // current data buf being played
    uint play_data_buf_pos; // position in the ADC data buffer


    private const int listenPort = 45990;



    public static unsafe int Main()
    {
        bool done = false;
        UdpClient listener = new UdpClient(listenPort);
        IPEndPoint groupEP = new IPEndPoint(IPAddress.Parse("192.168.1.3"), listenPort);
        int BUFSIZE = 700;
        byte[] receive_byte_array;
        uint current_recv_data_buf = 1;
        List<byte> tenBuffsToPlay = new List<byte>();
        int iterBuffsToPLay = 0;
        byte[] byteArrToPlay = new byte[data_buf.Length * 2];
        byte[] byte10ArrToPlay;
        int pktcount = 0;

        var sampleRate = 20000;
        var frequency = 500;
        var amplitude = 0.2;
        var seconds = 5;

        while (!done)
        {
            receive_byte_array = listener.Receive(ref groupEP);
            if (receive_byte_array.Length > 0)
            {
                Console.WriteLine("received !"+pktcount++);
                int sz = receive_byte_array.Length;
                unsafe
                {

                    byte[] buf = new byte[sz];

                    buf = receive_byte_array;
                   fixed (UInt16* data_bufPtr = &data_buf[0])
                   fixed (byte* ptrbuf = buf)
                   do_undelta7(ptrbuf, sz, data_bufPtr);

                    //string firstPart = "";
                    //string secondPart = "";

                    for (int i =0;i<data_buf.Length;i++)
                    {
                        //Console.WriteLine("Hex: {0:X}", data_buf[i]);

                        byteArrToPlay[i*2] = (byte)((data_buf[i] >> 8)&0x0f);
                        byteArrToPlay[(i*2)+1] = (byte)(data_buf[i] & 0xff);
                        //firstPart = Convert.ToString(byteArrToPlay[i], 2).PadLeft(4, '0');
                        //Console.Write(firstPart);
                        //secondPart = Convert.ToString(byteArrToPlay[i+1], 2).PadLeft(4, '0');
                        //Console.Write(secondPart+"\n");
                    }

                    //byteArrToPlay = data_buf.SelectMany(BitConverter.GetBytes).ToArray();

                    //foreach (var Arr in byteArrToPlay)
                    // {
                    // Console.WriteLine("Hex: {0:X}", Arr);
                    // }
                    tenBuffsToPlay.AddRange(byteArrToPlay);
                    iterBuffsToPLay++;
                    if (iterBuffsToPLay == 3)
                    {
                        byte10ArrToPlay = tenBuffsToPlay.ToArray();


                        /*var raw = new byte[sampleRate * seconds * 2];

                        var multiple = 2.0 * frequency / sampleRate;
                        for (int n = 0; n < sampleRate * seconds; n++)
                        {
                            var sampleSaw = ((n * multiple) % 2) - 1;
                            var sampleValue = sampleSaw > 0 ? amplitude : -amplitude;
                            var sample = (short)(sampleValue * Int16.MaxValue);
                            var bytes = BitConverter.GetBytes(sample);
                            raw[n * 2] = bytes[0];
                            raw[n * 2 + 1] = bytes[1];
                        }*/


                        var ms = new MemoryStream(byte10ArrToPlay);
                        var rs = new RawSourceWaveStream(ms, new WaveFormat(sampleRate, 16, 1));


                        var wo = new WaveOutEvent();
                        wo.Init(rs);
                        wo.Play();
                        /*while (wo.PlaybackState == PlaybackState.Playing)
                        {
                            Thread.Sleep(1);
                        }*/
                        //wo.Dispose();







                        /*using (MemoryStream ms = new MemoryStream())
                        {
                            WriteWavHeader(ms, false, 1, 16, 20000, (byte10ArrToPlay.Length / 2 - 45));
                            // Construct the sound player
                            ms.Write(byte10ArrToPlay, 0, byte10ArrToPlay.Length);
                            ms.Position = 0;
                            SoundPlayer player = new SoundPlayer(ms);
                            player.Play();
                        }*/
                        tenBuffsToPlay.Clear();
                       iterBuffsToPLay = 0;
                    }

                }

            }
        }

        listener.Close();
        return 0;
    }


    static unsafe long do_undelta7(byte* val, int sz, UInt16* outArray)
    {
        // Implement delta 7 decompression.
        // First bit = 0 <=> uncompressed 15 bits following 
        // First bit = 1 <=> 7 bits follow representing delta
        // must switch to big endian...
        UInt16 last = 0;
        byte* ptr = (byte*)&outArray[0];
        byte* start = ptr;
        for (int i = 0; i < sz; i++)
        {
            UInt16* ptr16 = (UInt16*)ptr;
            byte firstbyte = val[i];
            var bit = (firstbyte & (1 << 8 - 1)) != 0;
            if (bit == true)
            {
                // Delta7 compressed
                // byte is CSMMMMMM
                sbyte delta = (sbyte)(firstbyte & 0x3f);
                bit = (firstbyte & (1 << 7 - 1)) != 0;
                if (bit == true)
                {
                    delta = (sbyte)(0x0 - delta);
                }
                UInt16 value = (UInt16)(last + delta);
                *ptr16 = value;
                ptr += 2;

                last = value;
            }
            else
            {
                // uncompressed -- switch bytes back to LE

                *ptr++ = val[i + 1];
                *ptr++ = val[i];
                last = (UInt16)(val[i + 1] | val[i] << 8);
                i++;
            }
        }

        return ptr - start;

    }
    private static void WriteWavHeader(MemoryStream stream, bool isFloatingPoint, ushort channelCount, ushort bitDepth, int sampleRate, int totalSampleCount)
    {
        stream.Position = 0;
        stream.Write(Encoding.ASCII.GetBytes("RIFF"), 0, 4);
        stream.Write(BitConverter.GetBytes((2* totalSampleCount) + 36), 0, 4);
        stream.Write(Encoding.ASCII.GetBytes("WAVE"), 0, 4);
        stream.Write(Encoding.ASCII.GetBytes("fmt "), 0, 4);
        stream.Write(BitConverter.GetBytes(16), 0, 4);
        stream.Write(BitConverter.GetBytes((ushort)(isFloatingPoint ? 3 : 1)), 0, 2);
        stream.Write(BitConverter.GetBytes(channelCount), 0, 2);
        stream.Write(BitConverter.GetBytes(sampleRate), 0, 4);
        stream.Write(BitConverter.GetBytes(sampleRate * 2), 0, 4);
        stream.Write(BitConverter.GetBytes((ushort)2), 0, 2);
        stream.Write(BitConverter.GetBytes(16), 0, 2);
        stream.Write(Encoding.ASCII.GetBytes("data"), 0, 4);
        stream.Write(BitConverter.GetBytes(2 * totalSampleCount), 0, 4);
    }


} // end of class UDPListener

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM