8x sample player using the internal SAFP (GP 4.82 and later)

Hi folks!
This time i made a rackspace for a sample/audio player with 8 tracks/slots.
I used the internal Streaming Audio File Player (SAFP) as the source…
In the rackspace you can load up to 8 audio files into the SAFP which are then available to be played via separate buttons (you can map those buttons to your midi controller at will).
The tracks will only work in a “radio button” manner (the SAFP can only play one track at a time)!
You can activate “loop play” mode, or leave it OFF which then causes the tracks to be played as single shot.
I used quite a bit of scripting to make the UI as informative as possible, which means:

  • you only will see widgets for the number of actual available tracks
    (empty track’s elements are hidden)
  • the name of the available tracks
  • the tracks area is updated with each change of the track list in the SAFP

Just press a “Track button” to make it play.
As long as loop mode is active, the player will continue playing, while you can switch between the diffrent tracks.
Pressing “STOP” will stop the player and reset the playhead position.
Pressing PLAY/PAUSE while audio is played will pause the playhead, from where you can continue playing by pressing PLAY again.

Important to know:
If you change the playlist in the SAFP (deleting one file or adding one), the respecting assignment of the track buttons will change accordingly! The SAFP only supports a continuous playlist - no empty spaces allowed/possible!
Even if you can load up to 1000 tracks into SAFP, the rackspace is layed out to handle just 8!

This is how it looks like:
empty state

5 files loaded

fully loaded (8 tracks)

in action:

This is the script content (for the curious ones):

var
lblTrkSelect, btnLoop, btnPlay, btnStop : widget
btnTrk1,btnTrk2,btnTrk3,btnTrk4,btnTrk5,btnTrk6,btnTrk7,btnTrk8 :widget
lblTrk1,lblTrk2,lblTrk3,lblTrk4,lblTrk5,lblTrk6,lblTrk7,lblTrk8 :widget

trackSelection : widget array = [btnTrk1,btnTrk2,btnTrk3,btnTrk4,btnTrk5,btnTrk6,btnTrk7,btnTrk8]
lblTrkNames : widget array = [lblTrk1,lblTrk2,lblTrk3,lblTrk4,lblTrk5,lblTrk6,lblTrk7,lblTrk8]
trkNrTot : integer


plgSAFP : PluginBlock

function SetTracks() //user function to set the trackselection area on start or if the tracklist has changed
var
index: integer
    trkNrTot = Round(GetParameter(plgSAFP, 15)*1000) //get number of loaded tracks
    
    if trkNrTot == 0 Then
       SetWidgetLabel(lblTrkSelect, "NO TRACKS LOADED!")
    else
        SetWidgetLabel(lblTrkSelect, "TRACK SELECTION")
    end
    
    For index=0; index<Size(trackSelection); index = index +1 Do
        if index +1 > trkNrTot Then
            SetWidgetHideOnPresentation(trackSelection[index], true)
            SetWidgetHideOnPresentation(lblTrkNames[index], true)
        else
            SetWidgetHideOnPresentation(trackSelection[index], false)
            SetWidgetHideOnPresentation(lblTrkNames[index], false)
        end
        SetWidgetValue(trackSelection[index],0) // turn off all trackselect widgets
    end

    For index=0; index<Size(lblTrkNames); index = index +1 Do
        SetParameter(plgSAFP, 13, IntToFloat(index)/1000)
        SetWidgetLabel(lblTrkNames[index],GetParameterText(plgSAFP, 14))
    end

End

function zeroTrackSelection() // user function to zero every track select button
var
index : integer
    for index=0; index<Size(trackSelection); index = index +1 Do
        SetWidgetValue(trackSelection[index],0)
    end
End

// Called automatically after script is loaded
Initialization
    SetTracks() // call user function to set the trackselection area
    zeroTrackSelection() // call user function to zero the trackselect widgets
End

// Called when a plugin block parameter value has changed
On ParameterValueChanged(parameterNumber : integer, parameterValue : double) from plgSAFP
    if parameterNumber == 15 Then // if the number of tracks has changed
        SetWidgetValue(btnStop,1.0)
        SetTracks() // call user function to set the trackselection area
        SetWidgetValue(btnStop,0)
    end
End

// set track selection
On WidgetValueChanged(w : Widget, index: integer, newValue : double) from btnTrk1,btnTrk2,btnTrk3,btnTrk4,btnTrk5,btnTrk6,btnTrk7,btnTrk8
    if newValue > 0.6 Then
        SetParameter(plgSAFP, 13, IntToFloat(index)/1000)
        SetWidgetValue(btnPlay,1.0)
    end
End

On WidgetValueChanged(bVal:double) from btnPlay
    if bVal <0.4 and GetWidgetValue(btnLoop) < 0.4 Then
        zeroTrackSelection() // call user function to zero the trackselect widgets
    end
End

On WidgetValueChanged(bVal:double) from btnLoop
    if bVal <0.4 Then
        zeroTrackSelection() // call user function to zero the trackselect widgets
    end
End

On WidgetValueChanged(bVal:double) from btnStop
    if bVal <0.4 Then
        zeroTrackSelection() // call user function to zero the trackselect widgets
    end
End

And finally the gig file to download
(make sure you download the file for your actual version of Gig Performer!!!):

Only for GP V4
8xLoopPlayer.gig (459.2 KB)

Only for GP V5
8xLoopPlayer_workaround(V5).gig (459.5 KB)
(see postings below to know the reason for having to use a temporary “workaround”)

Have fun with it! :beers: :sunglasses:

16 Likes

Very useful, Eric. Thanks!

2 Likes

Hi - I Could not get this to work
Win 11 GP 5

Re
In the rackspace you can load up to 8 audio files into the SAFP which are then available to be played via separate buttons (you can map those buttons to your midi controller at will).

I loaded 8 wave tracks into Safp , I go back to rackspace and nothing showing in track list ?

1 Like

Thanks for your reply!
The SAFP of GPV5 seemed to have changed the parameter numbers list, so it couldn’t be working correctly.
I uploaded a diffrent version wich should work with V5 - please download and test this version.
(see my initial posting)
Cheers!
Erik

1 Like

Nice work Eric
All works now
Cheers

After saving with 8 files loaded

When re opening gigfile does not show any files loaded

You have to open safp and go back to panels view then they show up and work

ah, ok… good point. I have to check that… thanks.

Seems to be a bug… i have to discuss this with the devs.

Ok thanks Eric

Sorry to say, but at the moment the only workaround for this issue is to open/close the SAFP window…

… which can of course be scripted also. :slight_smile:

Absolutely awesome stuff!

I MUST get in to scripting this winter…

The design is simple but very effective…
Great work

1 Like

Ok thanks for replying-
Do you have a script to make it automatically open/work? . Cheers

Alright… i made another version (for GP5) which contains a workaround in the script which will cause the plugin window to open automatically for 500ms and then closes again.
This will happen on load (initialization) and also on activation (rackspace change).
I must confess i might be a bit naggy, but it seems to be the only working “trick” at the moment…
Please test if it works now.
If it doesn’t, you can try to adjust the waiting time in the script (use the local script editor).
It’s right at the end of the variable definition block (WaitTime).
Set it to another value (in milliseconds) and the press “Compile” to make the change take place.

8xLoopPlayer_workaround(V5).gig (459.5 KB)

I hope this works for you…

1 Like

Great stuff - will test
Cheers

1 Like

Works fine but - can’t below timer (500) by much.
lowest timer =150 and works safely
Nice work
Cheers

2 Likes

Just bought 16 pad trigger pad - is there a reason for limit of 8 tracks or can the script be modified for 16 tracks?

I just thought that for a first run, 8 tracks would be sufficient for most cases, but you can easily expand it. You just had to stick to the existing naming convention and add the according pads & labels on the panel and the variables in the script.
The “active” code of the script should be flexible enough to run with the additional elements.
Don’t forget to re-compile if you are done with the changes!

Hi
Will try to expand it in code - and let you know results
Cheers

1 Like

Dont forget to give the corresponding handle names to all the additional widgets!
Good luck!