Mp3-Recording via bass.dll

  • Hallo

    ich hab mir ein mp3-recording programm gebastelt und dazu die bass.dll & bassenc.dll von http://www.un4seen.com/ verwendet

    UDF BASS.AU3:

    Spoiler anzeigen
    [autoit]


    $BASS = DllOpen(@ScriptDir & "\bass.dll")
    $BASSENC = DllOpen(@ScriptDir & "\bassenc.dll")
    Dim $HRecord,$CHFX

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

    Func Mp3Active()
    Local $Ret[1]
    $Ret = DllCall($BASSENC, "dword", "BASS_Encode_IsActive", "hwnd", $HRecord[0])
    Return $Ret[0]
    EndFunc ;==>Mp3Active

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

    Func StopMp3()
    DllCall($BASSENC, "dword", "BASS_Encode_Stop", "hwnd", $HRecord[0])
    EndFunc ;==>StopMp3

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

    Func CloseBass()
    DllCall($BASS, "dword", "BASS_RecordFree")
    DllClose($BASS)
    DllClose($BASSENC)
    EndFunc ;==>CloseBass

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

    Func SetInput($Init, $Chnl, $Volume, $Active)
    DllCall($BASS, "dword", "BASS_RecordSetDevice", "dword", $Init - 1)
    if $Volume >=0 Then $Ret = DllCall($BASS, "dword", "BASS_RecordSetInput", "dword", $Chnl, "dword", BitOR($Volume, 0x40000))
    If $Active = 1 Then $Ret = DllCall($BASS, "dword", "BASS_RecordSetInput", "dword", $Chnl, "dword", BitOR(1, 0x20000))
    If $Active = 0 Then $Ret = DllCall($BASS, "dword", "BASS_RecordSetInput", "dword", $Chnl, "dword", BitOR(1, 0x10000))
    EndFunc ;==>SetInput

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

    Func MakeMp3($output)
    DllCall($BASSENC, "long", "BASS_Encode_Start", "hwnd", $HRecord[0], "str", "lame --alt-preset insane - " & $output, "dword", 0, "dword", 0, "dword", 0)
    ;DllCall($BASSENC, "long", "BASS_Encode_Start", "hwnd", $CHFX[0], "str", "output.wav", "dword", 0, "dword", 0, "dword", 0)
    DllCall($BASS,"long","BASS_ChannelPlay","hwnd",$hrecord[0],"dword",0)
    EndFunc ;==>MakeMp3

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

    Func RecStart($Init,$gain,$attack,$release,$threshold,$ratio,$predelay)
    DllCall($BASS, "dword", "BASS_RecordSetDevice", "dword", $Init - 1)
    $HRecord = DllCall($BASS, "hwnd", "BASS_RecordStart", "dword", 44100, "dword", 2, "dword", 128, "dword", 0, "dword", 0)
    $CHFX=DllCall($BASS, "dword", "BASS_ChannelSetFX", "hwnd", $HRecord[0], "dword", 1, "dword", 0)
    $Ret=DllCall($BASS, "dword", "BASS_ErrorGetCode")
    $str="float gain;float attack;float release;float threshold;float ratio;float predelay"
    $struct=DllStructCreate($str)
    DllStructSetData($struct,"gain",$gain)
    DllStructSetData($struct,"attack",$attack)
    DllStructSetData($struct,"release",$release)
    DllStructSetData($struct,"threshold",$threshold)
    DllStructSetData($struct,"ratio",$ratio)
    DllStructSetData($struct,"predelay",$predelay)
    $Ret=DllCall($BASS, "dword", "BASS_FXSetParameters", "hwnd", $CHFX[0], "ptr", DllStructGetPtr($struct))
    $Ret=DllCall($BASS, "dword", "BASS_ErrorGetCode")
    EndFunc ;==>RecStart

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

    Func GetPeak()
    Local $Ret[1]
    Dim $Return[2]
    $Ret = DllCall($BASS, "dword", "BASS_ChannelGetLevel", "hwnd", $HRecord[0])
    $Return[0] = LoWord($Ret[0]) * 100 / 32768
    If $Return[0] < 0 Then $Return[0] = $Return[0] * (-1)
    $Return[1] = HiWord($Ret[0]) * 100 / 32768
    If $Return[1] < 0 Then $Return[1] = $Return[1] * (-1)
    Return $Return
    EndFunc ;==>GetPeak

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

    Func GetInputs($Init)
    Local $Ret[1], $Count, $Name
    Dim $Return[1][2]
    DllCall($BASS, "dword", "BASS_RecordInit", "dword", $Init - 1)
    For $Count = 0 To 10
    $Ret = DllCall($BASS, "dword", "BASS_RecordGetInput", "dword", $Count)
    If $Ret[0] <= 0 Then ExitLoop
    $Name = DllCall($BASS, "str", "BASS_RecordGetInputName", "dword", $Count)
    ReDim $Return[$Count + 2][2]
    $Return[$Count + 1][0] = $Name[0]
    $Return[$Count + 1][1] = LoWord($Ret[0])
    Next
    $Return[0][0] = $Count
    Return $Return
    EndFunc ;==>GetInputs

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

    Func GetDevices()
    Local $Count, $Ret[1], $Loop
    Dim $Return[1]
    For $Count = 0 To 10
    $Ret = DllCall($BASS, "dword", "BASS_RecordGetDeviceDescription", "dword", $Count)
    If $Ret[0] <= 0 Then ExitLoop
    Next
    ReDim $Return[$Count + 1]
    For $Loop = 0 To $Count - 1
    $Ret = DllCall($BASS, "str", "BASS_RecordGetDeviceDescription", "dword", $Loop)
    $Return[$Loop + 1] = $Ret[0]
    Next
    $Return[0] = $Count
    Return $Return
    EndFunc ;==>GetDevices

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

    Func LoWord($dword)
    If BitAND($dword, 0x8000) = 0 Then
    Return BitAND($dword, 0xFFFF)
    Else
    Return BitOR($dword, 0xFFFF0000)
    EndIf
    EndFunc ;==>LoWord

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

    Func HiWord($dword)
    Return BitAND($dword, 0xFFFF0000) / 0x10000
    EndFunc ;==>HiWord

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

    Func MakeLong($LoWord, $HiWord)
    Return BitOR(BitAND($HiWord * 0x10000, 0xFFFF0000), BitAND($LoWord, 0xFFFF))
    EndFunc ;==>MakeLong

    [/autoit]

    GetDevices liefert ein Array:
    [0]=Anzahl der Audiointerfaces
    [1]=Name des 1 Audiointerface
    [2]=Name des 2 Audiointerface
    .
    .

    GetInputs(1) liefert ein Array des 1 Audiointerface:
    [0][0]=Anzahl der AudioInputs
    [1][0]=Name des 1 AudioInputs (z.b: Mikrofoneingang)
    [1][1]=Eingestellte Lautstärke
    .
    .

    RecStart startet den Input. Noch NICHT die Aufnahme, aber man kann schon die Peaks ablesen
    Außerdem lassen sich noch Einstellungen des Compressors vornemen

    GetPeak liefert ein Array:
    [0]=Ausschlag des linken Kanals
    [1]=Ausschlag des rechten Kanals

    SetInput setzt einen AudioInput auf Aktiv oder Inaktiv und stellt die Lautstärke ein

    MakeMp3 schließlich startet die eigentliche Aufnahme und codiert als MP3


    man benötigt die Dateien Bass.dll, BasEnc.dll und Lame.exe


    dieses UDF ist natürlich auf mein programm zugeschnitten und z.z. sind keine @Error-Codes eingebaut.

    aber vielleicht kann ja jemand etwas damit anfangen...

    und vielleicht hat ja mal jemand Lust ein ordentliches UDF für Bass.dll zu coden ;)

  • kann mir jemand helfen mit der bass.dll ein audio spectrum darzustellen

    ich kann zwar linken und rechten kanal auslesen habe aber keine ahnung wie ich ein spectrum darstelle.

    es sollte diese funktion der bass.dll sein BASS_ChannelGetInfo

    Danke

  • um die bass.dll mit autoit nutzen zu können, benötigt man eine callback-routine!
    diese stürtz mit autoit immer nach kurzer zeit ab!
    (mein post von oben funktioniert ohne callback auch nur, wenn man alle 15ms eine peak-abfrage macht ;))

    deshalb hab ich mir eine dll in freepascal geschrieben, welche diese callback übernimmt...

    ich würd jetzt mal sagen: eine spectrumanalyse mit bass.dll direkt von autoit aus ist nicht ohne umweg möglich!

    falls du in c++ fit bist - bei der bass.dll ist ein c++ beispiel für spectrum-analyse dabei...


    lgE

  • ich hatte ja probleme mit der callback-funktion: [ offen ] DllCallBack stürzt ab, außer ich verschiebe das GUI
    deshalb hab ich diese in eine dll "ausgelagert"
    diese basscb.dll ist in devpascal (freepascal) geschrieben.
    http://www.bloodshed.net/devpascal.html

    ich habe momentan nur die funktionen eingebaut, die ich bei meinen derzeitigen projekten benötige, allerdings halten die bass-dll´s noch unzählige weitere funktionen bereit...
    http://un4seen.com

    pascalkundige und interessierte personen sind natürlich aufgerufen das projekt wachsen zu lassen ;)

    lgE

  • Hast du denn eine Seite mit den detaillierten Funktionen und Beschreibungen der Bass.dll? Bräuchte das eigentlich nur von der Record- und Stop-Funktion.

    edit:
    Okay, die Befehle sind ja in deinem Beispielskript. Allerdings wird bei mir am Ende des Aufnehmens nichts gespeichert? Kann man eigentlich das aufnehmen, was aus den Boxen kommt?

  • eine mp3/wav dateiwird nur erstellt, wenn ein richtiger input der soundkarte gewählt wurde.
    wenn bei meinem beispiel Reclength -1 ist und beim drücken auf start EncoderActive 0 bleibt, dann kann von dem ausgewählten input nicht aufgenommen werden.

    //Edit 2: Die Zeile "_RecStart(1,1,44100)" muß vor GuiCreate verschoben werden, also von zeile 53 auf zeile 13.


    die bass.dll scheint mit manchen soundkarten probleme zu machen - so hab ich letztens bemerkt, daß ich den audioinput meiner pinnacle dazzle dvc100 nicht ansprechen konnte!
    mittlerweile gibt es schon eine neuere version der bass.dll, die hab ich aber noch nicht ausprobiert.

    auf http://www.autoit.de/www.un4seen.com kannst du die aktuellen versionen downloaden, incl. c/delphi/vb beispielscripts und helpfiles.
    dort gibt es auch ein forum.

    du kannst auch aufnehmen, was aus den boxen rauskommt. ich muß dazu bei meinem laptop z.b. den input "Stereomix" auswählen.

    im anhang hab ich noch die helpfiles angefügt.

    lgE


    //Edit: bei meinem beispielscript ist mir ein fehler unterlaufen; bei mehreren installierten soundkarten wurde die inputliste nicht korrekt aktualisiert, wenn man eine andere karte ausgewählt hat. Geänderte Funktion:

    Spoiler anzeigen
    [autoit]

    Func _SelectDevice()
    If _GUICtrlComboBox_GetCurSel($SelDev)+1<>$Device Then
    $Device=_GUICtrlComboBox_GetCurSel($SelDev)+1
    $String = ''
    For $i = 1 To _GetInputs($Device)
    $String = $String & "|" & _getinputname($i)
    Next
    GUICtrlSetData($SelInp, $String, _getinputname(1))
    GUICtrlSetData($Slider,_GetInputLevel(1))
    $Input=1
    _StopRec()
    If GUICtrlRead($AGC)=1 Then
    _EnableAGC(1)
    Else
    _EnableAGC(0)
    EndIf
    _RecStart($Device,$Input,44100)
    _SetAGC(20,0.96)
    EndIf
    EndFunc

    [/autoit]
  • Also bei meiner Soundkarte (Creative X-Fi Xtreme Music) wird nur der Mikrofoneingang erkannt. Dann muss ich mich wohl nach ner stabileren DLL zum Recorden umschauen ;)

  • es gäbe da noch die "xaudio.dll" ;) (hab ich aber noch nicht ausprobiert)
    hast du schon meinen "Edit 2" aus dem letzten post ausprobiert?

    ich muß zugeben, ich habe die dll extra für dieses forum angepasst; vielleicht haben sich da einige bugs eingeschlichen ;)

    zumindest läuft MEIN aufnahmeprogramm auf mehreren rechnern (ca. 15) seit geraumer zeit einwandfrei!

    lgE

  • Nun hat sich BrettF ausm englischen Forum drangemacht eine UDF für die Bass.dll zu schreiben:
    http://www.autoitscript.com/forum/index.php?showtopic=83481

    daraus werden in weiterer Zukunft noch großartige Dinge entstehen!
    (wenn man eine Ahnung davon hat, was mit Bass alles möglich ist ;))

    Ich hab das (wieder) mal für ein kleines MP3-Recording Script verwendet...

    lgE