2015-12-29 2 views
2

Je vais d'abord m'excuser. J'avais l'habitude de bricoler avec VB5 il y a longtemps et j'ai été hors de la chaise du programmeur pendant des années - je réapprends toujours les bases et ai commencé à apprendre C# /. NET récemment. Je suis également nouveau sur ce site, et je vous demande votre patience et vos conseils. Assez de backstory sur moi. En utilisant this wrapper for Opus, dont j'ai ajouté le projet wrapper à ma propre solution, et NAudio je crois que je l'ai configuré pour saisir activement l'audio de mon appareil (carte son) et utiliser l'exemple de code encodeur pour obtenir de l'audio codé dans le _playBuffer. Ma tâche suivante consiste à récupérer les données encodées et à les envoyer à l'aide de RDP afin qu'elles puissent être envoyées pour décodage dans une application cliente sur une autre machine où elles seront décodées et lues à partir de leur périphérique audio. Ai-je raison de comprendre que les données du _playBuffer sont des données codées prêtes à l'emploi? Ou est-ce que ce besoin doit se diviser différemment pour les paquets RTP? (Je vois un uLAW example here, mais je ne sais pas si je peux m'adapter à mes besoins.) Comme le code source téléchargé est commenté dans ce qui semble être allemand - pourtant je parle et écris à peine l'anglais comme première langue - même ceux qui ne sont pas très utiles (Ai-je même utilisé la bonne terminologie?) A partir de maintenant, le code de stock que vous voyez met les données _playBuffer à travers un WaveOut comme son exemple - que j'ai négligé d'omettre ici et je suis parti pour expliquer mon (manque probable de) compréhension. (Si c'est "jouable", c'est "sendable.")Envoi de l'audio codé en NAudio/Opus à partir de l'appareil en tant que RTP

Un autre problème est que mon intention était de multicast le flux pour point à point sur Internet - même si je ne suis pas sûr que la multidiffusion est ce que je veux pour cette.

using System; 
    using System.Collections.Generic; 
    using System.ComponentModel; 
    using System.Data; 
    using System.Drawing; 
    using System.Linq; 
    using System.Text; 
    using System.Threading.Tasks; 
    using System.Windows.Forms; 
    using NAudio; 
    using NAudio.CoreAudioApi; 
    using NAudio.Wave; 
    using FragLabs.Audio.Codecs; 

    namespace VUmeterappStereo 
    { 
     public partial class Form1 : Form 
     {private void Form1_Load(object sender, EventArgs e) 
     { 
      for (int i = 0; i < WaveIn.DeviceCount; i++) 
      { 
       comboBox1.Items.Add(WaveIn.GetCapabilities(i).ProductName); 
      } 
      if (WaveIn.DeviceCount > 0) 
       comboBox1.SelectedIndex = 0; 
      for (int i = 0; i < WaveOut.DeviceCount; i++) 
      { 
       comboBox2.Items.Add(WaveOut.GetCapabilities(i).ProductName); 
      } 
      if (WaveOut.DeviceCount > 0) 
       comboBox2.SelectedIndex = 0; 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      button2.Enabled = true; 
      button1.Enabled = false; 
      StartEncoding(); 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      button1.Enabled = true; 
      button2.Enabled = false; 
      StopEncoding(); 
     } 

     WaveIn _waveIn; 
     WaveOut _waveOut; 
     BufferedWaveProvider _playBuffer; 
     OpusEncoder _encoder; 
     OpusDecoder _decoder; 
     int _segmentFrames; 
     int _bytesPerSegment; 
     ulong _bytesSent; 
     DateTime _startTime; 
     Timer _timer = null; 

     void StartEncoding() 
     { 
      _startTime = DateTime.Now; 
      _bytesSent = 0; 
      _segmentFrames = 960; 
      _encoder = OpusEncoder.Create(48000, 1, FragLabs.Audio.Codecs.Opus.Application.Voip); 
      _encoder.Bitrate = 8192; 
      _decoder = OpusDecoder.Create(48000, 1); 
      _bytesPerSegment = _encoder.FrameByteCount(_segmentFrames); 

      _waveIn = new WaveIn(WaveCallbackInfo.FunctionCallback()); 
      _waveIn.BufferMilliseconds = 50; 
      _waveIn.DeviceNumber = comboBox1.SelectedIndex; 
      _waveIn.DataAvailable += _waveIn_DataAvailable; 
      _waveIn.WaveFormat = new WaveFormat(48000, 16, 1); 

      _playBuffer = new BufferedWaveProvider(new WaveFormat(48000, 16, 1)); 

      _waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()); 
      _waveOut.DeviceNumber = comboBox2.SelectedIndex; 
      _waveOut.Init(_playBuffer); 

      _waveOut.Play(); 
      _waveIn.StartRecording(); 

      if (_timer == null) 
      { 
       _timer = new Timer(); 
       _timer.Interval = 1000; 
       _timer.Tick += _timer_Tick; 
      } 
      _timer.Start(); 
     } 

     void _timer_Tick(object sender, EventArgs e) 
     { 
      var timeDiff = DateTime.Now - _startTime; 
      var bytesPerSecond = _bytesSent/timeDiff.TotalSeconds; 
      Console.WriteLine("{0} Bps", bytesPerSecond); 
     } 

     byte[] _notEncodedBuffer = new byte[0]; 
     void _waveIn_DataAvailable(object sender, WaveInEventArgs e) 
     { 
      byte[] soundBuffer = new byte[e.BytesRecorded + _notEncodedBuffer.Length]; 
      for (int i = 0; i < _notEncodedBuffer.Length; i++) 
       soundBuffer[i] = _notEncodedBuffer[i]; 
      for (int i = 0; i < e.BytesRecorded; i++) 
       soundBuffer[i + _notEncodedBuffer.Length] = e.Buffer[i]; 

      int byteCap = _bytesPerSegment; 
      int segmentCount = (int)Math.Floor((decimal)soundBuffer.Length/byteCap); 
      int segmentsEnd = segmentCount * byteCap; 
      int notEncodedCount = soundBuffer.Length - segmentsEnd; 
      _notEncodedBuffer = new byte[notEncodedCount]; 
      for (int i = 0; i < notEncodedCount; i++) 
      { 
       _notEncodedBuffer[i] = soundBuffer[segmentsEnd + i]; 
      } 

      for (int i = 0; i < segmentCount; i++) 
      { 
       byte[] segment = new byte[byteCap]; 
       for (int j = 0; j < segment.Length; j++) 
        segment[j] = soundBuffer[(i * byteCap) + j]; 
       int len; 
       byte[] buff = _encoder.Encode(segment, segment.Length, out len); 
       _bytesSent += (ulong)len; 
       buff = _decoder.Decode(buff, len, out len); 
       _playBuffer.AddSamples(buff, 0, len); 
      } 
     } 

     void StopEncoding() 
     { 
      _timer.Stop(); 
      _waveIn.StopRecording(); 
      _waveIn.Dispose(); 
      _waveIn = null; 
      _waveOut.Stop(); 
      _waveOut.Dispose(); 
      _waveOut = null; 
      _playBuffer = null; 
      _encoder.Dispose(); 
      _encoder = null; 
      _decoder.Dispose(); 
      _decoder = null; 

     } 



     private void timer1_Tick(object sender, EventArgs e) 
     { 
      MMDeviceEnumerator de = new MMDeviceEnumerator(); 
      MMDevice device = de.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia); 
      //float volume = (float)device.AudioMeterInformation.MasterPeakValue * 100; 
      float volLeft = (float)device.AudioMeterInformation.PeakValues[0] * 100; 
      float volRight = (float)device.AudioMeterInformation.PeakValues[1] * 100; 
      progressBar1.Value = (int)volLeft; 
      progressBar2.Value = (int)volRight; 
     } 

     private void timer2_Tick(object sender, EventArgs e) 
     { 

     } 
    } 
} 

Merci pour tout ce que vous pouvez contribuer à m'aider à comprendre comment faire pour obtenir les données via un flux RTP. Oh, et oui, cela a commencé avec mon bricolage pour recréer un VU-mètre à partir d'un exemple de tutoriel - donc le nom de l'espace de nom et le code supplémentaire, qui fonctionne.

Répondre

0

L'exemple de code code et décode l'audio. Vous devrez envoyer les octets contenus dans Buff au réseau.