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]

    #include <Bass.au3>
    #include <BassConstants.au3>
    #include <BassFX.au3>
    #include <BassMix.au3>
    #include <BassEnc.au3>
    _BASS_Startup(@ScriptDir & "\bass.dll")
    _BASS_MIX_Startup(@ScriptDir & "\bassmix.dll")
    _BASS_FX_Startup(@ScriptDir & "\bass_fx.dll")
    _BASS_Init(0, -1, 44100, 0, "")
    _BASS_Encode_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    $smpl1 = _BASS_StreamCreateFile(False, @ScriptDir & "\beispiel_1.mp3", 0, 0, $BASS_STREAM_DECODE)
    $smpl2 = _BASS_StreamCreateFile(False, @ScriptDir & "\beispiel_2.mp3", 0, 0, $BASS_STREAM_DECODE)

    [/autoit] [autoit][/autoit] [autoit]

    $hTempo1 = _BASS_FX_TempoCreate($smpl1, 0)
    _BASS_ChannelSetAttribute($hTempo1, $BASS_ATTRIB_TEMPO, 0)
    _BASS_ChannelSetAttribute($hTempo1, $BASS_ATTRIB_TEMPO_PITCH, 0)
    $hTempo2 = _BASS_FX_TempoCreate($smpl2, 0)
    _BASS_ChannelSetAttribute($hTempo2, $BASS_ATTRIB_TEMPO, 0)
    _BASS_ChannelSetAttribute($hTempo2, $BASS_ATTRIB_TEMPO_PITCH, 0)

    [/autoit] [autoit][/autoit] [autoit]

    $hMixer = _BASS_Mixer_StreamCreate(44100, 2, 0)
    _BASS_Mixer_StreamAddChannel($hMixer,$hTempo1, 0)
    _BASS_Mixer_StreamAddChannel($hMixer,$hTempo2, 0)
    _BASS_ChannelPlay($hMixer, 1)
    _BASS_Encode_Start($hMixer, @ScriptDir & "\test.wav", $BASS_ENCODE_PCM)

    [/autoit] [autoit][/autoit] [autoit]

    sleep(1000)
    _BASS_STOP()
    _BASS_FREE()

    [/autoit]

    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."

    3 Mal editiert, zuletzt von Developer30 (1. November 2010 um 11:57)

  • thx^^

    "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."

  • 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]

    #include <Bass.au3>
    #include <BassConstants.au3>
    #include <BassFX.au3>
    #include <BassMix.au3>
    #include <BassExt.au3>
    #include <BassEnc.au3>
    _BASS_Startup(@ScriptDir & "\bass.dll")
    _BASS_MIX_Startup(@ScriptDir & "\bassmix.dll")
    _BASS_FX_Startup(@ScriptDir & "\bass_fx.dll")
    _BASS_EXT_Startup(@ScriptDir & "\bassext.dll")
    _BASS_Init(0, -1, 44100, 0, "")
    _BASS_Encode_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    $smpl1 = _BASS_StreamCreateFile(False, @ScriptDir & "\test1.mp3", 0, 0, $BASS_STREAM_DECODE)
    $smpl2 = _BASS_StreamCreateFile(False, @ScriptDir & "\test2.wav", 0, 0, $BASS_STREAM_DECODE)

    [/autoit] [autoit][/autoit] [autoit]

    $hTempo1 = _BASS_FX_TempoCreate($smpl1, $BASS_STREAM_DECODE)
    _BASS_ChannelSetAttribute($hTempo1, $BASS_ATTRIB_TEMPO, 0)
    _BASS_ChannelSetAttribute($hTempo1, $BASS_ATTRIB_TEMPO_PITCH, 0)
    $hTempo2 = _BASS_FX_TempoCreate($smpl2, $BASS_STREAM_DECODE)
    _BASS_ChannelSetAttribute($hTempo2, $BASS_ATTRIB_TEMPO, 0)
    _BASS_ChannelSetAttribute($hTempo2, $BASS_ATTRIB_TEMPO_PITCH, 0)

    [/autoit] [autoit][/autoit] [autoit]

    $hMixer = _BASS_Mixer_StreamCreate(44100, 2, 0)
    _BASS_Mixer_StreamAddChannel($hMixer,$hTempo1, 0)
    _BASS_Mixer_StreamAddChannel($hMixer,$hTempo2, 0)
    _BASS_ChannelPlay($hMixer, 1)
    _BASS_Encode_Start($hMixer, @ScriptDir & "\test.wav", $BASS_ENCODE_PCM)

    [/autoit] [autoit][/autoit] [autoit]

    sleep(1000)
    _BASS_STOP()
    _BASS_RecordFree()
    _BASS_FREE()

    [/autoit]

    "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]

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

    [/autoit]

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

    [autoit]

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

    [/autoit]


    muss natürlich so aussehen:

    [autoit]

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

    [/autoit]

    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

  • 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."

  • ja

    "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]

    #AutoIt3Wrapper_UseX64=n
    #include "Bass.au3"
    #include "BassMix.au3"
    #include "BassEnc.au3"

    [/autoit] [autoit][/autoit] [autoit]

    Global $iOutputFreq = 32000

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Startup()
    ___Debug(@error, "load bass.dll")

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_ENCODE_Startup()
    ___Debug(@error, "load bassenc.dll")

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_MIX_Startup()
    ___Debug(@error, "load bassmix.dll")

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Init(0, -1, 44100, 0, "")
    ___Debug(@error, "initialize bass")

    [/autoit] [autoit][/autoit] [autoit]

    Global $tBuffer = DllStructCreate("byte[20000]")
    Global $pBuffer = DllStructGetPtr($tBuffer)
    Global $iBuffer = DllStructGetSize($tBuffer)

    [/autoit] [autoit][/autoit] [autoit]

    $sFile = FileOpenDialog("Open...", "", "Wav Files (*.wav)")
    ___Debug($sFile = "", $sFile)

    [/autoit] [autoit][/autoit] [autoit]

    $hMusicHandle = _BASS_StreamCreateFile(False, $sFile, 0, 0, $BASS_STREAM_DECODE)
    ___Debug(@error, "create stream from file")
    $aInfo = _BASS_ChannelGetInfo($hMusicHandle)
    ___Debug(@error, "get channel infos")

    [/autoit] [autoit][/autoit] [autoit]

    $hMixer = _BASS_Mixer_StreamCreate($iOutputFreq, $aInfo[1], BitOR($BASS_MIXER_END, $BASS_STREAM_DECODE))
    ___Debug(@error, "create mixer stream")

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Mixer_StreamAddChannel($hMixer, $hMusicHandle, $BASS_MIXER_FILTER)
    ___Debug(@error, "add channel to mixer")

    [/autoit] [autoit][/autoit] [autoit]

    $hEncoder = _BASS_Encode_Start($hMixer, @ScriptDir & "\Resampled.wav", $BASS_ENCODE_PCM)
    ___Debug(@error, "set up encoder")

    [/autoit] [autoit][/autoit] [autoit]

    $iBytes = _BASS_ChannelGetLength($hMusicHandle, $BASS_POS_BYTE)
    ___Debug(@error, "get filesize: " & $iBytes)

    [/autoit] [autoit][/autoit] [autoit]

    $iBytes = $iBytes * $iOutputFreq / $aInfo[0]
    $iDone = 0

    [/autoit] [autoit][/autoit] [autoit]

    While _BASS_ChannelIsActive($hMixer)
    $iLength = _BASS_ChannelGetData($hMixer, $pBuffer, $iBuffer)
    ___Debug(@error, "read data: " & $iLength & " bytes")

    [/autoit] [autoit][/autoit] [autoit]

    $iDone += $iLength
    ___Debug(-1, Round($iDone * 100 / $iBytes) & "% done")
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Encode_Stop($hEncoder)
    ___Debug(@error, "stop encoder")

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_StreamFree($hMixer)
    ___Debug(@error, "free stream")

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Free()
    ___Debug(@error, "free bass")

    [/autoit] [autoit][/autoit] [autoit]

    Func ___DeBug($iError, $sAction)
    Switch $iError
    Case -1
    ConsoleWrite(@CRLF & "-" & $sAction & @CRLF)
    Case 0
    ConsoleWrite(@CRLF & "+" & $sAction & " - OK" & @CRLF)
    Case Else
    ConsoleWrite(@CRLF & "!" & $sAction & " - FAILED" & @CRLF)
    Exit
    EndSwitch
    EndFunc ;==>___DeBug

    [/autoit]

    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]

    #include "Bass.au3"
    #include "BassFX.au3"
    #include "BassMix.au3"
    #include "BassExt.au3"
    #include "BassEnc.au3"
    _BASS_Startup(@ScriptDir & "\bass.dll")
    _BASS_MIX_Startup(@ScriptDir & "\bassmix.dll")
    _BASS_FX_Startup(@ScriptDir & "\bass_fx.dll")
    _BASS_EXT_Startup(@ScriptDir & "\bassext.dll")
    _BASS_Init(0, -1, 44100, 0, "")
    _BASS_Encode_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    $smpl1 = _BASS_StreamCreateFile(False, @ScriptDir & "\test1.mp3", 0, 0, $BASS_STREAM_DECODE)
    $smpl2 = _BASS_StreamCreateFile(False, @ScriptDir & "\test2.wav", 0, 0, $BASS_STREAM_DECODE)

    [/autoit] [autoit][/autoit] [autoit]

    $hTempo1 = _BASS_FX_TempoCreate($smpl1, $BASS_STREAM_DECODE)
    _BASS_ChannelSetAttribute($hTempo1, $BASS_ATTRIB_TEMPO, 0)
    _BASS_ChannelSetAttribute($hTempo1, $BASS_ATTRIB_TEMPO_PITCH, 0)
    $hTempo2 = _BASS_FX_TempoCreate($smpl2, $BASS_STREAM_DECODE)
    _BASS_ChannelSetAttribute($hTempo2, $BASS_ATTRIB_TEMPO, 0)
    _BASS_ChannelSetAttribute($hTempo2, $BASS_ATTRIB_TEMPO_PITCH, 0)

    [/autoit] [autoit][/autoit] [autoit]

    $hMixer = _BASS_Mixer_StreamCreate(44100, 2, BitOR($BASS_MIXER_END, $BASS_STREAM_DECODE))
    _BASS_Mixer_StreamAddChannel($hMixer, $hTempo1, 0)

    [/autoit] [autoit][/autoit] [autoit]

    $iBytesStart = _BASS_ChannelSeconds2Bytes($hTempo2, 5)
    $iBytesLength = _BASS_ChannelSeconds2Bytes($hTempo2, 3)
    ConsoleWrite(@CRLF & "! Start nach 5s = " & $iBytesStart & " bytes / spiele 3s = " & $iBytesLength & " bytes" & @CRLF & @CRLF)
    _BASS_Mixer_StreamAddChannelEx($hMixer, $hTempo2, 0, $iBytesStart, $iBytesLength)
    _BASS_Encode_Start($hMixer, @ScriptDir & "\test.wav", $BASS_ENCODE_PCM)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $tBuffer = DllStructCreate("byte[20000]")
    Global $pBuffer = DllStructGetPtr($tBuffer)

    [/autoit] [autoit][/autoit] [autoit]

    $iBytesEncode = _BASS_ChannelSeconds2Bytes($hMixer, 10) ; 10 sekunden Aufnahmelänge

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $iBytesEncode Step 20000
    If $i + 20000 <= $iBytesEncode Then
    _BASS_ChannelGetData($hMixer, $pBuffer, 20000)
    Else
    _BASS_ChannelGetData($hMixer, $pBuffer, $iBytesEncode - $i)
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_FREE()

    [/autoit]
  • perfekt :thumbup:
    danke :party:

    "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."

  • 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]

    #include "Bass.au3"
    #include "BassMix.au3"
    #include "BassEnc.au3"

    [/autoit] [autoit][/autoit] [autoit]

    ;result: 0s 10s
    ;output.wav: |----------------------------|
    ;sample1.wav: |----------|
    ;sample2.wav: |----------------|
    ;sample3.wav: |-------------|

    [/autoit] [autoit][/autoit] [autoit]

    $iBufferSize = 20000 ; bytes

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Startup()
    _BASS_MIX_Startup()
    _BASS_Encode_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Init(0, -1, 44100, 0, "")

    [/autoit] [autoit][/autoit] [autoit]

    $hStream1 = _BASS_StreamCreateFile(False, @ScriptDir & "\sample1.wav", 0, 0, $BASS_STREAM_DECODE)

    [/autoit] [autoit][/autoit] [autoit]

    $hStream2 = _BASS_StreamCreateFile(False, @ScriptDir & "\sample2.wav", 0, 0, $BASS_STREAM_DECODE)
    _BASS_ChannelSetPosition($hStream2, _BASS_ChannelSeconds2Bytes($hStream2, 5), $BASS_POS_BYTE) ;sample offset: 5s

    [/autoit] [autoit][/autoit] [autoit]

    $hStream3 = _BASS_StreamCreateFile(False, @ScriptDir & "\sample3.wav", 0, 0, $BASS_STREAM_DECODE)

    [/autoit] [autoit][/autoit] [autoit]

    $hMixer = _BASS_Mixer_StreamCreate(44100, 2, BitOR($BASS_MIXER_END, $BASS_STREAM_DECODE))

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Mixer_StreamAddChannelEx($hMixer, $hStream1, BitOR($BASS_MIXER_FILTER, $BASS_STREAM_AUTOFREE), _
    _BASS_ChannelSeconds2Bytes($hMixer, 1), _BASS_ChannelSeconds2Bytes($hMixer, 4)) ;sample1.wav: start: 1s / duration: 4s

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Mixer_StreamAddChannelEx($hMixer, $hStream2, BitOR($BASS_MIXER_FILTER, $BASS_STREAM_AUTOFREE), _
    _BASS_ChannelSeconds2Bytes($hMixer, 3), _BASS_ChannelSeconds2Bytes($hMixer, 6)) ;sample2.wav: start: 3s (sample offset 5s) / duration: 6s

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Mixer_StreamAddChannelEx($hMixer, $hStream3, BitOR($BASS_MIXER_FILTER, $BASS_STREAM_AUTOFREE), _
    _BASS_ChannelSeconds2Bytes($hMixer, 6), _BASS_ChannelSeconds2Bytes($hMixer, 5)) ;sample3.wav: start: 6s / duration: 5s

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Encode_Start($hMixer, @ScriptDir & "\output.wav", $BASS_ENCODE_PCM)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $tBuffer = DllStructCreate("byte[" & $iBufferSize & "]")
    $pBuffer = DllStructGetPtr($tBuffer)

    [/autoit] [autoit][/autoit] [autoit]

    $iBytesEncode = _BASS_ChannelSeconds2Bytes($hMixer, 10); max length of output.wav

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $iBytesEncode Step $iBufferSize
    If $i + $iBufferSize <= $iBytesEncode Then
    _BASS_ChannelGetData($hMixer, $pBuffer, $iBufferSize)
    Else
    _BASS_ChannelGetData($hMixer, $pBuffer, $iBytesEncode - $i)
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_FREE()

    [/autoit]