Fruitbox V2 – Skins Guide, An Unofficial Guide to Understanding and Constructing Your Own Skins

Version 1.0 By Colin King

Introduction

Fruitbox is an amazing piece of software and is fully customisable

It may appear daunting at first but it is really fairly straight forward to design your own skins, even easier to edit or adapt an existing skin to suit your needs.

I am by no means an expert on fruitbox,I am an enthusiastic user and possibly an intermediate user. Most of this guide is from my own experiences with a few hints and tips gleaned from other users and responses to questions posed to the creator Mike Kingsley.

This is not meant to be a definitive guide but should be considered a companion document to be used alongside the Official Users Guide. Hopefully it will encourage you to give creating your own skin a go – and if you do build your own skin then please share it with the fruitbox community !

Colin King January 2024


The Skin Configuration File

The cornerstone of fruitbox is the configuration file fruitbox.cfg.

Fruitbox.cfg is found in the skin folder along with image files, sound files and text files. The .cfg file is a human readable .txt file that defines and links all these various files to provide the fruitbox interface.

When first looking at how skins are put together I noticed a lot of skins have files such as Foreground.png, Background.jpg etc. However it became apparent that fruitbox has absolutely no understanding of the terms foreground or background they are simply filenames they could be bananas and apples as far as fruitbox is concerned.

Configuration files (skins) define the look and feel of fruitbox. A configuration file is a human-readable text file containing a list of parameters and their values.

Parameters are grouped into sections, where each section is defined by its name enclosed in square brackets eg [bitmap], [status], [spectrum], a ‘header’ if you will. Each section ‘header’ is followed by the parameter list for that section. A parameter is defined by specifying its name, followed by its parameter value(s). (See the user guide for full details) Note: If a parameter is not specified in the configuration file, fruitbox will use a default value.

The order of these sections within the .cfg file is not important except when the section refers to a display object, in which case the order of the sections determines the physical order in which they are rendered to the display. Because fruitbox renders objects ie image files to the screen in the order they appear in the .cfg file it gives you the ability to build the screen in layers some of which will have transparent areas to act as ‘windows’ to the layers beneath. Knowing this simple fact is key in achieving the viewed end result.

Comments can be included in the configuration file by prefixing any comment text with the hash ‘#’ character. This is useful for adding notes to your .cfg file.

Status Boxes

Status boxes provide a very flexible way of displaying real-time text-based information, fixed and animated bitmaps, video clips and sound effects.

Examples of status include ‘Now Playing’ information, ‘Coming Up’ song list, Select Code, Credits, etc.

It will be seen that a [status] typically comprises of three main items:

  • The defined {status] entry in the .cfg file
  • An assosciated ‘contents’ file
  • An assosciated object (graphic, sound, video etc)

The contents file is a simple txt file that contains human readable text which indicates what is written, drawn or played in the status box.

As well as fixed text, the user can also use predefined variables, which represent song details and jukebox status, and also enable text and bitmaps to be conditionally drawn under many different circumstances.

Status boxes can also be used to allow GPIO pins to be driven with high or low values under different fruitbox conditions.

Over the following pages you can view an overview of the configuration file for a skin an existing skin (SB-M1100).
In the left column is the actual .cfg file listing, in the right column is a breakdown and description of the parameters being called.

After the above overview we move onto Planning and designing a new skin, followed by ‘Lets Build This’ section – these parts are best followed with the actual example skin being built ‘SmallSage’ available from the fruitbox Git Hub if not already pre-loaded in your fruitbox download.

https://github.com/chundermike/rpi-fruitbox-v2

 

SB-M100 Skin and fruitbox.cfg file

Understanding The Configuration File (fruitbox.cfg)

The configuration file is the key document in fruitbox.

Here is a breakdown of the fruitbox.cfg file for the SB-M100 skin and descriptions of its various parts

Actual .cfg file entryNotes
[general]
SkinName = SB-M100 SkinDescription = by Keefypee
SkinSize = 1920 1080  
Skin Name

Skin size in pixels
SortSongsBy = Title SortSongsBy = ArtistYou can sort songs alphabetically for the following database fields :
Title, Artist, Album, AlbumArtist, Year, Genre, TrackNumber, Publisher, ISRC, Custom Tag, Random, Unsorted.
You can sort multiple times eg:
SortSongsBy = AlbumArtist
SortSongsBy = Album
SortSongsBy = TrackNumber
SelectButtons = ABCD
SelectButtons = 12345678
These are the actual buttons the skin will use (your jukebox may have more but they will be inactive with this particular skin) In this instance it will produce the codes A1, A2, A3, A4, A5, B1, B2, … E8
SelectButtonsSequence = RowColColRow : SelectButton sequences are cycled in order they are defined
RowCol : SelectButton sequences are cycled in reverse order they are defined
AutoSelect = yesThe song is selected immediately on entering the select code.
If set to ‘No’ you will need to hit the ‘select’ button to play the song
SelectTimeout = 4 secondsTimeout for select code to return to undefined after not detecting all the selection digits
SelectHoldTimeout = 2 seconds  Timeout for select code to return to undefined after song selected
SongsPerTitleStrip = 2  Number of song entries on each song title strip
TitleStripAutoTurnTime = 1 minute  Time between title_strips automatically turning (0 = no automatic title strip turn)
TitleStripSize = 374 100  Size of each title strip in pixels
TitleStripBackground = page_bkgndred.jpg
#TitleStripBackground = page_bkgndgreen.jpg Rock
#TitleStripBackground = page_bkgndblue.jpg Pop
Filename of graphic image (bmp, png, tga, jpg, pcx) to be used as the title strip background. Optional Genre string is name of genre specific title strip background so you could have different colour title strips for each genre defined
TitleStripMoveStyle = 12 5 yesThe style of animation of the title strip <speed> <effect> <fade>
<speed> 1..x = higher number = faster title strip turn (0 = instant)
<effect> 0 = swipe horizontally 1 = swipe vertically 2 = reveal horizontally 3 = reveal vertically 4 = turn horizontally 5 = turn vertically 6 = dissolve
<fade> no = title strips don’t fade yes = title strips fade to black
PairSongs = DualNo – each song in a title strip is listed with its artist line
Yes – two songs are displayed (above and below) the artist line only if they are by the same artist
Dual – two songs are displayed (above and below) the artist line regardless of artist (both artists will appear on artist line which may be crowded on smaller screens)
SongText = 1 0 0 0 255 center false -1 false 0 4 330Text style for Song Title in title strip <font> <colour (r g b a)> <alignment> <capitalise> <mode> <quoted> <offset (x y)> <max_width>
See section ‘Fonts and Text’ in user guide for more details
ArtistDescription = ${SONG_ARTIST} / ${PAIRED_SONG_ARTIST}  Defining the artist description in the title_strips
ArtistText = 1 0 0 0 255 centre true -1 false 0 4 250Text style for Artist Name <font> <colour (r g b a)> <alignment> <capitalise> <mode> <quoted> <offset (x y)> <max_width>
See section ‘Fonts and Text’ in user guide for more details
ExtraDescription = ${GENRE}Defining the extra description in the title_strips (same values as ‘SongDescription’) Note that each entry must have a corresponding “ExtraText” entry (see below)
ExtraText = 4 32 32 32 200 right false -1 false -8 4 330Text style for the extra text field(s) in song title strip ExtraText * <font> <colour (r g b a)> <alignment> <capitalise> <mode> <quoted> <offset (x y)> <max_width> Note that this must be defined for each definition of “ExtraDescription”
ExtraDescription = ${PAIRED_GENRE}  As Above
ExtraText = 4 32 32 32 200 right false -1 false -8 80 330  As Above
SongLoadTime = 7.5 seconds  The time the song takes to load (from removing from the coming up queue to starting to play)
SongUnloadTime = 7 secondsThe time the song takes to unload (from finishing playing to the next song in the queue loading)
[status]
Contents = coin_insert_sound.txt
Sound = coin-insert.wav 90
A Status typically has three parts: This Status which defines the other two items: Contents – An assosciated  txt file which will instruct fruitbox when and what to do. An assosciated file (Bitmap, Sound, Video, text etc) In this case the Status will play the sound of a coin being inserted. The number following a defined audio file is the volume level it will be played at
[status]
Contents = select_song_sound.txt
Sound = JBBPress.wav 100  
As Above
[status]
Contents = load_song_sound.txt
Sound = mech-only2.wav 90  
As Above
[status]
Contents = unload_song_sound.txt
Sound = mech-only-rev.wav 90  
As Above
[status]
Contents = invalid_song_sound.txt
Sound = invalid.wav 100  
As Above
[fonts]
File = courierb.ttf 25
File = dvsansb.ttf 19
File = hatten.ttf 50
File = courier.ttf 16
Lists the fonts and sizes to be added to the fontpool   <file><height> (ttf, opentype, type1, CID, CFF, fon, fnt, x11, pcf)
Note that the order in which the fonts are defined in the [fonts] section determines their font number, starting at 1.
(Font number 0 is the internal fruitbox font used for the on-screen menus etc)
[bitmap]
File = lighting.jpg
Position = 346 700
Size = 1228 360
Tint = 32 [255 ${SPECTRUM_BAND} 0] 32 [255 ${SPECTRUM_BAND} 0] 32 [255 ${SPECTRUM_BAND} 0] 255  
This is the background behind the spinning record
[status]
Position = 346 880 [700 ${SONG_LOAD_POSITION}]
Size = 1228 360
Bitmap = record_spin01.png
Bitmap = record_spin02.png
Bitmap = record_spin03.png
Bitmap = record_spin04.png
Bitmap = record_spin05.png
Bitmap = record_spin06.png
Bitmap = record_spin07.png
Bitmap = record_spin08.png
Bitmap = record_spin09.png
Bitmap = record_spin10.png
Bitmap = record_spin11.png
Bitmap = record_spin12.png
Bitmap = record_spin13.png
Bitmap = record_spin14.png
Bitmap = record_spin15.png
Bitmap = record_spin16.png
Contents = record_spin.txt
TimerTickPeriod = 1
A status to display a ‘video’ animation of a spinning record at a defined size and position. As can be readily seen the ‘video’ is actually a series of images displayed at a defined speed (TimerTickPeriod)
[bitmap]
File = pickup.png
Position = 510 180 [380 ${SONG_LOAD_POSITION}]
Size = 440 500
Angle = -5 [-60 ${NOW_PLAYING_ELAPSED_TIME}]
An image of a tone arm with dynamic parameters which will ‘move’ the tone arm from its song load position to its maximum position as governed by the elapsed time. The format of the dynamic value field is “[max_value mode <param>]”. Note the square brackets must be specified in order for the dynamic values to be recognised. The parameter value will change between the initial value and the ‘max_value’.  
[title strip]
Position = 50 112
Angle = 359
Movedelay = 10
MoveReverse = no
Defines where the title strip will be positioned and how it will be displayed. Position in pixels Angle (0 – 360 degrees) MoveDelay = Delay (in video frame ticks) between left/right button press and the title strip physically moving MoveReverse = Yes/No Reverse the direction of the title strip movement  
[title strip]
Position = 50 230
Angle = 0
Movedelay = 4
MoveReverse = no
By varying the Angle and MoveDelay and MoveReversein different title strips can give the illusion of title strips ‘tumbling’ in a more convincing mechanical jukebox effect rather than perfect ‘digital’ movement.
[title strip]
Position = 50 348
Angle = 0
Movedelay = 5
MoveReverse = no
As Above
[title strip]
Position = 554 112
Angle = 0
Movedelay = 7
MoveReverse = yes
As Above and similar for all other title strips defined in the .cfg file
[bitmap]
File = foreground.png
Position = 0 0
Size = 1920 1080
Tint = 255 255 255 255
A defined image at a defined size and position, in this case full screen  Fruitbox doesn’t understand the terms foreground and background. Objects are drawn to the screen in the order they are defined in the .cfg file. Hence the preceeding title strips are drawn before this ‘foreground’ image is drawn / ‘laid’ on top. Tint modifies the objects colour Tint <red> <green> <blue> <alpha>
[status]
Contents = stereo.txt
Position = 864 930
Size = 200 26
Bitmap = stereo_red.png
Tint = 200 [255 ${RANDOM}] 255 255 255
Status to display (draw) an image at the defined location whenever a stereo song is detected. The image Tint will vary randomly between an RGB value of 200 and 255giving the illusion of an incandesant lamp
[spectrum]
Position = 120 750
Size = 318 222
HorizontalFlip = yes
Tint = 80 80 80 255
Band = 0 1.0 0 0
Band = 1 1.0 0 0
Band = 2 1.0 0 0
Band = 3 1.0 0 0
Band = 4 1.0 0 0
Band = 5 1.0 0 0
Band = 6 1.0 0 0
Band = 7 1.0 0 0
Band = 8 1.0 0 0
Band = 9 1.0 0 0
Band = 10 1.0 0 0
Band = 11 1.0 0 0
Band = 12 1.0 0 0
Band = 13 1.0 0 0
Band = 14 1.0 0 0
Band = 15 1.0 0 0
Band = 16 1.0 0 0
Band = 17 1.0 0 0
Band = 18 1.0 0 0
Band = 19 1.0 0 0
Bitmap = spectrum.png
Mode = scaled
Channel = left
Decay = 2
A [spectrum] object allows an audio frequency spectrum to be displayed for the mp3 songs.   Multiple [spectrum] objects can be defined. Various options allow great flexibility in the visual appearance. For example, the user has control over the look of each of the 32 possible frquency bands, and which are visible.  
The position is the position prior to flipping    
Band = <number (0 thru 31)>
[gain (1.0 nominal)]
[offset (x y)]
[tint (r g b a)] Note: the tint is applied in addition to the global [spectrum] Tint  
Bitmap is the defined graphic used to display each band
Mode specifies how the graphic is drawn using the audio values. It can be either scaled, clipped or position:
Scaled – the graphic is drawn fully, but sized to the appropriate height
Clipped – The graphic is not scaled, but cut off at the audio value height
Position – The graphic is  drawn full size, but the audio value determines its vertical position  
Channel can be Left, Right or Both  
Decay <value> the speed of peak Decay – time (0=instant)
[spectrum]
Position = 120 750
Size = 318 222
Tint = 255 255 255 255
Band = 0 1.0 0 0
Band = 1 1.0 0 0
Band = 2 1.0 0 0
Band = 3 1.0 0 0
Band = 4 1.0 0 0
Band = 5 1.0 0 0
Band = 6 1.0 0 0
Band = 7 1.0 0 0
Band = 8 1.0 0 0
Band = 9 1.0 0 0
Band = 10 1.0 0 0
Band = 11 1.0 0 0
Band = 12 1.0 0 0
Band = 13 1.0 0 0
Band = 14 1.0 0 0
Band = 15 1.0 0 0
Band = 16 1.0 0 0
Band = 17 1.0 0 0
Band = 18 1.0 0 0
Band= 19 1.0 0 0
Bitmap = spectrum.png
Mode = scaled
Channel = right
Decay = 2
As Above
[status]
Position = 116 750
Size = 314 222
Text = 2 255 0 0 255 center false 1 false 0 0 300 Contents = now_playing.txt
TimerTickPeriod = 4 linespacing = 1
A Status Box at a defined position and size displaying info on the song currently being played Displaying text using font number 2 (dvsansb.ttf 19) from the text pool see [fonts] above <font> <colour> <alignment> <capitalise> <mode> <quoted> <offset (x y)> <max_width> the text colour is 255 0 0 255, the text is centre aligned,  not capitalised, text is scrolled at the specified speed (1 = slowest) if it doesn’t fit into max_width, text is not quoted, no offsets for positioning, and a maximum width of 300 characters Linespacing (gap) in pixels
[status]
Position = 1500 812
Size = 310 148
Text = 2 255 0 0 255 center false -1 false 0 0 300 Contents = coming_up.txt
LineSpacing = 1
A Status box at a defined position and size displaying text of songs coming up
[status]
Position = 1480 746
Size = 190 160 Text = 3 255 0 0 255 center false 0 false 0 0 160
Contents = selection.txt
A status box at a defined position and size displaying the song selection using font 3 (hatten.ttf 50)
[status]
Position = 1660 746
Size = 190 160
Text = 3 255 0 0 255 center false 0 false 0 0 160
Contents = credits.txt
TimerTickPeriod = 150
A Status box at a defined position and size displaying “Freeplay” or the number of credits available

Building A New Skin

Planning A New Skin

Consider what it is you want the skin to look like, what information and how you want it displayed.

In this example  :

  • I want  a skin for a small 10.1” display
  • I want a clean and simple look
  • I want the title strips to :
    • roll up / down in synch
  • I want to display:
    • Selection made
    • Now Playing info
    • Coming Up info
  • I want status messages for:
    • User Select Mode / Autoplay Mode
    • Invalid Selection
    • Duplicate Selection
    • Play Paused
    • Play Muted
  • I want a graphic image for:  
    • Play Paused
    • Play Mute
  • I  want a sound effect for:
    • Title Strip movement
    •  Invalid Selection  
    • Duplicate Selection
  • I want the 12 title strips to show  a single artist and song unless both songs are by the same artist
    • (This should help keep it clean uncluttered by the increase in ‘white space’)

Design Time

Fire up your art package of choice –  I run Corel Paintshop Pro X9  (2016)  it maybe a little outdated but its still got more features than I’m ever likely to use.

I am making the huge assumption you know how to use your chosen software of choice as this is a guide for fruitbox skinning not a Photoshop masterclass.

Because this skin is for use on a smaller display I created a new image with a size of 1280 x 720 pixels with a resolution of 72 pixels per cm and a transparent background.

Normally most fruitbox skins are 1920 x 1080. Fruitbox will rescale the skin to fit the display in use but its perhaps best practice to keep the size relative to the display.

Pick out your colour and flood fill the image – I went for a nice Sage green, hence the name SmallSage.

We now need to ‘cut’ holes for the title strips to show through to the transparent background – this will let the title strips show through from underneath. To do so we need to know what size title strip we are using so it’s a bit of a chicken and egg situation as to what you want to do first. There are different ways of doing this depending on your software of choice, ability etc. but basically you make the title strip a few pixels bigger than the hole so that you don’t end up with any black ‘dead’ areas or lines showing.

Most art packages include tools for sizing  ‘objects’ such as rectangles and have other tools like Align and Distribution to make life easier planning on the placement of title strips on your workspace. There are also online resources that may help like this one  Smaller Rectangles Within A Larger Rectangle   

It is quite usual to have the status boxes cut-out to the transparency too like small windows for the status message displays. However,  in this case I want to print the Now Playing and coming up info printed onto areas that match the title strips and the status messages to be printed onto the same sage green background to ensure a clean uncluttered look, less is more as they say.

This is the title strip (size 400 x 112pixels)

So, this is what my ‘foreground’ image looks like – remember, fruitbox doesn’t understand the terms foreground or background they are just convenient names of images. The transparent (chequered) are where the title strips will be positioned/drawn by fruitbox BEFORE drawing the foreground over the top effectively masking any overlap.

The status box for things like ‘User Select Mode’, ‘Autoplay Mode’, ‘Duplicate Selection’, ‘Invalid Selection’ and ‘Select Code’ is to be defined as the area in between the ‘Now Playing’ and ‘Coming Up’ areas.

Once you have an image your happy with grab a pen and a notepad as you will need to ‘map’ certain areas of your image to tell fruitbox what and where the areas are.

So, with the image loaded in your art package you can zoom in to 100% or more to accurately measure each of the top left corners of the title strip ‘holes’ and its size (both in pixels) the ‘Now Playing’ status box, the ‘Coming Up’ status box and the area where you want to place status messages.

Most art packages have a cross hair cursor and co-ordinates easily found. Hopefully as we go through the .cfg file it will all start making sense !

Let’s Build This !

OK, armed with our image files – foreground and title strip, any sound effect files you want to use we can assemble the whole jukebox interface using nothing more than than a humble text editor – good old Notepad if you’re a PC kind of guy.

So boot up Notepad and create a file fruitbox.cfg (or cheat and edit an existing .cfg file from another skin, its what we all do) and start entering the info:

Refer back to the SB-M100 skin config file as and when you you need to !

Note: When editing the configuration file you can use the hash ‘#’ to make notes as fruitbox will ignore anything on that line after the #

SkinName = SmallSage 
SkinDescription = by Colin King 
SkinSize = 1280 720 
SortSongsBy Title 
SortSongsBy Artist 
SelectButtons = ABC 
SelectButtons = 12345678 
AutoSelect = Yes 
SelectTimeout = 3 sec 
SelectHoldTimeout = 3 sec 
NoDuplicates = yes 
  
# TITLE STRIPS 
TitleStripAutoTurnTime = 1 minute 
SongsPerTitleStrip = 2 
TitleStripSize = 400 112Make sure you change this to your title strip size
TitleStripBackground = title_strip.pngMake sure you change this to your title strip image name
PairSongs = yes 
SongDescription = ${SONG_TITLE} 
ArtistDescription = ${SONG_ARTIST} 
TitleStripMoveStyle = 15 5 no 
SongLoadTime = 0.5 sec 
SongUnloadTime = 0 
ArtistText = 2 185 50 55 220 centre true -1 false 0 8 170You may need to revisit these to fine tune position of text in title strips
SongText = 1 50 40 45 200 centre true -1 false 0 8 239as above
PairedSongText = 1 50 40 55 200 centre true -1 false 0 0 239As above
  
[fonts] 
File = TCB_____.TTF 27
File = TCB_____.TTF 25
File = TCB_____.TTF 35
 
  
# TITLE STRIPS COLUMN #1 
[title strip]
Position = 25 160
Movedelay = 0
Make sure the positions match those of your image
[title strip]
Position = 25 287
Movedelay = 0
Make sure the positions match those of your image
[title strip]
Position = 25 416
Movedelay = 0
Make sure the positions match those of your image
[title strip]
Position = 25 543
Movedelay = 0
Make sure the positions match those of your image
  
# TITLE STRIPS COLUMN #2 
[title strip]
Position = 446 159 
Movedelay = 0
Make sure the positions match those of your image
[title strip]
Position = 446 287
Movedelay = 0
Make sure the positions match those of your image
[title strip]
Position = 446 417
Movedelay = 0
Make sure the positions match those of your image
[title strip]
Position = 446 543
Movedelay = 0
Make sure the positions match those of your image
  
# TITLE STRIPS COLUMN #3Make sure the positions match those of your image
[title strip]
Position = 866 159
Movedelay = 0
 
[title strip]
Position = 866 287
Movedelay = 0
Make sure the positions match those of your image
[title strip]
Position = 866 415
Movedelay = 0
Make sure the positions match those of your image
[title strip]
Position = 866 543
Movedelay = 0
Make sure the positions match those of your image
  
[bitmap] File = foreground.png
Position = 0 0
Size = 1280 720
 The image of the foreground – Remember fruitbox doesn’t recognise terms like foreground and background. Its just a filename. What is important is that it is positioned after the title strip images to display correctly on screen
  
[status]
# Page turn sound
Contents = page_turn.txt
Sound = pagemove.wav 80
The contents of page_turn_txt:
${IF_TITLE_STRIP_MOVING}${IF_NOT_SONG_PLAYING}${PLAY_SOUND} 
[status]
# PAUSE
Position = 0 0
Size = 1280 720
Bitmap = paused-text.png
Contents = pause_pressed.txt
The contents of Pause_pressed.txt:
${IF_PAUSED}${DRAW_BITMAP}

${IF_NOT_PAUSED}${UNDRAW_BITMAP}  
  
 [status]
# MUTE
Position = 0 0
Size = 1280 720
Bitmap = muted-text.png
Contents = mute_pressed.txt     
contents of mute_pressed.txt:
${IF_MUTE}${DRAW_BITMAP}

${IF_NOT_MUTE}${UNDRAW_BITMAP}  
  
[status]
# NOW PLAYING
Position = 17 43
Size = 483 89
Text = 1 50 40 45 200 centre true -1 false 0 8 239
Contents = status_nowplaying.txt
contents of status_nowplaying.txt:
${IF_PAUSED}JUKEBOX IS${ELSE}${IF_NOT_PAUSED}${IF_MUTE}JUKEBOX IS${ELSE}${IF_NOT_MUTE}${IF_SONG_PLAYING}${NOW_PLAYING_TITLE}${ELSE}${IF_NOT_SONG_ PLAYING}${IF_NOT_ATTRACT_MODE} USER SELECT MODE ${ELSE}${IF_NOT_FREEPLAY}${IF_NO_CREDITS}INSERT COIN - SELECT LETTER THEN NUMBER${ELSE}${IF_ANY_CREDITS}${CREDITS} CREDITS - SELECT LETTER THEN NUMBER${END_IF}

${IF_PAUSED}PAUSED${ELSE}${IF_NOT_PAUSED}${IF_MUTE}MUTED${ELSE}${IF_NOT_MUTE}${IF _SONG_PLAYING}${NOW_PLAYING_ARTIST}${ELSE}${IF_NOT_SONG_PLAYING}${IF_NOT_ATTRAC T_MODE}SELECT LETTER AND NUMBER 

${IF_SONG_PLAYING}${NOW_PLAYING_ELAPSED_TIME}     ${NOW_PLAYING_LENGTH}
  
[status] 
# COMING UP
Position = 767 43
Size = 483 899
Text = 1 50 40 45 200 centre true -1 false 0 8 239
Contents = status_comingup.txt
contents of status_comingup.txt:
${IF_ANY_COMING_UP}${COMING_UP_TITLE}${ELSE}${IF_NOT_ATTRACT_MODE}USER SELECT MODE${ELSE}AUTOPLAY MODE
${IF_ANY_COMING_UP}${COMING_UP_ARTIST}${ELSE}${IF_NOT_ATTRACT_MODE}SELECT LETTER AND NUMBER${ELSE}(SONGS ARE STILL SELECTABLE)

${IF_ANY_COMING_UP}${COMING_UP_NUM_SONGS} Tracks      - ${COMING_UP_TOTAL_TIME}
  
[status] 
# CURRENT MODE
Position = 501 43
Size = 264 62
Text = 2 214 214 214 200 centre true -1 false 0 8 239
Contents = status_current_mode.txt
Sound = Uh-Uh.wav 40
contents of status_current_mode.txt:
${IF_PAUSED}JUKEBOX IS${ELSE}${IF_NOT_PAUSED}${IF_MUTE}JUKEBOX IS${ELSE}${IF_NOT_MUTE}${IF_PLAYQUEUE_FULL}PLAYQUEUE${ELSE}${IF_DUPLICATE_CHOICE}D UPLICATE SELECTION${ELSE}${IF_INVALID_CHOICE}INVALID SELECTION${ELSE}${IF_NOT_ATTRACT_MODE}USER SELECT MODE${ELSE}AUTOPLAY MODE

${IF_PAUSED}PAUSED${ELSE}${IF_NOT_PAUSED}${IF_MUTE}MUTED${ELSE}${IF_NOT_MUTE}${IF _PLAYQUEUE_FULL}FULL${ELSE}${IF_DUPLICATE_CHOICE}SONG NOT ADDED

${IF_DUPLICATE_CHOICE}${PLAY_SOUND}

${IF_INVALID_CHOICE}${PLAY_SOUND}  
[status]
# Select CODE
Position = 501 107
Size = 260 48
Text = 3 214 214 214 214 centre true 0 false 0 0 46
Contents = status_select.txt
contents of status_select.txt:

${SELECT_CODE}
[spectrum]
Visible = yes
Position = 280 605 S
ize = 350 100
HorizontalFlip = yes
Tint = 218 216 211
Band = 0 0.8 0 0
Band = 1 0.9 0 0
Band = 2 1.0 0 0
Band = 3 1.0 0 0
Band = 4 1.0 0 0
Band = 5 1.0 0 0
Band = 6 1.0 0 0
Band = 7 1.0 0 0
Band = 8 1.0 0 0
Band = 9 1.0 0 0
Band = 10 1.0 0 0
Band = 11 1.0 0 0
Band = 12 1.0 0 0
Band = 13 1.0 0 0
Band = 14 1.0 0 0
Band = 15 1.0 0 0
Band = 16 1.0 0 0
Band = 17 1.0 0 0
Band = 18 1.0 0 0
Band = 19 1.0 0 0
Bitmap = spectrum.png
Mode = clipped
Channel = left
Decay = 4  
See the following section ‘Spectrum Analyzer’
  
[spectrum]
Position = 630 605
Size = 350 100
Tint = 218 216 211
Band = 0 0.8 0 0
Band = 1 0.9 0 0
Band = 2 1.0 0 0
Band = 3 1.0 0 0
Band = 4 1.0 0 0
Band = 5 1.0 0 0
Band = 6 1.0 0 0
Band = 7 1.0 0 0
Band = 8 1.0 0 0
Band = 9 1.0 0 0
Band = 10 1.0 0 0
Band = 11 1.0 0 0
Band = 12 1.0 0 0
Band = 13 1.0 0 0
Band = 14 1.0 0 0
Band = 15 1.0 0 0
Band = 16 1.0 0 0
Band = 17 1.0 0 0
Band = 18 1.0 0 0
Band = 19 1.0 0 0
Bitmap = spectrum.png
Mode = scaled
Channel = right
Decay = 4    
See the following section ‘Spectrum Analyzer’
  

And here it is, the finished skin

Spectrum Analyzer

A [spectrum] object allows an audio frequency spectrum to be displayed for the mp3 songs (Note: does not work for ogv videos)

Multiple [spectrum] objects can be defined, for most skins two would be defined to show Left and Right channels.

Various options exist to allow great flexibility in the visual appearance of the spectrum analyser.
For example, the user has control over the look of each of the 32 possible frquency bands, and which are visible.

The options within the .cfg file are:

  • Visible <yes|no>
    • Makes the object visible or invisible
  • Size <width> [dynamic] <height> [dynamic] (in pixels)
  • Position <x> [dynamic] <y> [dynamic] (in pixels)
  • Clip <x> [dynamic] <y> [dynamic] <width> [dynamic] <height> [dynamic] (in pixels)
  • Angle <angle>
    • [dynamic] of object in degrees (0..359)
  • Tint – <r> [dynamic] <g> [dynamic] <b> [dynamic] <a> [dynamic]
    • Modify the objects colour
  • DynamicEnableFlag <1..4>
    • Enable dynamic parameters using status flag 1..4
  • HorizontalFlip <yes|no>
    • Flip object horizontally
      • useful for making left and right audio channel bars appear as a ‘valley’ or a ‘mountain’
  • VerticalFlip <yes|no>
    • Flip object vertically
      • ideal for a Batcave skin with audio stalagtites pulsing down ??
      •  or one flipped and one not pulsing into a rectangle
  • Bitmap <filename> of band(s) graphic image (bmp, png, tga, jpg, pcx)
  • Band * <number (0..31)> [gain (1.0 nominal)] [offset (x y)] [tint (r g b a)]
  • Mode <position, scaled, clipped>

Obviously there is no need to itemise all the above parameters in the [spectrum] tab of the configuration file just the particular parameters you are calling.

Example (Classic Skin)

 

[spectrum] # LEFT ANALYSER BARS

Bitmap = spectrum.png

Mode = scaled

Position = 104 284

Size = 160 370

HorizontalFlip = yes

Decay = 3

Channel = left

Band = 0 1.0 0 0

Band = 2 1.0 0 0

Band = 4 1.0 0 0

Band = 6 1.0 0 0

Band = 9 1.0 0 0

Band = 12 1.0 0 0

Band = 15 1.0 0 0

Band = 18 1.0 0 0

[spectrum] # RIGHT ANALYSER BARS

Bitmap = spectrum.png

Mode = scaled

Position = 1414 284

Size = 162 370

HorizontalFlip = no

Decay = 3

Channel = right

Band = 1 1.0 0 0

Band = 3 1.0 0 0

Band = 5 1.0 0 0

Band = 7 1.0 0 0

Band = 10 1.0 0 0

Band = 13 1.0 0 0

Band = 16 1.0 0 0

Band = 19 1.0 0 0

Spectrum Analyzer Mode

With the spectrum analyser you specify the bitmap graphic used for the bands and the mode specifies how the image is drawn using the audio values.

Position

Position means the graphic is drawn full size but the audio value determines its vertical position.
Position can look like a squashed picture that is being pulled up to full height

Scaled

Scaled means the graphic is drawn fully but sized to the appropriate height.
It looks a little like a concertina effect being squashed and pulled.

Clipped

Clipped means the image is not scaled to fit but is drawn at 100% scale and is revealed by the audio value

It took me a while and a fair amount of head scratching to get to grips with the basics of the spectrum analyser.
Its not always easy  to envisage the effect applying either of the modes without trying them out first or having a look at other skins and see how other people have achieved particular effects.

If a picture can paint a thousand words then heres three thousand words to explain it more …….

Example 1 – Lift Off !
Example 2 – Small Block

OK so not everyone wants Saturn 5 rockets for a vu display so If you use a simple small block as the graphic then the mode effect is like this :

Example 3 – Multi-Coloured Bars

And a muli colotured graphic like this …….

Horizontal VU Bar

The bands that form the [spectrum] object are vertical components ie the object is positioned and drawn in a vertical orientation.

However, by use of the ‘angle’ parameter option we can rotate the object 0 – 359 degrees therefore we can create a horizontal VU bar by using ‘angle = 90’

When using the ‘angle’ parameter the object is rotated around a central axis point. However, please note that although the object is rotated its ‘position’ ie co-ordinates for its location (top left corner) remain the same.

As an example, In this picture below of Stans ‘Aluminium’ skin the object (vertical VU bar) is superimposed over the VU meter shown in its actual defined position co-ordinates for the left channel bar marked by the green cross. Setting the parameter to ‘angle = 90’ rotates  the left VU bar around its central axis into the desired position.

 Pic Courtesy of Stan

When designing the skin it may be easier to work out the physical location of where you want the graphic to be, locate its central axis and from this point work out its position co-ordinates for the .cfg file. You may have to tweak it a few times to get it spot on.

Example:

Stans .cfg for the VU Bar above

[spectrum]   # LEFT VU BAR Bitmap = vu_bar.png
Mode = clipped
Position = 675 228
Size = 14 340
Angle = 90
VerticalFlip = no
Decay = 0
Channel = left
Band = 0 1.1 0 0  
[spectrum]   # RIGHT VU BAR
Bitmap = vu_bar.png
Mode = clipped
Position = 675 258
Size = 14 340
Angle = 90
VerticalFlip = no
Decay = 0
Channel = right
Band = 0 1.1 0 0  

VU Meters

(pic courtesy of Jay Thompson)

After considering the possibilities of how, if at all, it would be possible to have hi-fi style VU meters on a skin I was resoundly beaten to the post by Brian Dermody and Jay Thompson who both previewed their resulting skins on the Digital Jukebox Builders Facebook page within hours of each other.

Its actually easier to achieve than I first thought.

By using the needle of the meter as the spectrum band we simply use the ‘angle’ parameter to position the needle eg angle = -45 will lean the needle to the left to align with the scale ‘0’ and it will swing to the right in time with the music frequency/amplitude

Remember that the  ‘angle’ parameter rotates around a central axis so add an equal transparent length to your needle so it pivots around its central axis point which will probably be the base of the visible needle.
Also remember that as above in the horizontal vu bar that the position co-ordinates remain the same despite use of the angle parameter.

Jay Thompsons .cfg code (background and foreground images omitted):

[bitmap]
File = needle.png
Position = 559 548
Size = 10 361
Angle = -47 [60 ${LEFT_SPECTRUM_BAND} 2]

[bitmap]
file = needle.png  
Position = 868 548
Size = 10 361
Angle = -47 [60 ${RIGHT_SPECTRUM_BAND} 2]

Note – in the above example the object (vu meter needle) is defined as [bitmap] not [spectrum] and as such we are unable to modify needle movement by use of the ‘gain’ or ‘decay’ as these are parameters for [spectrum] objects not [bitmap]

Most meters are made up of three graphic objects (bitmaps). The background with the vu scale on it, the needle and a foreground or mask layer. Remember the order these appear in the .cfg file is the order they are drawn to the screen.

Colour Organ

(pic courtesy of Brian Dermody)

I’ve never come across the term ‘Color Organ’ or ‘Light Organ’ before. I assume its an American term, here in the UK we would probably describe it as a sound-to-light box. So, if your after an effect that can replicate a disco light show from back in the day look no further.

I tried unsuccessfully to get this to work a few times using layered .png files but just kept getting a blank screen. Enter Brian Dermody, at the time of writing relatively new to Fruitbox but with years of DW Jukebox experience who posted a skin with a working color organ on the Digital Jukebox Builders Facebook page and kindly shared his skin for me to check it out.

What Brian did was to use white only images with a transparent background and then use the fruitbox ‘tint’ parameter and linking its opacity to a band of the spectrum analyser so that the colour transitions from 100% transparent (000) to fully opaque (255)  giving the illusion of varying illiumination brightness in time with the frequency.

The parameter for Tint is <R G B A>. By setting the RGB values to ‘0’ they are all transparent. By adding a progressive value of 255 and defining a band we will get an increase in colour proportional to the band frequency

This is typically written as:

 Tint = 0 [255 ${SPECTRUM_BAND} 2] 0 0 0

Notice that the increase to 255 and the spectrum band number are placed in parenthesis between the Red ‘0’ and the Green, Blue and Alpha 0’s. This will give a Solid Red appearance

A Green spectrum band would be:

Tint = 0 0 [255 ${SPECTRUM_BAND} 2] 0 0

And a Blue would be:

Tint = 0 0 0 [255 ${SPECTRUM_BAND} 2] 0

You can mix tints to give additional colours, eg for Yellow we can mix Red and Green:

Tint = 0 [255 ${SPECTRUM_BAND} 2] 0 [255 ${SPECTRUM_BAND} 2] 0 0

If that’s a little too yellow we can add a touch of blue to tone it down:

Tint = 0 [255 ${SPECTRUM_BAND} 2] 0 [255 ${SPECTRUM_BAND} 2] 20 0

And White would be:

Tint = 0 [300 ${SPECTRUM_BAND} 8] 0 [300 ${SPECTRUM_BAND} 8] 0 [300 ${SPECTRUM_BAND} 8] 0

As a point of interest Brian reported that it is possible to ‘fool’ fruitbox to thinking it can go from 0 to 300.  The highest in actuality is still 255, but the light spends more time at the high end and is fully ON when the sound level peak is 255 or above.  This, in general, results in a display that is brighter than if the range is simply set from 0 to 255.

Example:

For Brians  Color Organ pictured above

 [bitmap]                                             # Color Organ Green
file = ColorGreen.png
Position = 20 20
Size = 1900 1060
Tint = 0 0 [400 ${SPECTRUM_BAND} 5] 0 0

[bitmap]                                              # Color Organ White
file = ColorWhite.png
Position = 20 20
Size = 1900 1060
Tint = 0 [400 ${SPECTRUM_BAND} 6] 0 [400 ${SPECTRUM_BAND} 6] 0 [400 ${SPECTRUM_BAND} 6] 0

[bitmap]                                              # Color Organ Yellow
file = ColorYellow.png
Position = 20 20

Size = 1900 1060
Tint = 0 [400 ${SPECTRUM_BAND} 7] 0 [400 ${SPECTRUM_BAND} 7] 0 [30 ${SPECTRUM_BAND} 7] 0 

[bitmap]                                              # Color Organ Red
File = ColorRed.png
Position = 20 20
Size = 1900 1060
Tint = 0 [400 ${SPECTRUM_BAND} 1] 0 0 0

[bitmap]                                              # Color Organ Blue
file = ColorBlue.png
Position = 20 20
Size = 1900 1060
Tint = 0 0 0 [400 ${SPECTRUM_BAND} 4] 0

Note: Again, as with the VU Meter example these individual layers (objects) are defined as [bitmap] not [spectrum] objects and as such we are unable to modify the effect ‘gain’or ‘decay’ as these parameters have no effect on [bitmap] objects. You can try altering the spectrum band and perhaps the maximum opacity to tweak the effect to your liking but personally I think Brians choices work well in the majority of instances and you still have the option of adding additional [spectrum] objects into the mix.

I believe screens like the above Colour Organ will gain in popularity with the release of Fruitbox v3 and its Dual Display support.

End Note

Fruitbox is truly versatile and fully customisable.

Theres more than one way to skin a cat – and more than one way to skin a Fruitbox.

This guide is just a brief introduction and I hope you find it informative and gives you some pointers. If you do design your own skin please consider sharing it with the Fruitbox community.
If you have any tips or design methods you would like to share in this guide drop me a message via Digital Jukebox Builders on Facebook.