Hi,
weil ich auf der Suche nach eine Audio Codec war und @Manawyrm den Opus Codec empfohlen hat, habe ich mir diesen nun einmal angeguckt und bin auf einen C# Wrapper gestoßen: github.com/JohnACarruthers/Opus.NET Dieser benutzt als Audio Bibliothek NAudio, welches ich dann durch CSCore ersetzt habe. Soweit, so gut, jedoch funktioniert das alles nicht so, wie gedacht. Hier ist der gekürzte Code, den ich benutze:
Spoiler anzeigen
Wie man sehen kann, ist dort bestimmter Code auskommentiert. Dies ist Testcode, welcher den Codec aushebelt und wodurch es wunderbar funktioniert (zum Test, damit der Fehler nicht irgendwo anders ist).
Das Problem scheint darin zu liegen, dass ich dem
Der
Daran liegt es wohl auch, dass wenn man nur den Encoding Prozess ausklammert (die ersten zwei Zeilen in
Im Anhang ist ein lauffähiges Beispiel, aus welchem auch der Code oben entstammt. Vielleicht hat ja jemand ne Idee, was man da machen kann. Das Problem ist auch, dass Orpus 44100 Hz nicht unterstützt, wodurch wir nicht einfach dies ändern können.
Vielleicht hat ja jemand ne Idee
weil ich auf der Suche nach eine Audio Codec war und @Manawyrm den Opus Codec empfohlen hat, habe ich mir diesen nun einmal angeguckt und bin auf einen C# Wrapper gestoßen: github.com/JohnACarruthers/Opus.NET Dieser benutzt als Audio Bibliothek NAudio, welches ich dann durch CSCore ersetzt habe. Soweit, so gut, jedoch funktioniert das alles nicht so, wie gedacht. Hier ist der gekürzte Code, den ich benutze:
C#-Quellcode
- 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);
- MMDevice captureDevice = null;
- using (var deviceEnumerator = new MMDeviceEnumerator())
- using (
- var deviceCollection = deviceEnumerator.EnumAudioEndpoints(DataFlow.Capture, DeviceState.Active)
- )
- {
- foreach (var device in deviceCollection)
- {
- if (device.FriendlyName == comboBox1.Text)
- {
- captureDevice = device;
- break;
- }
- }
- }
- if (captureDevice == null)
- return;
- //var waveFormatExtensible = new WaveFormatExtensible(44100, 32, 2, Guid.Parse("00000003-0000-0010-8000-00aa00389b71"));
- var waveFormatExtensible = new WaveFormat(48000, 16, 1);
- _waveIn = new WasapiCapture(true, AudioClientShareMode.Shared, 100, waveFormatExtensible)
- {
- Device = captureDevice
- };
- _waveIn.Initialize();
- _waveIn.DataAvailable += _waveIn_DataAvailable1;
- _writeableBufferingSource = new WriteableBufferingSource(waveFormatExtensible) {FillWithZeros = true};
- _waveOut = new WasapiOut();
- _waveOut.Initialize(_writeableBufferingSource);
- _waveOut.Play();
- _waveIn.Start();
- if (_timer == null)
- {
- _timer = new Timer();
- _timer.Interval = 1000;
- _timer.Tick += _timer_Tick;
- }
- _timer.Start();
- }
- private void _waveIn_DataAvailable1(object sender, DataAvailableEventArgs e)
- {
- //_writeableBufferingSource.Write(e.Data, e.Offset, e.ByteCount);
- //return;
- byte[] soundBuffer = new byte[e.ByteCount + _notEncodedBuffer.Length];
- for (int i = 0; i < _notEncodedBuffer.Length; i++)
- soundBuffer[i] = _notEncodedBuffer[i];
- for (int i = 0; i < e.ByteCount; i++)
- soundBuffer[i + _notEncodedBuffer.Length] = e.Data[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);
- _writeableBufferingSource.Write(buff, 0, len);
- }
- }
Wie man sehen kann, ist dort bestimmter Code auskommentiert. Dies ist Testcode, welcher den Codec aushebelt und wodurch es wunderbar funktioniert (zum Test, damit der Fehler nicht irgendwo anders ist).
Das Problem scheint darin zu liegen, dass ich dem
WasapiCapture
zwar das richtige WaveFormat
gebe (48000 Hz), er jedoch dies nach dem Initialize()
aufruf wieder ändert:Der
WriteableBufferingSource
scheint damit jedoch kein Problem zu haben:Daran liegt es wohl auch, dass wenn man nur den Encoding Prozess ausklammert (die ersten zwei Zeilen in
_waveIn_DataAvailable1
unkommentiert), ohne das WaveFormat zu ändern, sehr unangenehme Töne entstehen (weil WasapiCapture
das WaveFormat ablehnt, der WriteableBufferingSource
damit jedoch kein Problem hat, wodurch es unterschiedliche WaveFormats werden). Also habe ich mal einen Blick in den Source von CSCore auf Github geworfen und festgestellt, dass wenn der Audio Client das WaveFormat nicht unterstützt, er sich einfach ein anderes sucht: github.com/filoe/cscore/blob/9…dIn/WasapiCapture.cs#L474Im Anhang ist ein lauffähiges Beispiel, aus welchem auch der Code oben entstammt. Vielleicht hat ja jemand ne Idee, was man da machen kann. Das Problem ist auch, dass Orpus 44100 Hz nicht unterstützt, wodurch wir nicht einfach dies ändern können.
Vielleicht hat ja jemand ne Idee
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VincentTB“ ()