Jump to content

BASS Function Library (Sound and Music Functions)


BrettF
 Share

Recommended Posts

Hi

I got it working!

I wrote a little dll in freepascal:

library BassCB;

Uses Bass;
Var RecHandle: DWORD;

function RecordingCallback(handle: DWORD; buffer: Pointer; length: DWORD; user: Pointer): BOOL; stdcall;
begin
     result := True;
end;

function RecordStart(Freq, Chan, Flag: DWord): DWord; export;
begin
     RecHandle := BASS_RecordStart(Freq, Chan, Flag, @RecordingCallback, 0);
     Result := RecHandle;
end;

exports
     RecordStart;

begin
end.
encoded to basscb.dll

That´s it! The returned RecHandle can now be used in Autoit and Bass.au3/Bassenc.au3 :mellow:

I am using this basscb.dll to have a realy stable callback, so the recordings do not have any dropouts :(

see the included example...

bassenc_stable_callback.rar

eukalyptus

Edited by eukalyptus
Link to comment
Share on other sites

Hi

I got it working!

I wrote a little dll in freepascal:

library BassCB;

Uses Bass;
Var RecHandle: DWORD;

function RecordingCallback(handle: DWORD; buffer: Pointer; length: DWORD; user: Pointer): BOOL; stdcall;
begin
     result := True;
end;

function RecordStart(Freq, Chan, Flag: DWord): DWord; export;
begin
     RecHandle := BASS_RecordStart(Freq, Chan, Flag, @RecordingCallback, 0);
     Result := RecHandle;
end;

exports
     RecordStart;

begin
end.
encoded to basscb.dll

That´s it! The returned RecHandle can now be used in Autoit and Bass.au3/Bassenc.au3 :mellow:

I am using this basscb.dll to have a realy stable callback, so the recordings do not have any dropouts :(

see the included example...

bassenc_stable_callback.rar

eukalyptus

Very nice job!
Link to comment
Share on other sites

Here is a little example to set audioeffects on music (using bass_fx.dll)

bass_fx.rar

@BrettF:

This is a workaround, to use the effect-handles.

please replace _BASS_ChannelSetFX and _BASS_ChannelRemoveFX in your bass.au3 with this:

Func _BASS_ChannelSetFX($bass_dll, $handle, $type, $priority)
    $BASS_ret_ = DllCall($bass_dll, "dword", "BASS_ChannelSetFX", "DWORD", $handle, "DWORD", Eval($type & "_Value"), "int", $priority)
    $error = _BASS_ErrorGetCode($bass_dll)
    If $error <> 0 Then
        Return SetError($error, "", 0)
    Else
        Assign("BASS_FX_" & $BASS_ret_[0], Eval(StringReplace($type, "_FX", "")), 2)
        Return SetError(0, "", $BASS_ret_[0])
    EndIf
EndFunc  ;==>_BASS_ChannelSetFX

Func _BASS_ChannelRemoveFX($bass_dll, $handle, $fx)
    $BASS_ret_ = DllCall($bass_dll, "int", "BASS_ChannelRemoveFX", "DWORD", $handle, "DWORD", $fx)
    $error = _BASS_ErrorGetCode($bass_dll)
    If $error <> 0 Then
        Return SetError($error, "", 0)
    Else
        Return SetError(0, "", $BASS_ret_[0])
    EndIf
EndFunc  ;==>_BASS_ChannelRemoveFX

and add these functions to bass.au3

; #FUNCTION# ====================================================================================================

================
; Name...........: _BASS_FXSetParameters
; Description ...: Sets the parameters of an effect.
; Syntax.........: _BASS_FXSetParameters($bass_dll, $fxhandle, $parameters)
; Parameters ....:  -   $bass_dll   -   Handle to opened Bass.dll
;                   -   $fxhandle   -   Handle to the effect as returned by _BASS_ChannelSetFX
;                  -   $parameters  -   The parameters as string delimited by "|" ("1|2|3|...")
; Return values .: Success    - Returns 1
;                 Failure     - Returns 0 and sets @ERROR to error returned by _BASS_ErrorGetCode()
; Author ........: Eukalyptus
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......;
; ====================================================================================================

===========================
Func _BASS_FXSetParameters($bass_dll, $fxhandle, $parameters)
    Local $param = StringSplit($parameters, "|")
    $struct = DllStructCreate(Eval("BASS_FX_" & $fxhandle))
    For $i = 1 To $param[0]
        DllStructSetData($struct, $i, $param[$i])
    Next
    $BASS_ret_ = DllCall($bass_dll, "int", "BASS_FXSetParameters", "dword", $fxhandle, "ptr", DllStructGetPtr($struct))
    $error = _BASS_ErrorGetCode($bass_dll)
    If $error <> 0 Then
        Return SetError($error, "", 0)
    Else
        Return SetError(0, "", $BASS_ret_[0])
    EndIf
EndFunc  ;==>_BASS_FXSetParameters

; #FUNCTION# ====================================================================================================

================
; Name...........: _BASS_FXGetParameters
; Description ...: Retrieves the parameters of an effect.
; Syntax.........: _BASS_FXGetParameters($bass_dll, $fxhandle)
; Parameters ....:  -   $bass_dll   -   Handle to opened Bass.dll
;                   -   $fxhandle   -   Handle to the effect as returned by _BASS_ChannelSetFX
; Return values .: Success    - Returns Array of effect parameters.
;                                   - [0] = Number of parameters returned
;                                   - [1] = first parameter
;                                   - [2] = second parameter
;                                   - [n] = n parameter
;                 Failure     - Returns 0 and sets @ERROR to error returned by _BASS_ErrorGetCode()
; Author ........: Eukalyptus
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......;
; ====================================================================================================

===========================
Func _BASS_FXGetParameters($bass_dll, $fxhandle)
    Local $sRet = DllStructCreate(Eval("BASS_FX_" & $fxhandle))
    $BASS_ret_ = DllCall($bass_dll, "none", "BASS_FXGetParameters", "dword", $fxhandle, "ptr", DllStructGetPtr($sRet))
    $error = _BASS_ErrorGetCode($bass_dll)
    If $error <> 0 Then
        Return SetError($error, "", 0)
    Else
        Local $aRet[1], $types = StringSplit(Eval("BASS_FX_" & $fxhandle), ";")
        For $i = 1 To $types[0]
            ReDim $aRet[$i + 1]
            $rest = DllStructCreate($types[$i], DllStructGetData($sRet, $i))
            $aRet[$i] = DllStructGetData($sRet, $i)
            $sRet[0] = $i
        Next
        Return SetError(0, "", $aRet)
    EndIf
EndFunc  ;==>_BASS_FXGetParameters

This workaround requires some changes to BassConstants.au3 as well - you find the modified version in bass_fx.rar

regards

eukalyptus

Link to comment
Share on other sites

Hi there BrettF and eukalyptus,

It's nice to see this kind of action going around the BASS DLLs!

Could you please tell me what's the current status of Bass.au3?

Does it include the recent implementations and suggestions from eukalyptus?

Maybe it would be nice to create a version history :(

I'm going to try something out:

- 4 output channels to 4 different speakers

- background music in all channels at all times

- stream a certain file in one channel at a time - over the background sound.

I'll be around :mellow:

Thank you for all this work!

Link to comment
Share on other sites

I haven't had time to update BASS.au3 to be correct with eukalyptus' latest work, which might I add is awesome. :mellow:

There is a change log at the bottom of the first post. Well there was last time I checked... :( EDIT: Although it is limited. I will update BASS.au3 and add a "proper" change log.

Post how you go with the multi channel streaming, and I will add it to one of the example posts. I don't currently have the facilities to test this... A laptop with just stereo sound sucks...

Cheers and best of luck,

Brett

Edited by BrettF
Link to comment
Share on other sites

Version 4

-> Removed _BASS_ChannelSetFX()
-> Removed _BASS_ChannelRemoveFX()
+> Added _BASS_FXSetParameters()
+> Added _BASS_FXGetParameters()
lol

Not remove _BASS_ChannelSetFX and _BASS_ChannelRemoveFX

but replace with the new ones:

Func _BASS_ChannelSetFX($bass_dll, $handle, $type, $priority)
    $BASS_ret_ = DllCall($bass_dll, "dword", "BASS_ChannelSetFX", "DWORD", $handle, "DWORD", Eval($type & "_Value"), "int", $priority)
    $error = _BASS_ErrorGetCode($bass_dll)
    If $error <> 0 Then
        Return SetError($error, "", 0)
    Else
        Assign("BASS_FX_" & $BASS_ret_[0], Eval(StringReplace($type, "_FX", "")), 2)
        Return SetError(0, "", $BASS_ret_[0])
    EndIf
EndFunc ;==>_BASS_ChannelSetFX

Func _BASS_ChannelRemoveFX($bass_dll, $handle, $fx)
    $BASS_ret_ = DllCall($bass_dll, "int", "BASS_ChannelRemoveFX", "DWORD", $handle, "DWORD", $fx)
    $error = _BASS_ErrorGetCode($bass_dll)
    If $error <> 0 Then
        Return SetError($error, "", 0)
    Else
        Return SetError(0, "", $BASS_ret_[0])
    EndIf
EndFunc ;==>_BASS_ChannelRemoveFX
Link to comment
Share on other sites

Oh crap. It was a very long day... (Wednesday was like 5am-11:30pm, freaking long allright...) and I still hadn't caught up on sleep :(

Will update :mellow:

Updated

Edited by BrettF
Link to comment
Share on other sites

Thank you so much!

This is really good work :)

Now to the details: on my first series of trials with my 7.1 surround soundcard, I've found the "problem" described below.

Let's say I want to play a looping stream in a single speaker (for instance, only in the Front Left speaker), you could do something like this:

; (...)
               $MusicHandle = _BASS_StreamCreateFile ($bass_dll, False, $file, 0, 0, BitOR($BASS_SAMPLE_MONO,$BASS_SAMPLE_LOOP,$BASS_SPEAKER_FRONTLEFT))
             ; (...)

Thing is.. $BASS_SPEAKER_FRONTLEFT doesn't set the stream to the Front Left speaker.

Taking a brief look at BassConstants.au3:

; (...)
               Global Const $BASS_SPEAKER_FRONT = 0x1000000; front speakers
               Global Const $BASS_SPEAKER_LEFT = 0x10000000; modifier: left
               Global Const $BASS_SPEAKER_FRONTLEFT = $BASS_SPEAKER_FRONT Or $BASS_SPEAKER_LEFT
             ; (...)

I really couldn't understand what the problem was. When I got tired of messing around with cabling, I found the "funniest" thing:

It works if I literally add the values together! What the...??

So: $BASS_SPEAKER_FRONTLEFT = $BASS_SPEAKER_FRONT + $BASS_SPEAKER_LEFT

Or: 0x1000000+0x10000000=0x11000000

Working example:

; (...)
               $MusicHandle = _BASS_StreamCreateFile ($bass_dll, False, $file, 0, 0, BitOR($BASS_SAMPLE_MONO,$BASS_SAMPLE_LOOP,0x11000000))
             ; (...)

Is there something obvious that I'm missing here? (like, let's say, I'm scripting this in the wrong way? :mellow: )

The other thing is... Rear speakers are not responding individually with anything I've tried so far..

However, the Center and LFE speakers respond as expected, just as well as the front speakers.

This leads me to believe that this specific problem comes from my soundcard configuration.

Now, again, thank you for your all your work. Really. I just hope there's a solution ;)

Tomorrow I'll keep trying stuff out.. Starting 6 PM GMT. See you guys then! :(

Edited by footswitch
Link to comment
Share on other sites

Yes you have to literally add the constants together.

Glad to hear you have something working. I will be able to test multi channel set-ups in a month (unless I play with my parents computer and hook it into my system. FYI- I'm on a laptop).

As I can't test I am unsure on what we need to do, so I will leave it up to you to have a play and see if anything works. :mellow:

Cheers,

Brett

EDIT: I will double check the constants too. It seems there are some errors.

Edited by BrettF
Link to comment
Share on other sites

Here is an example playing a sound file on the left, right then centre channel.

#include <Bass.au3>
#include <BassConstants.au3>

;Open Bass.DLL.  Required for all function calls.
$bass_dll = DllOpen("BASS.dll")

;Initalize bass.  Required for most functions.
_BASS_Init ($bass_dll, 0, -1, 44100, 0, "")

;Check if bass iniated.  If not, we cannot continue.
If @error Then
    MsgBox(0, "Error", "Could not initialize audio")
    Exit
EndIf

;Prompt the user to select a MP3 file
$file = FileOpenDialog("Open...", "", "Any File (*.*)")

; Front Left
$HNDL_FL = _BASS_StreamCreateFile ($bass_dll, False, $file, 0, 0, BitOR($BASS_SAMPLE_MONO,$BASS_SAMPLE_LOOP,$BASS_SPEAKER_FRONTLEFT))
; Front Right
$HNDL_FR = _BASS_StreamCreateFile ($bass_dll, False, $file, 0, 0, BitOR($BASS_SAMPLE_MONO,$BASS_SAMPLE_LOOP,$BASS_SPEAKER_FRONTRIGHT))
; Center
$HNDL_C = _BASS_StreamCreateFile ($bass_dll, False, $file, 0, 0, BitOR($BASS_SAMPLE_MONO,$BASS_SAMPLE_LOOP,$BASS_SPEAKER_CENTER))

MsgBox (0, "", "Starting Front Left speaker.")
_BASS_ChannelPlay ($bass_dll, $HNDL_FL, 1)
;Check if we opened the file correctly.
If @error Then
    MsgBox(0, "Error", "Could not load audio file" & @CR & "Error = " & @error)
    Exit
EndIf
Sleep (2000)
MsgBox (0, "", "Starting Front Right speaker.")
_BASS_ChannelPlay ($bass_dll, $HNDL_FR, 1)
;Check if we opened the file correctly.
If @error Then
    MsgBox(0, "Error", "Could not load audio file" & @CR & "Error = " & @error)
    Exit
EndIf
Sleep (2000)
MsgBox (0, "", "Starting Center speaker.")
_BASS_ChannelPlay ($bass_dll, $HNDL_C, 1)
;Check if we opened the file correctly.
If @error Then
    MsgBox(0, "Error", "Could not load audio file" & @CR & "Error = " & @error)
    Exit
EndIf
Sleep (10000)

Exit

Func OnAutoItExit ()
    _BASS_Free ($bass_dll)
EndFunc

Seems to work at the moment... :|

Link to comment
Share on other sites

Hey All,

Another example that I hope works!

Download below!

I hope it works as it should!

Cheers,

Brett

Please note it does not include BASS.dll, or BASS.au3 and BASSConstants.au3.

See post 3 for updated working example.

Edited by BrettF
Link to comment
Share on other sites

Hey All,

Another example that I hope works!

(...)

Like I said before, the speaker assignment values must be literally added in order to make it work.

Using the constants included in BassConstants.au3 (which use 'Or' instead of '+') doesn't work. At least in my case.

Working version (added LFE channel for subwoofer): MultiChannelViewer_v2.zip

Gotta go to work. Later :mellow:

Link to comment
Share on other sites

OK, so...

I need to play the same sample in every four channels, but I need to have control over each speaker volume for that sample.

Meaning, I don't want to change the volume in all speakers at the same time to the same degree.

For instance, at one point I want to decrease the volume ONLY in Front Left, but leave the other speakers intact.

BASS.dll has channel linking, which is somehow an indirect way to do it, but it's rather easy to get the speakers desynchronized from each other.

So, solution is... BASSmix.dll

From the BASSmix documentation: "BASSmix is an extension to the BASS audio library, providing the ability to mix together multiple BASS channels, with resampling and matrix mixing features."

This is going to be a bit of a pain for me, because I've never "translated" these VB DLL Functions to AutoIt before. I don't even know how to build those DLL Structures. And BASSmix's matrixes, I haven't even had the time to look at them straight.

But I have no option. I'll try to learn from your files. Just for reference.. How long did you take to translate/rewrite BASS.dll Functions to AutoIt? :mellow:

I'm very excited about getting this done. This is somewhat a christmas group project involving robotics and we'll only meet during Saturday or Sunday, so timing is really tight..

Link to comment
Share on other sites

Okay I've set up another computer with my surround sound system, and I have working 5.1CH sound. I've got to finish some more of the UDF functions, then I will post for testing.

Edited by BrettF
Link to comment
Share on other sites

First Post Updated,

Second Deleted.

Everything can now be found in a .zip file (under 1MB) containing BASS.dll, Bass.au3, BassConstants.au3 and the examples.

I fixed that error too thanks eukalyptus.

Cheers,

Brett

Link to comment
Share on other sites

bassasio.au3 for using ASIO-drivers with bass.

nothing documented at the moment...

3 examples included:

example_livefx.au3 - like the example comes with bassasio.dll (AsioIn => + FX => AsioOut)

example_playfile.au3 - ASIO-version of BrettF´s example1.au3

example_record.au3 - record to wavfile from AsioIn

http://rapidshare.com/files/162578015/bassasio.rar

enjoy

Eukalyptus

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...