
dabudabu
Members-
Posts
2 -
Joined
-
Last visited
Everything posted by dabudabu
-
BASS Function Library (Sound and Music Functions)
dabudabu replied to BrettF's topic in AutoIt Example Scripts
Dear Eukalyptus, you cannot imagine how your help has been important to me. Without your support I would be still lost, due to the exact measurement of the asio input level is crucial to my research. Having had the opportunity to take a look at your example scripts made me able to definitively work out the solution I so desperately needed and, at last, got. To be honest, it is still not perfectly clear to me the exact way in which your _Bass_Asio_ChannelGetLevel gets the result, but anyway it works, doing it damn well! So, hoping this will be useful to any of you, I built up a GUI around your _Bass_Asio_ChannelGetLevel and added a bit of logic to manage the asio input device, the recorded file and the input channel levels, even if the core, which makes the piece of sw useful, is completely yours and I only made some minor changes to it, just to make the script more readable. When compiled, this script exactly realizes what it is aimed to, a small, stand alone application to exactly show the asio device input levels. I also added the visualization of the current maximum input level, which is hold for roughly one second. It could be needed to change the directories in the #include statements to point to the position of the _BASS include files and, of course, the dlls must be in the script folder in order to make it works. One more time, thank you. Should one day my research be complete, please let me quote your help (together with Ian, the author of the terrific bass dlls set), and in case I will ask you your permission to do so, asking you some further details other than a nick name on this forum to make people know more about you. ;;#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 ;#include-once ;#include "Bass.au3" #include "D:\Measure\au3\BASS_New By Eucaliptus\BASS\Bass.au3" ;#include "BassAsio.au3" #include "D:\Measure\au3\BASS_New By Eucaliptus\BASS_ASIO\BassAsio.au3" ;#include "BassExt.au3" #include "D:\Measure\au3\BASS_New By Eucaliptus\BASS_EXT\BassExt.au3" ;#include "BassEnc.au3" #include "D:\Measure\au3\BASS_New By Eucaliptus\BASS_ENC\BassEnc.au3" #include <ButtonConstants.au3> #include <ComboConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <ProgressConstants.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #Region ### START Koda GUI section ### Form=d:\measure\au3\asio sin meter\formasiosinmeter.kxf $frmAsioInputMeter = GUICreate("16 BIT 44.100 Hz ASIO DEVICE INPUT METER", 557, 185, 193, 114) $cmbDevice = GUICtrlCreateCombo("", 72, 8, 337, 25) $txtChannel1Level = GUICtrlCreateInput("", 8, 104, 249, 45, BitOR($ES_CENTER,$ES_AUTOHSCROLL,$ES_READONLY)) GUICtrlSetFont(-1, 24, 800, 0, "MS Sans Serif") GUICtrlSetColor(-1, 0x800080) $txtChannel2Level = GUICtrlCreateInput("", 296, 104, 249, 45, BitOR($ES_CENTER,$ES_AUTOHSCROLL,$ES_READONLY)) GUICtrlSetFont(-1, 24, 800, 0, "MS Sans Serif") GUICtrlSetColor(-1, 0x800080) $ProgressChannel1 = GUICtrlCreateProgress(8, 158, 249, 17) $ProgressChannel2 = GUICtrlCreateProgress(296, 158, 249, 17) $cmdStop = GUICtrlCreateButton("Stop", 484, 6, 60, 25, $WS_GROUP) $cmdStart = GUICtrlCreateButton("Start", 416, 6, 60, 25, $WS_GROUP) $txtRecordFile = GUICtrlCreateInput("", 71, 38, 425, 21) $lblAsioDevice = GUICtrlCreateLabel("Asio device", 9, 12, 59, 17) $cmdBrowseRecFile = GUICtrlCreateButton("...", 503, 36, 41, 25, $WS_GROUP) GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif") $lblRecordInto = GUICtrlCreateLabel("Record into", 7, 40, 59, 17) $lblChannel1 = GUICtrlCreateLabel("Value - Max Ch 1", 7, 82, 119, 20) GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif") GUICtrlSetColor(-1, 0x800080) $lblChannel2 = GUICtrlCreateLabel("Value - Max Ch 2", 431, 82, 119, 20) GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif") GUICtrlSetColor(-1, 0x800080) $txtSamplingRate = GUICtrlCreateInput("", 192, 64, 65, 21, BitOR($ES_CENTER,$ES_AUTOHSCROLL,$ES_READONLY)) $lblSamplingRate = GUICtrlCreateLabel("Sample Rate", 127, 68, 65, 17) $lblBitDepth = GUICtrlCreateLabel("Bit depth", 367, 68, 46, 17) $txtBitDepth = GUICtrlCreateInput("", 296, 64, 65, 21, BitOR($ES_CENTER,$ES_AUTOHSCROLL,$ES_READONLY)) $ProgressCPU = GUICtrlCreateProgress(268, 104, 17, 45, $PBS_VERTICAL) $lblCPU = GUICtrlCreateLabel("CPU", 265, 86, 26, 17) $txtCPULevel = GUICtrlCreateInput("", 262, 158, 29, 17, BitOR($ES_CENTER,$ES_AUTOHSCROLL,$ES_READONLY)) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### OnAutoItExitRegister("_FreeBass") HotKeySet("{ESC}", "_Exit") Global $hEncoder, $ReadSampleRate, $InputSampleRate, $hAsioBuffer, $aPipe[6], $aInfo Global $NoFlags, $AppName, $OneChannel, $NoFlags, $Channel1, $Channel2, $IsAnInputChannel Global $BitDepth, $BitDepthFullScale, $MilliSecMaxValueRetemption, $TwoChannels, $MilliSecForCycle Global $MaxChannel1, $MaxChannel2, $MilliSecElapsed $AppName = "ASIO Input Meter" $NoFlags = 0 $Channel1 = 0 $Channel2 = 1 $IsAnInputChannel = True $BitDepth = 16 $BitDepthFullScale = 32767 $TwoChannels = 2 $MilliSecForCycle = 50 $MilliSecMaxValueRetemption = 1000 StartApp() $Start = False $MilliSecElapsed = 0 While 1 $CanStart = GUICtrlRead( $txtRecordFile ) <> "" and GUICtrlRead( $cmbDevice ) <> "" and $Start = False if $CanStart Then GUICtrlSetState($cmdStop, $GUI_DISABLE) GUICtrlSetState($cmdStart, $GUI_ENABLE) Else GUICtrlSetState($cmdStop, $GUI_ENABLE) GUICtrlSetState($cmdStart, $GUI_DISABLE) endif $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $cmdBrowseRecFile if $Start = False Then $RecordFile = FileSaveDialog("Choose WAV record file", @ScriptDir, "Wav file (*.wav)", 16) if $RecordFile = "" Then $RecordFile = @ScriptDir & "\" & "asioinputmeter.wav" endif GUICtrlSetData($txtRecordFile, $RecordFile) EndIf Case $cmdStop $Start = False _FreeBass() Case $cmdStart $sDevice = GUICtrlRead($cmbDevice) $Device = int(StringRight($sDevice, 1)) $Start = True MeterStart($Device, $RecordFile, 44100) EndSwitch Sleep($MilliSecForCycle) $MilliSecElapsed += $MilliSecForCycle if $Start then $Ch1Level = round( _BASS_ASIO_ChannelGetLevel(True, $Channel1) * $BitDepthFullScale, 0) $Ch2Level = round( _BASS_ASIO_ChannelGetLevel(True, $Channel2) * $BitDepthFullScale, 0) if $Ch1Level > $MaxChannel1 Then $MaxChannel1 = $Ch1Level $MilliSecElapsed = 0 EndIf if $Ch2Level > $MaxChannel2 Then $MaxChannel2 = $Ch2Level $MilliSecElapsed = 0 EndIf if $MilliSecElapsed > $MilliSecMaxValueRetemption Then $MilliSecElapsed = 0 $MaxChannel1 = $Ch1Level $MaxChannel2 = $Ch2Level EndIf GUICtrlSetData($txtChannel1Level, $Ch1Level & "-" & $MaxChannel1 ) GUICtrlSetData($txtChannel2Level, $Ch2Level & "-" & $MaxChannel2 ) GUICtrlSetData($ProgressChannel1, $Ch1Level * 100 / $BitDepthFullScale ) GUICtrlSetData($ProgressChannel2, $Ch2Level * 100 / $BitDepthFullScale ) GUICtrlSetData($txtSamplingRate, _BASS_ASIO_ChannelGetRate(True, $Channel1) ) $CPU = Round( _BASS_ASIO_GetCPU()*100, 1) GUICtrlSetData($ProgressCPU, $CPU ) GUICtrlSetData($txtCPULevel, $CPU ) GUICtrlSetData($txtBitDepth, $BitDepth & "/" & $BitDepthFullScale ) else GUICtrlSetData($txtChannel1Level, "" ) GUICtrlSetData($txtChannel2Level, "" ) GUICtrlSetData($ProgressCPU, 0 ) GUICtrlSetData($txtCPULevel, "" ) GUICtrlSetData($ProgressChannel1, 0 ) GUICtrlSetData($ProgressChannel2, 0 ) EndIf Wend Func _Exit() Exit EndFunc ;==>_Exit Func _FreeBass() Assert(0, "Stopping Asio Input Meter:" & @CRLF ) Assert( _BASS_Encode_Stop($hEncoder), " _BASS_Encode_Stop" ) Assert( _BASS_ASIO_Stop(), " _BASS_ASIO_Stop()" ) Assert( _BASS_ASIO_Free(), " _BASS_ASIO_Free()" ) Assert( _BASS_Free(), " _BASS_Free()" ) EndFunc ;==>_FreeBass Func ___DeBug($iError, $sAction) Switch $iError Case -1 ConsoleWrite(@CRLF & "-" & $sAction & @CRLF) Case -2 ConsoleWrite(@CRLF & ">" & $sAction & @CRLF) Case 0 ;;ConsoleWrite(@CRLF & "+" & $sAction & " - OK" & @CRLF) ConsoleWrite("OK " & $sAction & @CRLF) Case Else ConsoleWrite(@CRLF & "!" & $sAction & " - FAILED, @error: " & $iError & @CRLF) Exit EndSwitch EndFunc ;==>___DeBug Func Assert($retVal, $sAction) If @error Then MsgBox(0, $AppName, $sAction & " ERROR: " & @error, $sAction) Exit Else Consolewrite("OK " & $sAction & @CRLF) EndIf EndFunc Func StartApp() Assert(0, "Initializing App loading BASS dll" & @CRLF ) ;;*********************STARTUP BASS ********************************* Assert (_BASS_Startup(), " _BASS_Startup(): load bass.dll") ;; ___Debug(@error, "load bass.dll") Assert( _BASS_ASIO_Startup(), " _BASS_ASIO_Startup(): load bassasio.dll") ;; ___Debug(@error, "load bassasio.dll") Assert( _BASS_ENCODE_Startup(), " _BASS_ENCODE_Startup(): load bassenc.dll") ;; ___Debug(@error, "load bassenc.dll") Assert( _BASS_EXT_STARTUP(), " _BASS_EXT_STARTUP(): load bassext.dll") ;; ___Debug(@error, "load bassext.dll") ;;*********************STARTUP BASS ********************************* ;;Fill the device combo box $iDevice = 0 $lstDevice = "" While 1 $aDeviceInfoInfo = _BASS_ASIO_GetDeviceInfo($iDevice) If @error Then ExitLoop Else $lstDevice = $lstDevice & $aDeviceInfoInfo[1] & " - Device " & $iDevice & "|" $iDevice += 1 EndIf Wend GUICtrlSetData($cmbDevice, $lstDevice) EndFunc Func MeterStart($Device, $RecordFile, $InputSampleRate) Assert(0, "Starting Asio Input Meter:" & @CRLF ) Assert( _BASS_ASIO_Init($Device), " _BASS_ASIO_Init device: initialize asio device number " & $Device ) ;;___Debug(@error, "initialize asio") Assert( _Bass_ASIO_SetRate($InputSampleRate), " _Bass_ASIO_SetRate: set Asio sample rate at " & $InputSampleRate & " Hz") ;;___Debug(@error, "set asio samplerate: " & $InputSampleRate) $ReadSampleRate = _BASS_ASIO_GetRate() ___Debug(@error, " _BASS_ASIO_GetRate: get asio samplerate: " & $ReadSampleRate & " Hz") Assert( _BASS_Init($NoFlags, -1, $ReadSampleRate), " _BASS_Init: initialize bass (same samplerate as asio)" ) ;;___Debug(@error, "initialize bass (same samplerate as asio)") $hAsioBuffer = _BASS_StreamCreate($ReadSampleRate, $TwoChannels, $NoFlags, $STREAMPROC_PUSH, 0) ___Debug(@error, " _BASS_StreamCreate: create push stream to act as buffer for asio in") Assert( _BASS_ChannelSetAttribute($hAsioBuffer, $BASS_ATTRIB_VOL, 0), " _BASS_ChannelSetAttribute: mute channel" ) ;;___Debug(@error, "mute channel") Assert( _BASS_ChannelPlay($hAsioBuffer, False), " _BASS_ChannelPlay: start channel - data is sent to encoder when buffer is filled") ;; ___Debug(@error, "start channel - data is sent to encoder when buffer is filled") $hEncoder = _BASS_Encode_Start($hAsioBuffer, $RecordFile, BitOR($BASS_ENCODE_PCM, $BASS_ENCODE_FP_16BIT)) ___Debug(@error, " _BASS_Encode_Start: set encoder on the stream") $aInfo = _BASS_ASIO_GetInfo() ___Debug(@error, " _BASS_ASIO_GetInfo: get asio infos") $aPipe = _BASS_EXT_StreamPipeCreate($hAsioBuffer, $BASS_EXT_STREAMPROC_PUSH) ___Debug(@error, " _BASS_EXT_StreamPipeCreate: using created push stream as buffer for asio in") Assert( _BASS_ASIO_ChannelEnable($IsAnInputChannel, $Channel1, $BASS_EXT_AsioProc, $aPipe[0]), " _BASS_ASIO_ChannelEnable: enable asio input channel 1" ) ;; ___Debug(@error, "enable asio input channel 1") Assert( _BASS_ASIO_ChannelSetFormat($IsAnInputChannel, $Channel1, $BASS_ASIO_FORMAT_16BIT), " _BASS_ASIO_ChannelSetFormat: set asio input channel 1 sampleformat to 16 bit" ) ;; ___Debug(@error, "set asio input channel 1 sampleformat to 16bit") Assert( _BASS_ASIO_ChannelSetRate($IsAnInputChannel, $Channel1, $ReadSampleRate), " _BASS_ASIO_ChannelSetRate: set asio input channel 1 samplerate to " & $ReadSampleRate ) ;; ___Debug(@error, "set asio input channel 1 samplerate to " & $ReadSampleRate) Assert( _BASS_ASIO_ChannelJoin($IsAnInputChannel, $Channel2, $Channel1), " _BASS_ASIO_ChannelJoin: join asio input channel 2 and 1" ) ;; ___Debug(@error, "join asio input channel 2 and 1") Assert( _BASS_ASIO_Start($aInfo[5]), " _BASS_ASIO_Start: start asio processing" ) ;; ___Debug(@error, "start asio processing") ___Debug(-2, "Recording to " & $RecordFile) ___Debug(-1, "press ESC to quit") GUICtrlSetData($txtSamplingRate, $ReadSampleRate) EndFunc -
BASS Function Library (Sound and Music Functions)
dabudabu replied to BrettF's topic in AutoIt Example Scripts
Hi to all of you. This is my first post, so I hope you will be mercifully with me. The matter is I badly need to know the input level of some ASIO device input channels (namely a digidesign MBOX2 and a EMU 0404 externalUSB, but I think this is not so important). As the examples for collecting input samples and reading the peak level from BASS ASIO devices I would able to come across to were less than a few, the development of a little piece of AutoIt software which could handle this topic is driving me mad :-( At the moment I only tried using "purely" BASS_ASIO calls, but this really doesn't matter to me, what I only need is to read the peak level of an ASIO input channel from an ASIO device or, as an alternative, get the samples in an array and calculate it, so in any way it could be done it will be great! The snippet I wrote tries to read this info by using a callback invoked by BASS_ASIO_ChannelEnable, but, as you can guess, it doesn't work, crashing as soon as the code reaches the end of the callback function. To make things a bit more parametric, I developed a tiny GUI, which lets you insert both the device and the input channel numbers. Using it, I first of all set up device and input channel, then I press the "INIT" button to initializate BASS_ASIO (which seems to me runs smoothly), and, at last, I supposed the reading of the input channel would be done by pressing the "START" button, which actually makes the program crashes. I inserted some debug consolewrite to trace what is going on inside the code, and it seems the sleep function inside the callback "helps" the program to crash, as well as the attempt to write the read peak level onto the GUI, as they conflict with the ASIO core. Furthermore it is not clear to me I would have to organize the code to read the input level continuously, suppose for 10 minutes, like looking at an input V-Meter, which is what this software is aimed to. Is the callback called continuously? Have I to put an infinite loop in the callback itself? Unfortunately this also is not clear to me. Finally I have to say I'm using "BASSASIO for ALL" to test my script (so I've never tested it with the two audio cards I own) reading its device and channel numbers by using the "list.exe" little program which comes together with the BASS and BASS_ASIO packages and putting these values in the GUI. To be honest, I'm much more interested in targeting my goal: to get the input peak value (or getting it by the samples array coming from an ASIO device input channel), rather than investigating in where I'm wrong, even if it could be interesting. Indeed, this development is just a little piece of an huge audio research I've been doing from the last 4 years, and at this stage I only, even if badly, need a very precise numeric V-Meter to exactly read the audio input level (in case using the samples array to calculate it), so all of this is no more than an unavoidable stuff to get it. Forgive me for this so long and perhaps boring description, for sure any help would be really appreciated as at the moment I'm lost in the middle of nowhere and this is delaying my research, which absolutely needs this instrument to go on. Thank you so much to all of you for your help and support, Daniele, Rome, Italy Here follows my AutoIt script: #include <BASS.au3> #include <BASSConstants.au3> #include <BASSAsio.au3> #include <BASSAsioConstants.au3> #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #Region ### START Koda GUI section ### Form=d:\measure\au3\asio sin meter\asiosinmeterform.kxf $frmAsioInputMeter = GUICreate("Asio Input Meter", 302, 192, 192, 114) $cmdAsioStart = GUICtrlCreateButton("START", 184, 48, 49, 41, $WS_GROUP) $cmdAsioStop = GUICtrlCreateButton("STOP", 241, 48, 49, 41, $WS_GROUP) $txtChannelLevel = GUICtrlCreateInput("", 8, 96, 281, 81, BitOR($ES_CENTER,$ES_AUTOHSCROLL,$ES_READONLY)) GUICtrlSetFont(-1, 48, 800, 0, "Times New Roman") GUICtrlSetColor(-1, 0x0A246A) $txtDevice = GUICtrlCreateInput("", 8, 64, 49, 21, BitOR($ES_CENTER,$ES_AUTOHSCROLL)) $txtChannel = GUICtrlCreateInput("", 64, 64, 49, 21, BitOR($ES_CENTER,$ES_AUTOHSCROLL)) $lblDevice = GUICtrlCreateLabel("Device", 11, 47, 38, 17) $lblChannel = GUICtrlCreateLabel("Channel", 65, 47, 43, 17) $lblTitle = GUICtrlCreateLabel("Asio Input Meter", 9, 2, 291, 41) GUICtrlSetFont(-1, 24, 400, 0, "MS Sans Serif") $cmdAsioInit = GUICtrlCreateButton("INIT", 127, 48, 49, 41, $WS_GROUP) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### $IsInput = 1 $UsesCurrentBufferLen = 0 global $cbSamplesBuffer = DllStructCreate("int Buffer[2048]") global $cbSamplesBufferPTR = DllStructGetPtr($cbSamplesBuffer ) global $cblen = DllStructCreate("DWORD len") global $cbChannel = DllStructCreate("DWORD cbChannel") global $cbIsInput = DllStructCreate("DWORD cbIsInput") global $cbDummyData = 0 global $cbDummyDataPTR = DllStructGetPtr($cbDummyData) _BASS_STARTUP() _BASS_ASIO_STARTUP() While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit case $cmdAsioInit Assert(_BASS_ASIO_Stop(), "_BASS_ASIO_Stop") Assert(_BASS_ASIO_Free(), "_BASS_ASIO_Free") $Device = GUICtrlRead($txtDevice) $Channel = GUICtrlRead($txtChannel) Assert(_BASS_ASIO_STARTUP(), "_BASS_ASIO_STARTUP") Assert(_BASS_ASIO_Init($Device), "_BASS_ASIO_Init") Assert(_BASS_ASIO_SetRate(44100.0), "_BASS_ASIO_SetRate") Assert(_BASS_ASIO_ChannelSetFormat($IsInput, 0, $BASS_ASIO_FORMAT_16BIT), "_BASS_ASIO_ChannelSetFormat") Assert(_BASS_ASIO_ChannelSetRate($IsInput, $Channel, 44100.0), "_BASS_ASIO_ChannelSetRate") Assert(_BASS_ASIO_ChannelEnable($IsInput, $Channel, "cbAsioShowInputLevel", $cbDummyData), "_BASS_ASIO_ChannelEnable") $cbIsInput = $IsInput $cbChannel = $Channel case $cmdAsioStart Assert(_BASS_ASIO_Start($UsesCurrentBufferLen), "_BASS_ASIO_Start") ConsoleWrite("now out from callback" & @CRLF) case $cmdAsioStop Assert(_BASS_ASIO_Stop(), "_BASS_ASIO_Stop") Assert(_BASS_ASIO_Free(), "_BASS_ASIO_Free") EndSwitch WEnd Func cbAsioShowInputLevel($cbIsInput, $cbChannel, $cbSamplesBufferPTR, $cblen, $cbDummyDataPTR) $n = 1 ;while 1 ConsoleWrite($n & ".1 cbSamplesBuffer = " & DllStructGetData ($cbSamplesBuffer, 1) & @CRLF) $V = _BASS_ASIO_ChannelGetLevel($cbIsInput, $cbChannel) ;GUICtrlSetData($txtChannelLevel, $V) ConsoleWrite($n & ".2 wrote " & $V & " on GUI" & @CRLF) ;;Sleep(50) ConsoleWrite($n & ".3 callback sleept a bit" & @CRLF) $n = $n +1 ;wend EndFunc Func Assert($retVal, $CalledFunction) If @error Then MsgBox(0, $CalledFunction & " ERROR: " & @error, $CalledFunction) Exit Else ConsoleWrite("OK " & $CalledFunction & @CRLF) EndIf EndFunc