Fragen zur korrekten Anwendung der Bass.dll

  • VB.NET

Es gibt 34 Antworten in diesem Thema. Der letzte Beitrag () ist von kafffee.

    Fragen zur korrekten Anwendung der Bass.dll

    Hey allerseits,

    na dann bring ich mal wieder Schwung in diesen Thread. :D Ich hoffe das geht klar...

    Hat jemand ne Ahnung wie man die bass_fx.dll einbindet? Hab im Internet und in der Doku nichts gefunden.

    Also irgendwas mit:

    VB.NET-Quellcode

    1. Imports Un4seen.Bass. ...


    Ich habe vor die Abspielgeschwindigkeit bzw. den Pitch zu verändern. Wo jetzt der Unterschied zwischen beiden liegt ist mir auch noch nicht so klar, das müsste ich dann ausprobieren...

    mengenbedingt ausgelagert aus dem Bass.dll Tutorial ~VaporiZed

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

    Laut den ersten 10 Posts: SDK installieren und dann enweder über die Verweise die DLL einbinden oder entsprechend Post#10 (bzw. .NET-mäßig über <DllImport>.
    Imports ist ja bekanntlich nur eine Namespace-Vereinfachung und kein Dll-Import.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @kafffee Du musst zunächst die bass.net.dll Deinem Projekt als Verweis hinzufügen und diese und die bass.dll neben die exe legen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @VaporiZed
    Nur eine Namespace-Vereinfachung? Gut, hammer wieder was gelernt :)

    @RodFromGermany
    Genau. Soweit bin ich schon.

    Das lag dann wahrscheinlich daran, dass mein Code veraltet war...

    Jetzt bin ich schon soweit:

    Es gibt Folgendes:

    VB.NET-Quellcode

    1. Bass.BASS_ChannelSetAttribute(mixer, BASSAttribute.BASS_ATTRIB_TEMPO_PITCH, -60)


    Nur passiert da rein gar nichts wenn ich das anwende... IntelliSense schlägt mir das hier vor wenn ich drüber hovere:

    BASSAttribute.BASS_ATTRIB_TEMPO_PITCH = 65537
    BASS_FX Tempo: The pitch in semitones -60..0..+60

    Hat jemand eine Idee was ich falsch mache?

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

    @kafffee Was die Intellisense vorschlägt steht in der bass.net.xml neben der bass.net.dll.
    Was sagt die Beschreibung auf deren Home-Page?
    Hast Du andere Beispiele analysiert?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany

    Unter BASS_ATTRIB_TEMPO_PITCH finde ich auf der Homepage von Un4seen leider nichts.

    Wenn ich z.B. BASS_Bass.BASS_ChannelSetAttribute(mixer, BASSAttribute.BASS_ATTRIB_MUSIC_BPM, 1) mache, passiert auch nichts. Er will hier einen Wert von 0-255. Allerdings steht da irgendwas von "MOD"-Handle. Bin mir nicht sicher was das ist...

    Hab auch schon diverse Methoden probiert, die irgendwas damit zu tun haben könnten, (z.B. wenn ich mich richtig erinnere BASS_ATTRIB_FREQ), da passiert aber auch nichts...

    Hier mal der Link:

    un4seen.com/doc/#bass/bass_attrib_music_bpm.html
    @kafffee Es muss doch fertige Beispiele für die Bass.dll geben.
    Was genau willst Du denn mit der Bass.dll machen?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany

    Ja das denke ich auch, aber ich hab bis jetzt nix gefunden. Ich möchte zwei Musiktracks überblenden können. Den Crossfader mit Hilfe einer Trackbar hab ich schon hinbekommen, nun möchte ich aber die Abspielgeschwindigkeit der beiden Tracks aneinander anpassen können, so wie ein DJ das mit den Plattentellern macht, damit ein guter Übergang entsteht.

    @petaod

    OK super danke. Ich glaube dass das nicht funktioniert liegt wahrscheinlich daran, dass es kein MOD-File ist, sondern eine MP3. Auf der Un4seen-Homepage heisst es:

    BASS is an audio library for use in software on several platforms. Its purpose is to provide developers with powerful and efficient sample, stream (MP3, MP2, MP1, OGG, WAV, AIFF, custom generated, and more via OS codecs and add-ons), MOD music (XM, IT, S3M, MOD, MTM, UMX), MO3 music (MP3/OGG compressed MODs), and recording functions. All in a compact DLL that won't bloat your distribution.

    Das heisst dann wohl das geht nur mit den entsprechenden Dateitypen... Da hab ich die bass.dll wohl überschätzt.

    Aber das muss doch irgendwie anders gehen...??
    @kafffee Sorry, das ist mir zu weit entfernt, damit habe ich noch nicht gespielt.
    Und in die Disco gehe ich auch nicht mehr. ;)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    So, da dass hier ein Tutorial-Thema ist und ich mittlerweile die Lösung gefunden habe (jedenfalls fast), hier mal der lauffähige Code für einen Crossfader mit Pitch Adjust und BPM Counter (ich hab die Lösung für den Pitch Adjust auf mir einer bisher unbekannten Seite gefunden: entwickler-ecke.de). Der Crossfader und die Pitch Adjust lassen sich wunderbar in Echtzeit justieren, ganz ohne Aussetzer. Bass.dll ist da sehr gut.

    Lediglich im Zusammenspiel mit dem BPM Counter gibt es zwei Probleme:

    Die Tracks werden von Anfang an zu schnell abgespielt, und das Pitch lässt sich nicht mehr justieren.

    Wer das umgehen will, der muss erstmal komplett die timerBPMA_Tick und timerBPMB_Tick auskommentieren, dann funktioniert es wieder.

    Irgendwie kommen die sich in die Quere (meine Vermutung ist, dass das an der Funktion .ProcessAudio liegt.

    Ich hab jetzt eine Weile damit herumgespielt und komme auf keine Lösung. Wenn jemand weiss wie man das beheben kann bitte melden. Oder vielleicht kann man ja auch irgendwie tricksen, also z.B. dass zum Messen der BPM die Wiedergabe kurz pausiert wird oder sowas in der Art. Das sind so meine Ideen. Eure Vorschläge sind wie gesagt willkommen :) wäre doch gelacht wenn sich das nicht lösen lässt...

    Edit: Also es liegt an der. ProcessAudio. Hab sie mal auskommentiert und Pitch und Crossfader funktionierten wieder. Bloss wie kann ich machen, dass beides funktioniert?

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports Un4seen.Bass
    3. Imports Un4seen.Bass.AddOn.Mix.BassMix
    4. Imports Un4seen.Bass.Misc
    5. Public Class Form1
    6. Public mixer As Integer
    7. Public _bpmA As New BPMCounter(20, 44100)
    8. Public _bpmB As New BPMCounter(20, 44100)
    9. Public streamA As Integer
    10. Public streamB As Integer
    11. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    12. CrossFader.Minimum = 0
    13. CrossFader.Maximum = 100
    14. CrossFader.Value = 50
    15. PitchA.Minimum = 22050
    16. PitchA.Maximum = 66150
    17. PitchA.Value = 44100
    18. PitchB.Minimum = 22050
    19. PitchB.Maximum = 66150
    20. PitchB.Value = 44100
    21. timerBPMA.Interval = 20
    22. timerBPMB.Interval = 20
    23. Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_CPSPEAKERS, IntPtr.Zero, Nothing)
    24. 'this will be the final mixer output stream being played
    25. mixer = BASS_Mixer_StreamCreate(44100, 2, BASSFlag.BASS_SAMPLE_FLOAT)
    26. 'now we need some channels to plug them in...create two decoding sources
    27. streamA = Bass.BASS_StreamCreateFile("C:\Test1.mp3", 0, 0, BASSFlag.BASS_STREAM_DECODE Or BASSFlag.BASS_SAMPLE_FLOAT)
    28. streamB = Bass.BASS_StreamCreateFile("C:\Test2.mp3", 0, 0, BASSFlag.BASS_STREAM_DECODE Or BASSFlag.BASS_SAMPLE_FLOAT)
    29. Dim infoA As New BASS_CHANNELINFO()
    30. Dim infoB As New BASS_CHANNELINFO()
    31. Bass.BASS_ChannelGetInfo(streamA, infoA)
    32. Bass.BASS_ChannelGetInfo(streamB, infoB)
    33. 'finally we plug them into the mixer (no downmix, since we assume the sources to be stereo)
    34. Dim okA As Boolean = BASS_Mixer_StreamAddChannel(mixer, streamA, BASSFlag.BASS_DEFAULT)
    35. Dim okB As Boolean = BASS_Mixer_StreamAddChannel(mixer, streamB, BASSFlag.BASS_DEFAULT)
    36. 'play the mixer
    37. Bass.BASS_ChannelPlay(mixer, False)
    38. 'now streamA And streamB are both playing And are mixed
    39. _bpmA.Reset(infoA.freq)
    40. _bpmB.Reset(infoB.freq)
    41. ' start our bpm timer callback
    42. timerBPMA.Start()
    43. timerBPMB.Start()
    44. End Sub
    45. Private Sub CrossFader_Scroll(sender As Object, e As EventArgs) Handles CrossFader.Scroll
    46. Bass.BASS_ChannelSetAttribute(streamA, BASSAttribute.BASS_ATTRIB_VOL, CSng(CrossFader.Value / 100))
    47. Bass.BASS_ChannelSetAttribute(streamB, BASSAttribute.BASS_ATTRIB_VOL, CSng(1 - (CrossFader.Value / 100)))
    48. End Sub
    49. Private Sub PitchA_Scroll(sender As Object, e As EventArgs) Handles PitchA.Scroll
    50. Bass.BASS_ChannelSetAttribute(streamA, BASSAttribute.BASS_ATTRIB_FREQ, PitchA.Value)
    51. End Sub
    52. Private Sub PitchB_Scroll(sender As Object, e As EventArgs) Handles PitchB.Scroll
    53. Bass.BASS_ChannelSetAttribute(streamB, BASSAttribute.BASS_ATTRIB_FREQ, PitchB.Value)
    54. End Sub
    55. Private Sub timerBPMA_Tick(sender As Object, e As EventArgs) Handles timerBPMA.Tick
    56. If streamA = 0 OrElse Bass.BASS_ChannelIsActive(streamA) <> BASSActive.BASS_ACTIVE_PLAYING Then
    57. timerBPMA.Stop()
    58. Return
    59. End If
    60. Dim beat As Boolean = _bpmA.ProcessAudio(streamA, True)
    61. If beat Then
    62. lblBPMA.Text = _bpmA.BPM.ToString("#00.0")
    63. End If
    64. End Sub
    65. Private Sub timerBPMB_Tick(sender As Object, e As EventArgs) Handles timerBPMB.Tick
    66. If streamB = 0 OrElse Bass.BASS_ChannelIsActive(streamB) <> BASSActive.BASS_ACTIVE_PLAYING Then
    67. timerBPMB.Stop()
    68. Return
    69. End If
    70. Dim beat As Boolean = _bpmB.ProcessAudio(streamB, True)
    71. If beat Then
    72. lblBPMB.Text = _bpmB.BPM.ToString("#00.0")
    73. End If
    74. End Sub
    75. End Class


    EDIT: So, ich hab die Lösung gefunden. Einfach für den BPM Counter nochmal zwei extra Channels mit den gleichen Attributen kreieren... Also nach Zeile 37:

    VB.NET-Quellcode

    1. streamC = Bass.BASS_StreamCreateFile("C:\Test1.mp3", 0, 0, BASSFlag.BASS_STREAM_DECODE Or BASSFlag.BASS_SAMPLE_FLOAT)
    2. streamD = Bass.BASS_StreamCreateFile("C:\Test2.mp3", 0, 0, BASSFlag.BASS_STREAM_DECODE Or BASSFlag.BASS_SAMPLE_FLOAT)


    Und dann dementsprechend in der timerBPMA_Tick / timerBPMB_Tick alle streamA in streamC bzw. dementsprechend streamB in streamD umschreiben...

    Allerdings werden nur die BPM der Originaldatei errechnet, wenn man das Pitch ändert, ändert sich auch nichts an den BPM. Vielleicht hat ja jemand ne Idee wie das noch gehen könnte, wenn ich das BASS_ATTRIB_FREQ von streamC / streamD in der PitchA_Scroll bzw. PitchB_Scroll auch noch mit ändere, funktioniert das jedenfalls nicht...

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „kafffee“ ()

    So. Was jetzt noch richtig cool wäre, wenn man beispielsweise den streamA auf Lautsprecher legen könnte und den streamB auf Kopfhörer, so dass man richtig das Zeugs dazu hat, wie ein DJ zu mixen.

    Dass man allgemein den Soundausgang auf das gewünschte Gerät legen kann, weiss ich und hab ich schon mittels Bass.BASS_SetDevice realisiert. Nur kann man das irgendwie auch für jeden Channel/Stream getrennt handhaben? Hab irgendwas gelesen von wegen eine neue Instanz der bass.dll zu erzeugen also dann ein zweites Bass. BASS_Init benutzen zu können, nur wie das dann genau gehen soll hab ich nicht gefunden...

    Und noch eine Frage bzw. mehrere:
    @Kombrinki
    Es geht um das Thema "Amplitude von bestimmten Frequenzen auslesen", das ja im bass.dll Tutorial so gecodet wird:

    VB.NET-Quellcode

    1. Dim FFT(2048) As Single
    2. Bass.BASS_ChannelGetData(stream, value, BASSData.BASS_DATAFFT256)
    3. Dim data(128) As Double
    4. For i = 0 To 128
    5. data(i) = value(i * 4)
    6. Next
    7. Dim 125Hz As Integer = (128 * 125 / 44100)
    8. Dim Freq As Integer
    9. Freq = data(125Hz)


    (1) Was ist mit FFT(2048) As Single? Das wird deklariert und nicht verwendet...
    (2)Was ist mit der Variable value? Die wird verwendet und nicht deklariert... Sehe ich das richtig, dass mir value dann die Amplitude der gewählten Frequenz mitteilen soll?
    (3) Dim 125Hz scheint mir kein gültiger Variablenname zu sein??
    (4) Was liefert mir die Vatiable Freq?

    Ich verstehe den Code vorne und hinten nicht und wäre froh, wenn mir da jemand unter die Arme greifen würde...

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

    kafffee schrieb:

    VB.NET-Quellcode

    1. Dim 125Hz As Integer = (128 * 125 / 44100)
    Das sind bei mir zwei Fehler.
    ==>

    VB.NET-Quellcode

    1. Dim _125Hz As Integer = (128 * 125 \ 44100)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    kafffee schrieb:

    FFT()
    Sieht aus als würde dort die Fouriertransformierte berechnet, mit den Daten kannst Du den Frequenzgang darstellen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Also das bisschen Code ist aus mehreren Codes via C&P entstanden bahaupte ich mal, wenn das so aus dem Tutorial stammt, vergiss das Tutorial ganz schnell.

    ->Die variable FFT ist ungenutzt in deinem Code.
    ->value wird verwendet aber nicht deklariert, wurde der Code evtl. Tot editiert?
    ->Freq sollte dann die Amplitude dieser Frequenz halten.

    Aber vergiss den Code den du da hast, scheint viel Müll(im warsten Sinne des Wortes) drin zu sein.
    Hier ein Beispiel mit Timer, noch besser eines der SyncProcs der bass nutzen und das dort machen.

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Imports Un4seen.Bass
    3. Imports Un4seen.Bass.Utils
    4. Public Class Form1
    5. Private hstream As Integer
    6. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    7. If Not Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_CPSPEAKERS, 0) Then
    8. MessageBox.Show("BASS_Init: " & Bass.BASS_ErrorGetCode().ToString())
    9. Close()
    10. End If
    11. hstream = Bass.BASS_StreamCreateURL("https://wdr-1live-live.icecastssl.wdr.de/wdr/1live/live/mp3/128/stream.mp3", 0, BASSFlag.BASS_STREAM_AUTOFREE, Nothing, IntPtr.Zero)
    12. If hstream = 0 Then
    13. MessageBox.Show("hstream: is NULL")
    14. Close()
    15. End If
    16. Bass.BASS_ChannelPlay(hstream, False)
    17. End Sub
    18. Private Sub Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
    19. If Bass.BASS_ChannelIsActive(hstream) <> BASSActive.BASS_ACTIVE_STOPPED Then
    20. Bass.BASS_ChannelStop(hstream)
    21. End If
    22. Bass.BASS_Free()
    23. End Sub
    24. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    25. If Bass.BASS_ChannelIsActive(hstream) = BASSActive.BASS_ACTIVE_PLAYING Then
    26. Dim fft() As Single = New Single(1024) {} 'hier sind nach BASS_ChannelGetData die FFT daten drin(wenn erfolgreich)
    27. If -1 = Bass.BASS_ChannelGetData(hstream, fft, BASSData.BASS_DATA_FFT512) Then '-1 ein fehler trat auf
    28. Debug.WriteLine("BASS_ChannelGetData: " & Bass.BASS_ErrorGetCode().ToString())
    29. Else
    30. Dim frequency As Integer = 500 'die frequenz deren Amplitude wir wollen
    31. Dim index As Integer = Utils.FFTFrequency2Index(frequency, 512, 44100) 'wo sich der Wert im fft-Array befindet ermitteln
    32. Debug.WriteLine(fft(index)) 'amplitude von 500Hz ausgeben
    33. End If
    34. End If
    35. End Sub
    36. End Class


    Noch ein paar Sachen....
    Die Samplerate des Streams vorher ermitteln, auch die Anzahl der Kanäle, denn pro Kanal mehr haben wir mehr Daten, bei BASSData.BASS_DATA_FFT512 und 2 Kanälen haben wir 1024 Werte, daher ist der fft-Array auch so gros. Ich habe einiges fixed gemacht, was u.U. aber dynamisch sein kann(z.B. Samplerate 96000 statt 44100, oder nur eine Tonspur statt 2), somit Fehler eintreten könnten.

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

    @Takafusa

    Wow super vielen Dank :)

    Nur noch zwei Fragen.

    (1)In welcher Einheit wird die Amplitude dann ausgegeben, bzw. in welchem prozentualen Verhältnis zur Gesamtamplitude? Ich nehme an in einer Range von 0 - 10??
    (2) Ich möchte das Ganze in einer ProgressBar darstellen. Die brauch in der .Value ja nen Integer. Hab jetzt mal eine Range von 0-10 eingestelllt und möchte dann immer auf eine Ganzzahl abrunden. Der Code:

    VB.NET-Quellcode

    1. barFreqAmp.Value = CInt(Math.Floor(fft(index))) 'amplitude von 500Hz ausgeben


    Nur kommt da immer der Wert 0 raus, hab die Zahl mal auf einem Label ausgeben lassen, wenn ich direkt die Single ausgebe funktioniert es aber...

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „kafffee“ ()

    kafffee schrieb:

    Ich nehme an in einer Range von 0 - 10??
    Lass einen Stream konvertieren und sieh Dir das Maximum an.
    Der Rest wäre pure Anamologie.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    kafffee schrieb:

    "Stream konvertieren"
    Schlechte Formulierung.
    Sieh Dir alle verfügbaren Daten an und suche von denen das Maximum und das Minimum. Es könnte dann +-10 sein.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!