Fehler in meinem Script (Bass.dll)

    • [ gelöst ]

      Fehler in meinem Script (Bass.dll)

      Hey @ all,
      ich hab mal wieder eine Frage zu den BassDlls. Leider habe ich noch nicht sehr viel Erfahrung damit gesammelt, und habe versuch ein kleines Script zu schreiben, welches aber nicht funktioniert :( .
      Ich hoffe jemand kann mir weiterhelfen.

      Hier mein Script:
      Spoiler anzeigen

      AutoIt-Quellcode

      1. #include <Bass.au3>
      2. #include <BassConstants.au3>
      3. #include <BassFX.au3>
      4. #include <BassMix.au3>
      5. #include <BassEnc.au3>
      6. _BASS_Startup(@ScriptDir & "\bass.dll")
      7. _BASS_MIX_Startup(@ScriptDir & "\bassmix.dll")
      8. _BASS_FX_Startup(@ScriptDir & "\bass_fx.dll")
      9. _BASS_Init(0, -1, 44100, 0, "")
      10. _BASS_Encode_Startup()
      11. $smpl1 = _BASS_StreamCreateFile(False, @ScriptDir & "\beispiel_1.mp3", 0, 0, $BASS_STREAM_DECODE)
      12. $smpl2 = _BASS_StreamCreateFile(False, @ScriptDir & "\beispiel_2.mp3", 0, 0, $BASS_STREAM_DECODE)
      13. $hTempo1 = _BASS_FX_TempoCreate($smpl1, 0)
      14. _BASS_ChannelSetAttribute($hTempo1, $BASS_ATTRIB_TEMPO, 0)
      15. _BASS_ChannelSetAttribute($hTempo1, $BASS_ATTRIB_TEMPO_PITCH, 0)
      16. $hTempo2 = _BASS_FX_TempoCreate($smpl2, 0)
      17. _BASS_ChannelSetAttribute($hTempo2, $BASS_ATTRIB_TEMPO, 0)
      18. _BASS_ChannelSetAttribute($hTempo2, $BASS_ATTRIB_TEMPO_PITCH, 0)
      19. $hMixer = _BASS_Mixer_StreamCreate(44100, 2, 0)
      20. _BASS_Mixer_StreamAddChannel($hMixer,$hTempo1, 0)
      21. _BASS_Mixer_StreamAddChannel($hMixer,$hTempo2, 0)
      22. _BASS_ChannelPlay($hMixer, 1)
      23. _BASS_Encode_Start($hMixer, @ScriptDir & "\test.wav", $BASS_ENCODE_PCM)
      24. sleep(1000)
      25. _BASS_STOP()
      26. _BASS_FREE()


      mfG Developer30
      "Je mehr Käse, desto mehr Löcher; je mehr Löcher, desto weniger Käse. Ergo: Je mehr Käse, desto weniger Käse. 8| "
      "Programmers never die: they just GOSUB without RETURN"
      "I tried to change the world but I couldn't find the source code."

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

      habe mich nochmal hiermit beschäftigt.. das thema liegt zwar schon länger zurück, aber ich habe nochmal ein paar Fragen...
      Warum funktioniert das Script nur dann, wenn da _BASS_ChannelPlay($hMixer, 1) steht?

      Und ist es möglich, dass die Streams nicht gleichzeitig sondern hintereinander abgespielt werden.. Ich hab was von _BASS_Mixer_StreamAddChannelEx. Ist eine Verzögerung damit möglich? Wenn ja, wie?

      Spoiler anzeigen

      AutoIt-Quellcode

      1. #include <Bass.au3>
      2. #include <BassConstants.au3>
      3. #include <BassFX.au3>
      4. #include <BassMix.au3>
      5. #include <BassExt.au3>
      6. #include <BassEnc.au3>
      7. _BASS_Startup(@ScriptDir & "\bass.dll")
      8. _BASS_MIX_Startup(@ScriptDir & "\bassmix.dll")
      9. _BASS_FX_Startup(@ScriptDir & "\bass_fx.dll")
      10. _BASS_EXT_Startup(@ScriptDir & "\bassext.dll")
      11. _BASS_Init(0, -1, 44100, 0, "")
      12. _BASS_Encode_Startup()
      13. $smpl1 = _BASS_StreamCreateFile(False, @ScriptDir & "\test1.mp3", 0, 0, $BASS_STREAM_DECODE)
      14. $smpl2 = _BASS_StreamCreateFile(False, @ScriptDir & "\test2.wav", 0, 0, $BASS_STREAM_DECODE)
      15. $hTempo1 = _BASS_FX_TempoCreate($smpl1, $BASS_STREAM_DECODE)
      16. _BASS_ChannelSetAttribute($hTempo1, $BASS_ATTRIB_TEMPO, 0)
      17. _BASS_ChannelSetAttribute($hTempo1, $BASS_ATTRIB_TEMPO_PITCH, 0)
      18. $hTempo2 = _BASS_FX_TempoCreate($smpl2, $BASS_STREAM_DECODE)
      19. _BASS_ChannelSetAttribute($hTempo2, $BASS_ATTRIB_TEMPO, 0)
      20. _BASS_ChannelSetAttribute($hTempo2, $BASS_ATTRIB_TEMPO_PITCH, 0)
      21. $hMixer = _BASS_Mixer_StreamCreate(44100, 2, 0)
      22. _BASS_Mixer_StreamAddChannel($hMixer,$hTempo1, 0)
      23. _BASS_Mixer_StreamAddChannel($hMixer,$hTempo2, 0)
      24. _BASS_ChannelPlay($hMixer, 1)
      25. _BASS_Encode_Start($hMixer, @ScriptDir & "\test.wav", $BASS_ENCODE_PCM)
      26. sleep(1000)
      27. _BASS_STOP()
      28. _BASS_RecordFree()
      29. _BASS_FREE()
      "Je mehr Käse, desto mehr Löcher; je mehr Löcher, desto weniger Käse. Ergo: Je mehr Käse, desto weniger Käse. 8| "
      "Programmers never die: they just GOSUB without RETURN"
      "I tried to change the world but I couldn't find the source code."
      Im Prinzip ganz einfach:

      AutoIt-Quellcode

      1. $iBytesStart = _BASS_ChannelSeconds2Bytes($hTempo2, 5)
      2. $iBytesLength = _BASS_ChannelSeconds2Bytes($hTempo2, 3)
      3. ConsoleWrite(@CRLF & "! Start nach 5s = " & $iBytesStart & " bytes / spiele 3s = " & $iBytesLength & " bytes" & @CRLF & @CRLF)
      4. _BASS_Mixer_StreamAddChannelEx($hMixer, $hTempo2, 0, $iBytesStart, $iBytesLength)


      Allerdings hat die BassMix.au3 hier einen Bug:
      Zeile 599 :

      AutoIt-Quellcode

      1. Local $BASS_ret_ = DllCall($_ghBassMixDll, "int", "BASS_Mixer_StreamAddChannelEx", "hwnd", $handle, "dword", $channel, "uint64", $length)

      muss natürlich so aussehen:

      AutoIt-Quellcode

      1. Local $BASS_ret_ = DllCall($_ghBassMixDll, "int", "BASS_Mixer_StreamAddChannelEx", "hwnd", $handle, "dword", $channel, "dword", $flags, "uint64", $start, "uint64", $length)


      E

      Edit: Alternativ dazu kann man auch einen Syncpunkt (BASS_ChannelSetSync) erstellen, an dem dann das nächste Sample gestartet wird - das muss ich mir aber erst mal genauer ansehen

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

      ich glaube ich hab eine ältere Version der BassMix.au3.. bei mir ist das jedenfalls nicht Zeile 599 sondern 512.
      Warum gibt mir Encode immer eine 36byte datei zurück, sobald ich _BASS_ChannelPlay($hMixer, 1) auskommentiere?
      "Je mehr Käse, desto mehr Löcher; je mehr Löcher, desto weniger Käse. Ergo: Je mehr Käse, desto weniger Käse. 8| "
      "Programmers never die: they just GOSUB without RETURN"
      "I tried to change the world but I couldn't find the source code."
      Um die Samples zum Encoder zu bekommen, gibt es 2 Möglichkeiten:

      1) Normalen Stream abspielen (wie jetzt)
      2) Decoding Stream verwenden und mit _BASS_ChannelGetData die Samples "auslesen"

      Vielleicht hilft dir dieses Beispiel etwas weiter:
      Spoiler anzeigen

      AutoIt-Quellcode

      1. #AutoIt3Wrapper_UseX64=n
      2. #include "Bass.au3"
      3. #include "BassMix.au3"
      4. #include "BassEnc.au3"
      5. Global $iOutputFreq = 32000
      6. _BASS_Startup()
      7. ___Debug(@error, "load bass.dll")
      8. _BASS_ENCODE_Startup()
      9. ___Debug(@error, "load bassenc.dll")
      10. _BASS_MIX_Startup()
      11. ___Debug(@error, "load bassmix.dll")
      12. _BASS_Init(0, -1, 44100, 0, "")
      13. ___Debug(@error, "initialize bass")
      14. Global $tBuffer = DllStructCreate("byte[20000]")
      15. Global $pBuffer = DllStructGetPtr($tBuffer)
      16. Global $iBuffer = DllStructGetSize($tBuffer)
      17. $sFile = FileOpenDialog("Open...", "", "Wav Files (*.wav)")
      18. ___Debug($sFile = "", $sFile)
      19. $hMusicHandle = _BASS_StreamCreateFile(False, $sFile, 0, 0, $BASS_STREAM_DECODE)
      20. ___Debug(@error, "create stream from file")
      21. $aInfo = _BASS_ChannelGetInfo($hMusicHandle)
      22. ___Debug(@error, "get channel infos")
      23. $hMixer = _BASS_Mixer_StreamCreate($iOutputFreq, $aInfo[1], BitOR($BASS_MIXER_END, $BASS_STREAM_DECODE))
      24. ___Debug(@error, "create mixer stream")
      25. _BASS_Mixer_StreamAddChannel($hMixer, $hMusicHandle, $BASS_MIXER_FILTER)
      26. ___Debug(@error, "add channel to mixer")
      27. $hEncoder = _BASS_Encode_Start($hMixer, @ScriptDir & "\Resampled.wav", $BASS_ENCODE_PCM)
      28. ___Debug(@error, "set up encoder")
      29. $iBytes = _BASS_ChannelGetLength($hMusicHandle, $BASS_POS_BYTE)
      30. ___Debug(@error, "get filesize: " & $iBytes)
      31. $iBytes = $iBytes * $iOutputFreq / $aInfo[0]
      32. $iDone = 0
      33. While _BASS_ChannelIsActive($hMixer)
      34. $iLength = _BASS_ChannelGetData($hMixer, $pBuffer, $iBuffer)
      35. ___Debug(@error, "read data: " & $iLength & " bytes")
      36. $iDone += $iLength
      37. ___Debug(-1, Round($iDone * 100 / $iBytes) & "% done")
      38. WEnd
      39. _BASS_Encode_Stop($hEncoder)
      40. ___Debug(@error, "stop encoder")
      41. _BASS_StreamFree($hMixer)
      42. ___Debug(@error, "free stream")
      43. _BASS_Free()
      44. ___Debug(@error, "free bass")
      45. Func ___DeBug($iError, $sAction)
      46. Switch $iError
      47. Case -1
      48. ConsoleWrite(@CRLF & "-" & $sAction & @CRLF)
      49. Case 0
      50. ConsoleWrite(@CRLF & "+" & $sAction & " - OK" & @CRLF)
      51. Case Else
      52. ConsoleWrite(@CRLF & "!" & $sAction & " - FAILED" & @CRLF)
      53. Exit
      54. EndSwitch
      55. EndFunc ;==>___DeBug


      mfgE
      thx für das beispiel.. ich werde mal versuchen meine Ideen damit umzusetzen.. :)
      "Je mehr Käse, desto mehr Löcher; je mehr Löcher, desto weniger Käse. Ergo: Je mehr Käse, desto weniger Käse. 8| "
      "Programmers never die: they just GOSUB without RETURN"
      "I tried to change the world but I couldn't find the source code."
      Encoded 10 Sekunden von test1.mp3, nach 5 Sekunden startet test2.wav für 3 Sekunden:

      Spoiler anzeigen

      AutoIt-Quellcode

      1. #include "Bass.au3"
      2. #include "BassFX.au3"
      3. #include "BassMix.au3"
      4. #include "BassExt.au3"
      5. #include "BassEnc.au3"
      6. _BASS_Startup(@ScriptDir & "\bass.dll")
      7. _BASS_MIX_Startup(@ScriptDir & "\bassmix.dll")
      8. _BASS_FX_Startup(@ScriptDir & "\bass_fx.dll")
      9. _BASS_EXT_Startup(@ScriptDir & "\bassext.dll")
      10. _BASS_Init(0, -1, 44100, 0, "")
      11. _BASS_Encode_Startup()
      12. $smpl1 = _BASS_StreamCreateFile(False, @ScriptDir & "\test1.mp3", 0, 0, $BASS_STREAM_DECODE)
      13. $smpl2 = _BASS_StreamCreateFile(False, @ScriptDir & "\test2.wav", 0, 0, $BASS_STREAM_DECODE)
      14. $hTempo1 = _BASS_FX_TempoCreate($smpl1, $BASS_STREAM_DECODE)
      15. _BASS_ChannelSetAttribute($hTempo1, $BASS_ATTRIB_TEMPO, 0)
      16. _BASS_ChannelSetAttribute($hTempo1, $BASS_ATTRIB_TEMPO_PITCH, 0)
      17. $hTempo2 = _BASS_FX_TempoCreate($smpl2, $BASS_STREAM_DECODE)
      18. _BASS_ChannelSetAttribute($hTempo2, $BASS_ATTRIB_TEMPO, 0)
      19. _BASS_ChannelSetAttribute($hTempo2, $BASS_ATTRIB_TEMPO_PITCH, 0)
      20. $hMixer = _BASS_Mixer_StreamCreate(44100, 2, BitOR($BASS_MIXER_END, $BASS_STREAM_DECODE))
      21. _BASS_Mixer_StreamAddChannel($hMixer, $hTempo1, 0)
      22. $iBytesStart = _BASS_ChannelSeconds2Bytes($hTempo2, 5)
      23. $iBytesLength = _BASS_ChannelSeconds2Bytes($hTempo2, 3)
      24. ConsoleWrite(@CRLF & "! Start nach 5s = " & $iBytesStart & " bytes / spiele 3s = " & $iBytesLength & " bytes" & @CRLF & @CRLF)
      25. _BASS_Mixer_StreamAddChannelEx($hMixer, $hTempo2, 0, $iBytesStart, $iBytesLength)
      26. _BASS_Encode_Start($hMixer, @ScriptDir & "\test.wav", $BASS_ENCODE_PCM)
      27. Global $tBuffer = DllStructCreate("byte[20000]")
      28. Global $pBuffer = DllStructGetPtr($tBuffer)
      29. $iBytesEncode = _BASS_ChannelSeconds2Bytes($hMixer, 10) ; 10 sekunden Aufnahmelänge
      30. For $i = 1 To $iBytesEncode Step 20000
      31. If $i + 20000 <= $iBytesEncode Then
      32. _BASS_ChannelGetData($hMixer, $pBuffer, 20000)
      33. Else
      34. _BASS_ChannelGetData($hMixer, $pBuffer, $iBytesEncode - $i)
      35. EndIf
      36. Next
      37. _BASS_FREE()
      Hab einen kleinen Fehler gemacht!

      Bei _BASS_ChannelSeconds2Bytes musst du den Handle des Mixerstreams verwenden, sonst stimmen die Sekunden nicht, wenn du Samples mit anderer Samplingfrequenz verwendest!

      Hier noch ein kurzes Beispiel:
      Spoiler anzeigen

      AutoIt-Quellcode

      1. #include "Bass.au3"
      2. #include "BassMix.au3"
      3. #include "BassEnc.au3"
      4. ;result: 0s 10s
      5. ;output.wav: |----------------------------|
      6. ;sample1.wav: |----------|
      7. ;sample2.wav: |----------------|
      8. ;sample3.wav: |-------------|
      9. $iBufferSize = 20000 ; bytes
      10. _BASS_Startup()
      11. _BASS_MIX_Startup()
      12. _BASS_Encode_Startup()
      13. _BASS_Init(0, -1, 44100, 0, "")
      14. $hStream1 = _BASS_StreamCreateFile(False, @ScriptDir & "\sample1.wav", 0, 0, $BASS_STREAM_DECODE)
      15. $hStream2 = _BASS_StreamCreateFile(False, @ScriptDir & "\sample2.wav", 0, 0, $BASS_STREAM_DECODE)
      16. _BASS_ChannelSetPosition($hStream2, _BASS_ChannelSeconds2Bytes($hStream2, 5), $BASS_POS_BYTE) ;sample offset: 5s
      17. $hStream3 = _BASS_StreamCreateFile(False, @ScriptDir & "\sample3.wav", 0, 0, $BASS_STREAM_DECODE)
      18. $hMixer = _BASS_Mixer_StreamCreate(44100, 2, BitOR($BASS_MIXER_END, $BASS_STREAM_DECODE))
      19. _BASS_Mixer_StreamAddChannelEx($hMixer, $hStream1, BitOR($BASS_MIXER_FILTER, $BASS_STREAM_AUTOFREE), _
      20. _BASS_ChannelSeconds2Bytes($hMixer, 1), _BASS_ChannelSeconds2Bytes($hMixer, 4)) ;sample1.wav: start: 1s / duration: 4s
      21. _BASS_Mixer_StreamAddChannelEx($hMixer, $hStream2, BitOR($BASS_MIXER_FILTER, $BASS_STREAM_AUTOFREE), _
      22. _BASS_ChannelSeconds2Bytes($hMixer, 3), _BASS_ChannelSeconds2Bytes($hMixer, 6)) ;sample2.wav: start: 3s (sample offset 5s) / duration: 6s
      23. _BASS_Mixer_StreamAddChannelEx($hMixer, $hStream3, BitOR($BASS_MIXER_FILTER, $BASS_STREAM_AUTOFREE), _
      24. _BASS_ChannelSeconds2Bytes($hMixer, 6), _BASS_ChannelSeconds2Bytes($hMixer, 5)) ;sample3.wav: start: 6s / duration: 5s
      25. _BASS_Encode_Start($hMixer, @ScriptDir & "\output.wav", $BASS_ENCODE_PCM)
      26. $tBuffer = DllStructCreate("byte[" & $iBufferSize & "]")
      27. $pBuffer = DllStructGetPtr($tBuffer)
      28. $iBytesEncode = _BASS_ChannelSeconds2Bytes($hMixer, 10); max length of output.wav
      29. For $i = 1 To $iBytesEncode Step $iBufferSize
      30. If $i + $iBufferSize <= $iBytesEncode Then
      31. _BASS_ChannelGetData($hMixer, $pBuffer, $iBufferSize)
      32. Else
      33. _BASS_ChannelGetData($hMixer, $pBuffer, $iBytesEncode - $i)
      34. EndIf
      35. Next
      36. _BASS_FREE()
    autoit.de Webutation