CSCore - Highperformance Audiobibliothek

    • Release
    • Open Source

    Es gibt 589 Antworten in diesem Thema. Der letzte Beitrag () ist von simpelSoft.

      Jason schrieb:

      Ich habe noch eine Frage die mit CSCore nichst zu tun hat.

      Und was soll ich darauf antworten? PS: Der Code den du gepostet hast ist nicht so wie ich gesagt habe. Poste den ganzen Code relevanten Code und ich sag dir obs passt.


      Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
      Hier der Code:

      VB.NET-Quellcode

      1. Imports CSCore
      2. Imports CSCore.SoundOut
      3. Imports CSCore.Codecs
      4. Imports CSCore.Streams
      5. Public Class ...
      6. Dim soundOut As ISoundOut = GetSoundOut()
      7. Dim soundSource As IWaveSource = GetBackgroundSoundSource()
      8. 'SoundOut implementation which plays the sound
      9. soundOut = GetSoundOut()
      10. 'Tell the SoundOut which sound it has to play
      11. soundOut.Initialize(GetBackgroundSoundSource) ' soundsource
      12. 'Play the sound
      13. soundOut.Play()
      14. Private Function GetSoundOut() As ISoundOut
      15. If WasapiOut.IsSupportedOnCurrentPlatform Then
      16. Return New WasapiOut()
      17. Else
      18. Return New DirectSoundOut()
      19. End If
      20. End Function
      21. Private Function GetBackgroundSoundSource() As IWaveSource
      22. Return CodecFactory.Instance.GetCodec("Resources/Audio/Menu/01.wav")
      23. End Function
      24. Private Sub MenuForm_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
      25. If soundOut IsNot Nothing Then
      26. soundOut.Dispose()
      27. End If
      28. End Sub
      29. End Class
      Und was ist jetzt das Problem?


      Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „thefiloe“ ()

      Neuer Build auf NuGet. 1.1-beta. Hauptsächlich kleinere Ergänzungen und paar Bugs behoben. Eine "größere" Änderung. Equalizer-Klasse (und alles was dran hängt) wurde von CSCore.Streams Namespace in CSCore.Streams.Effects Namespace zu den anderen Effekten verschoben. War ein historisches überbleibsel und behebe das lieber jetzt als später. Ansonsten hat sich nix geändert. Scheint mittlerweile recht stabil zu laufen. Wird wohl bald der 1.1 Release kommen. Wollte eig. bis dahin OpenAL inkludieren. Da jetzt sowohl ich als auch @ThuCommix im Stress sind bzw. ich nix mehr gehört habe, wird sich das wohl auf mindestens 1.2 verzögern.


      Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
      Hallo,

      zunächst ein großes Lob für diese Bibliothek!
      Ich habe folgende Frage:
      Wie spiele ich einen MPEG4/ADTS (AAC) Stream ab?
      Ich bekomme nach und nach Pakete mit Samples in mein Programm, die alle schon einen ADTS-Header haben.
      Wenn ich diese Samples nun alle der Reihe nach in eine AAC-Datei schreibe, entsteht eine gültige Datei die ich abspielen kann.
      Nun möchte ich aber Die Samples nicht (nur) abspeichern, sondern gleich abspielen.
      Ich dachte da an die Klasse WriteableBufferingSource. Leider finde ich keine längere Dokumentation oder Anleitungen dazu, deswegen hier die Frage.
      Ich arbeite mit C#, .NET 4.5

      Vielen Dank für eine Antwort,

      //EDIT: Test-Code

      C#-Quellcode

      1. if (WasapiOut.IsSupportedOnCurrentPlatform)
      2. {
      3. soundOut = new WasapiOut();
      4. }
      5. else
      6. {
      7. soundOut = new DirectSoundOut();
      8. }
      9. WaveFormat format = new WaveFormat((int) sampleRate, (int) sampleSize, (int) channels, AudioEncoding.MPEG_ADTS_AAC); //44100, 16, 2
      10. soundSource = new WriteableBufferingSource(format); //Pufferlänge stimmt noch nicht!
      11. soundSource.FillWithZeros = false;
      12. .
      13. .
      14. .
      15. PACKET LOOP
      16. lock(..) { //Thread-sync
      17. data = e.data(); //sinngemäß
      18. soundSource.Write(data, 0, data.Length); //sinngemäß
      19. if (!isSoundInit)
      20. {
      21. soundOut.Initialize(soundSource);
      22. soundOut.Play();
      23. isSoundInit = true;
      24. }


      Dieser Code wirft bei soundOut.Initialize: "System.NotSupportedException: Inputformat not supported."

      //EDIT2
      Ich kann auch ohne Probleme die Samples ohne ADTS-Header streamen, sollte das nötig sein.
      SᴛᴀʀGᴀᴛᴇ01

      Dieser Beitrag wurde bereits 8 mal editiert, zuletzt von „StarGate01“ ()

      Muss zuerst decodiert werden. Ich würde mal versuchen rein die Url des Streams an die AacDecoder klasse zu übergeben. Je nachdem packt das die MediaFoundation so oder so und du musst gar nicht selbst puffern.


      Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
      Hi, danke für Deine Antwort, damit hast Du mir schon mal ein Stück weitergeholfen.

      Zunächst: Es gibt keine URL. Die Samples kommen auf recht obskurem Weg in Paketen herein. Betrachten wir diesen Vorgang als Black Box, mir geht es um Folgendes:

      Mithilfe des AacDecoder ist es mir nun gelungen einen MemoryStream an AAC-Daten abzuspielen.
      Problem: schreibe ich danach in den Stream, werden die Änderungen nicht übernommen.

      Lade ich den Stream komplett herunter, kann ich logischerweise alles abspielen.

      C#-Quellcode

      1. MemoryStream ms = //...
      2. //... Stream befüllen (mit Paket #0, oder eben allen Paketen) ...
      3. aacDecoder = new AacDecoder(ms);
      4. sampleSource = aacDecoder.ToSampleSource();
      5. soundSource = sampleSource.ToWaveSource();
      6. soundOut.Initialize(soundSource);
      7. //... schreibe ich nun in den Stream, bekommt das niemand mit


      Ich will nun aber während die Pakete eintrudeln schon mit der Wiedergabe anfangen.
      Wie verwende ich dazu zB. die Klasse WriteableBufferingSource? (Insbesondere, wie ermittle ich die Puffergröße? Ich kenne die Länge des AAC-Streams.)

      Danke für Deine Hilfe,
      SᴛᴀʀGᴀᴛᴇ01
      Uff um Frame für Frame AAC Daten zu decodieren müsste ich mich rein hängen und irgendwas suchen. Ist derzeit on the fly nicht da.
      Bin was streaming angeht noch nie sonderlich tief abgetaucht. Wäre ein Todo aber ... die Zeit fehlt einfach.
      Hab das mal mit MP3 gemacht, das funktioniert auch. Siehe Mp3WebStream. Aber wenn ich dich richtig verstehe ist das Problem, dass wenn der MemoryStream wächst, die neuen Daten die du da rein pufferst nicht abgespielt werden?
      Bei AAC müsste man wieder die ganzen MediaFoundationTransform-Geschichten implementieren. Und solche abartigen COM-Konstrukte auf .NET mappen ist einfach sehr viel Arbeit. Hab ich schon oft gemacht, ist halt einfach ne Zeitfrage.


      Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „thefiloe“ ()

      Leider kommst da mit Interops nicht weit. Die Art und Weise wie das bei CSCore umgesetzt ist, überschreitet eig. schon die Grenzen von C#.


      Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
      Hi,
      ich wollte eben mal ein älteres Programm von mir warten und dazu auch die vorhandene Implementation der CoreAudioApi wechseln. Leider ist mir dabei aufgefallen, dass Du zwar in der MMDeviceEnumator Klasse eine Methode GetDefaultAudioEndpointNative definiert hast, diese aber leider nur InteropCalls.CallI(...) aufruft - welche scheinbar noch nicht implementiert sind... Habe ich hierbei irgendwas übersehen, oder gibt es andere sinnvollere Wege die API zu nutzen?
      Grüße,
      FlashTek

      FlashTek schrieb:

      Habe ich hierbei irgendwas übersehen, oder gibt es andere sinnvollere Wege die API zu nutzen?

      Dein Verdacht ist zu 100% richtig. Es gibt wahrscheinlich über hundert (mehrere hundert??) solcher Aufrufe in CSCore. Wenn du dir die CallI-Methode anschaust, dann siehst du, dass diese das CSCalli-Attribut hat.
      Die Klasse welche diese Methode beinhaltet hat das RemoveObj-Attribut. Beides sind CSCore-interne Attribute und dahinter verbirgt sich sogar ein tieferer Sinn.
      CSCore greift teilweise recht tief ins System runter was mit reinen C#-Mitteln nicht mehr machbar ist. Ebenso bei COM-Aufrufen gab es im speziellen Kontext von CSCore einige Hürden. Diese sind genau durch folgenden Mechanismus gelöst: Nach dem erstellen der CSCore.dll wird im PostBuild das CSCli gestartet. Das ist ein Tool welches in der CSCore-Solution enthalten ist. Nicht sonderlich schön, tut aber seinen Zweck. Es liest die compilierte Dll erneut ein, geht sämtliche Klasse, mit sämtlichen Methoden und Eigenschaften durch und sucht nach Methoden Aufrufen. Hat die Methode die aufgerufen wird, das CSCalli-Attribut, so wird dieser Aufruf durch IL-Assembler Befehle ersetzt welche die Parameter für die jeweilige COM-Funktion/Methode auf den Stack laden und anschließend direkt über den Pointer zu der jeweiligen Funktion/Methode diese aufrufen. Auf die Gründe dazu möchte ich jetzt gar nicht lange eingehen. Am Ende werden sämtliche Dummy-Objekte inklusive der beiden Attribute aus der Assembly gelöst, neu compiliert und die dbg Dateien neu erstellt. Kurz: Diese Aufrufe stehen nur als Platzhalter im Source-Code. Schaust du das Resultat mit ILSpy etc. an, so wirst du weder diese Methodenaufrufe, noch diese ganzen CallI-Methoden finden.

      EDIT: @ThuCommix war schneller.


      Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
      Oh, alles klar, vielen Dank @ThuCommix und @thefiloe, das erklärt Einiges. Jetzt habe ich nur noch zwei kleine Fragen:
      1) Wie kann ich am einfachsten auf ein SimpleAudioVolume zugreifen, wenn ich ein Objekt vom Typ AudioSessionControl2 gegeben habe. Wenn ich die AudioSessionManager2.GetSimpleAudioVolume(...) Methode nuten möchte, brauche ich die GUID für die Session, aber wie kann ich diese erhalten? Vielleicht sehe ich hierbei auch den Wald vor lauter Bäumen nicht so recht.

      2) Per GetDefaultAudioEndpoint kann ich das Standard-Ausgabegerät erhalten, doch kann ich dieses auch ändern? Ich konnte bis lang leider keine Implementation der SetDefaultAudioEndpoint-Methode finden. Existiert diese (noch?) nicht, oder suche ich bloß an den falschen Stellen?
      Hej @thefiloe.

      Jetzt wollte ich mal versuchen mit dieser klasse Lib einen MP3-Player zu programmieren (anhand deines Beispielcodes im Startpost), und nichts funktioniert. ;(

      VB.NET-Quellcode

      1. Dim sampleSource As ISampleSource = New NotificationSource(source)


      "Option Strict On" lässt keine impliziten Konvertierungen von "IWaveSource" in "ISampleSource" zu.


      Wenn ich das ganze mit CType konvertiere, friert die Anwendung beim Auswählen einer Datei einfach ein.
      Hast du eventuell einen funktionieren Sample-Code für einen MP3-Player?

      Grüße
      Väinämö
      Ich gehe davon aus, dass source vom Typ IWaveSource ist. Das kannst natürlich nicht direkt konvertiert werden. Ändere das einfach zu New NotificationSource(source.ToSampleSource()) ab.
      Für das zufrieren ist CSCore sicher nicht verantwortlich. CType wird wenn dann eine Exception werfen. Alles andere wäre komisch.


      Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
      Hej @thefiloe.

      Er friert immer noch kurz ein, danach rauscht es und piepst wie wild bis sich nur noch ein "düt-düt-düt-düt-düt" schnell wiederholt.

      Irgendeine Ahnung?

      Grüße
      Väinämö