CSCore LineSpectrum

  • VB.NET

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von VB3-Guru.

    CSCore LineSpectrum

    Hi,

    ich habe ein LineSpectrum programmiert, das das Mikrofon wunderbar und zeitnah wiedergibt. Aber bei WasapiLoopback, also Lautsprecher, geht das nur mit zwei sekunden Verzögerung, was mal garnicht zu gebrauchen ist.
    Amnerkung: ich habe bei dem internen 192000 bei SampleRate, bei mikro 44100, mehr daten also

    Was mache ich falsch?

    LG Mario
    Was meinst du mit "bei dem internen 192000 bei SampleRate"? Bei der Aufnahme per Mikro kriegst du 44100 Samples pro Sekunde. Meist geht auch noch SPS=48000. Die kannst du innerhalb von ms per FFT in ein Spektrum umrechnen, d.h. du siehst das Ergebnis quasi in Echtzeit. Wo kriegst du also 192000 Samples pro Sekunde her? 192000 ist etwa das 4-fache. sollte also also auch noch recht flott zu analysieren sein.

    Wenn du 2 Sekunden Verzögerung siehst, dann wird da vor der FFT vermutlich irgendwas umgerechnet.

    Gruß,

    Klaus
    Jede D/A bzw. A/D-Wandlung erzeugt Verzögerungen.
    Das hängt von der Buffersize ab, also von der Größe des Puffers, die der WASAPI-Treiber verwendet.
    Je größer der ist, desto länger die Verzögerung.
    Je kleiner der ist, desto größer die Systembelastung.

    Üblicherweise liegt die Verzögerung pro Wandlung im ein- bis zweistelligen Millisekundenbereich.

    Bei 2 Sekunden Verzögerung muss also irgendwo im Signalweg ein Hund begraben sein.
    Wie sieht denn deine Signalkette aus?
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Hallo, und danke für die Antworten.

    Um das ganze zu verdeutlichen: man sieht, sobald alles initialisiert wurde sofort, ohne verzögerung, die Balken, jedoch wenn man dann den Verlauf anschaut wird die Verzögerung nach kurzer Zeit sichtbar, spich sobald ich das Lied stoppe zeigt er eben noch so zwei sekunden lang die bewegten balken an.

    Zum Code: ich erzeuge eine neue WasapiLoopback Klasse oder eine Wasapi klasse (Mikro) mit if abfrage, und alles andere ist derselbe code, bloß beim einen funzts beim andern net, warum?

    Ich schreibe gleich noch den code hierher

    LG mario
    Naja.
    Wenn ich das richtig verstanden habe, läuft die Signalkette so:
    Der LoopBack nimmt das Signal und schickt es erst mal durch den Windows-Mixer, dessen Output-Stream er dann abgreift.
    Dass da Verzögerungen auftreten können, kann ich mir schon vorstellen.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    VB.NET-Quellcode

    1. ​Private _soundIn As New WasapiCapture
    2. Private _writer As IWriteable
    3. Private BufferingSource As Streams.WriteableBufferingSource
    4. Private _finalSource As IWaveSource
    5. Dim buffer As Byte()
    6. Public Sub StartRecording(ByVal FileStream As Stream)
    7. If _soundIn.RecordingState = RecordingState.Recording Then StopRecording()
    8. If GetCaptureMode() = CaptureMode.Microphone Then
    9. _soundIn = New WasapiCapture()
    10. Else
    11. _soundIn = New WasapiLoopbackCapture()
    12. End If
    13. _soundIn.Device = GetSelectedDevice()
    14. _soundIn.Initialize()
    15. Dim soundInSource = New SoundInSource(_soundIn)
    16. Dim singleBlockNotificationStream = New SingleBlockNotificationStream(soundInSource.ToSampleSource)
    17. _finalSource = singleBlockNotificationStream.ToWaveSource()
    18. _writer = New WaveWriter(DataStream, _finalSource.WaveFormat)
    19. buffer = New Byte(_finalSource.WaveFormat.BytesPerSecond / 2 - 1) {}
    20. ' ?
    21. AddHandler _soundIn.DataAvailable, AddressOf NewDataAvailable
    22. ' ?
    23. AddHandler singleBlockNotificationStream.SingleBlockRead, AddressOf blockRead
    24. _soundIn.Start()
    25. End Sub
    26. Sub blockRead(s, a)
    27. ' Zu Testzwecken, hier würde ich dem LineSpectrum anfügen
    28. MsgBox(a.Left & " ; " & a.Right)
    29. End Sub
    30. Sub NewDataAvailable()
    31. Dim read As Integer = 1
    32. Do
    33. read = _finalSource.Read(buffer, 0, buffer.Length)
    34. If read <= 0 Then Exit Do
    35. _writer.Write(buffer, 0, read)
    36. Loop
    37. End Sub


    Das müsste der Code sein
    Ja, ich hab den oberen Code nur etwas abgeändert mit irgendwelchem schnickschnack, der hier nicht zur Sache tut, da ja das Mikro visualisieren funktioniert.

    Ach da fällt mir gerade ein, vllt liegts net am Code, den ich schon gepostet habe, sondern am LineSpectrum und der FFTSize, wird nämlich woanders initialisiert. Hab bis jetzt immer 4096 glaub verwendet. Hab aber kein Plan was des ist.
    Hab bis jetzt immer 4096 glaub verwendet. Hab aber kein Plan was des ist.


    4096 ist vermutl. die Buffergröße, also die Anzahl der zu analysierenden Samples (nicht zu verwechseln mit der Samplerate). 1024 ist die übliche Größe. 4096 ist das vierfache. Das müsste aber auch innerhalb weniger ms zu analysieren sein. Solange die Rechenzeit für die FFT kleiner ist, als die Spieldauer eines Buffers, kommt es zu keiner Verzögerung bei der Darstellung. Bei den heutigen Rechnerleistungen ist das kein Problem. Ich hab meine FFT-Programme seinerzeit auf nem 300MHZ-Pentium geschrieben und bin nicht an die Grenzen der Verarbeitungsdauer gestoßen. Code oder ein Control (FFT-OCX) kann ich allerdings nur für VB6 liefern. Eine .net-Version ist in Planung. Von WasapiLoopback etc hab ich allerdings keine Ahnung.

    Gruß,

    Klaus
    Danke, habe das Problem gelöst: Es lag an der BufferSize bei der Klasse New SoundInSource([WasapiLoopbackCapture], Optional [BufferSize]), die ich nicht angegeben hatte.

    Keine Ahnung warum das deswegen so komisch war, habe jetzt jedenfalls 4096 als BufferSize. Hängt die BufferSize auch irgendwie mit der ​FFTSize zusammen, sollte ich da denselben Wert nehmen?

    Trotzallem Liebe Grüße

    MG
    Hängt die BufferSize auch irgendwie mit der FFTSize zusammen?


    Ich würde sagen, dass Buffersize = FFTSize, weiß allerdings nicht, wie genau die FFTSize bei dir definiert ist. Buffersize ist die Anzahl der zu analysierenden Samples. Wenn du 1024 Samples durch den FFT-Algo jagst, dann erhältst du ein Spektrum mit 512 Werten, also "Balken" in deinem Fall. Bei 4096, sind's entsprechend 2048. Die Zahl der Balken kannst du natürlich verringern indem du mehrere zusammenfasst.

    Falls du mehr zum Thema wissen willst, kannst du dich gerne hier einklinken.
    foren.activevb.de/forum/vb-net…8/FFT-and-Dynamite/#forum
    Dort werde ich das Thema FFT mal für .net aufarbeiten.

    @Moderatoren: ich hoffe es ist gestattet, hier einen Link auf ein anderes Forum zu posten. Ich will euch keineswegs die Klientel abwerben.
    Kann den Thread dann schließen



    @Mario. Nicht so voreilig ;-). ich will deinen kompletten Code noch sehen! :P

    Vielen Dank auch für die Bewertung! Ist mein erster Pluspunkt bei VB-Paradise

    Gruß,

    Klaus
    Die FFTSize gibt an aus wie vielen Samples das Eingangssignal besteht und in wie viele Frequenzbänder dieses aufgeteilt wird. Das heißt umso höher FFTSize umso detaillierter das Ergebnis.
    Dabei gilt FFTSize = 2^n. Die gängigsten Werte für eine Darstellung sind 1024, 2048 und 4096.
    Und nein die Balken sind nicht gleich hoch. Wenn das so ist, dann hat der Algorithmus einen Fehler (du verwendest ja nicht den von CSCore) oder die Darstellung.
    Im Samples Ordner von CSCore ist eine Beispielanwendung inkludiert.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Da fällt mir noch ein, ich habe manchmal Balken, die gleichhoch immer sind. Liegt an FFTSIze?


    Ich vermute das liegt an der Darstellung. Vielleicht gehen diese Balken ja über die Grenzen der Darstellung. Ansonsten, schau dir mal die Zahlenwerte an oder plotte die Werte mal als Kurve (Polyline).

    Es könnte natürlich auch sein, dass du ein Signal hast, bei dem mehrere Frequenzen dicht beiander liegen (kann bei künstlich generierten Klängen passieren.

    Zum Testen solltest du ein Signal verwenden, was nur aus der Überlagerung mehrerer Sinuse besteht z.B 400, 500, 600Hz. Da kannst du auch sehen, ob die berechnten Frequenzen stimmen.

    Falls du noch VB6 hast, schau dir mal mein FFT-Oscilloscope an:
    activevb.de/members/klaus/NewTips/FFT/

    Gruß,

    Klaus