How to use the TracksBoard to visually compose songs
Audio DJ Studio API for .NET, through the TracksBoard class, allows visually composing new sound and/or music files by mixing together audio incoming from two main audio sources:
|•||Sound files stored inside disk files: these sound files can be in several audio formats as seen inside the LoadSound and LoadSoundFromRawFile methods|
|•||The Microsoft Speech API which allows creating audio data from a string of text or from a text file through synthesized voices|
An important concept about this feature is the fact that all sound items composing the session are layered, meaning that they can be added, removed or modified before being mixed for playback or for export into a destination file.
The TracksBoard can be added at runtime to the container form by invoking the TracksBoard.Create method which instances the window containing the user interface (very similar to the one rendered by the WaveformAnalyzer object implemented by our Audio Sound Recorder API for .NET and Audio Sound Editor API for .NET components) and links a player instanced by the control for the purpose of allowing playback of the final mix; as any other window, it can be later destroyed through the TracksBoard.Destroy method, moved/resized through the TracksBoard.Move method, refreshed through the TracksBoard.Refresh method and shown/hidden through the TracksBoard.Show method.
A specific instance of the API can create one single TracksBoard only.
The possibility to load sound or video files into the player linked to the TracksBoard is disabled while the TracksBoard window is instanced: the TracksBoard window needs to be destroyed through the TracksBoard.Destroy method in order to enable again methods like LoadSound, LoadSoundFromRawFile and any other method whose task is to load a file or a playlist into the linked player. Other eventual players instanced by the control will work normally.
Differently from the WaveformAnalyzer class, the TracksBoard is based upon the concept of "tracks" instead of "audio channels". The aforementioned TracksBoard.Create method will automatically create a new "session" with an initial number of tracks: this number can be incremented through the TracksBoard.TrackAdd method and decremented through the TracksBoard.TrackRemove method: it's important to note that a track can be only removed when empty and not when still containing one or more items.
The concept of audio channels is in any case still available, indeed each item added to the session can be assigned to a specific speaker and this will become effective when the mixing will occur, before starting playback through the PlaySound method or before starting the exporting to file phase through the TracksBoard.ExportToFile method. The total number of speakers managed by the session can be set through the TracksBoard.SpeakersNumSet method.
During a playback session started through the PlaySound method, the vertical line named play head line shows the current playback position: this line can be moved through the mouse by clicking a position outside of existing items; the position of the play head line can be also modified programmatically through the TracksBoard.PlayHeadPositionSet method and the current playback position can be retrieved through the TracksBoard.PlayHeadPositionGet method.
Modifications to the session performed through the mouse, like moving an item or changing the position/amplitude of a volume point, are disabled during playback.
The current duration of the session can be obtained through the TracksBoard.CurrentDurationGet method; once a session is no more needed it can be discarded from memory through the TracksBoard.FreeMemory method.
Other operations available for tracks added to the session are the following:
|•||TracksBoard.TracksCountGet enumerated existing tracks|
|•||TracksBoard.TrackLockStateSet locks all of the items added to the track, disallowing the possibility to move them through the mouse|
|•||TracksBoard.TrackMuteStateSet changes the mute state of the track: when muted, all of the items of the track will not be added to the final mix|
|•||TracksBoard.TrackDurationGet obtains the current duration the track|
On the screenshot below you can see an example of session with 4 tracks, each containing one or more "Items". On the final mix, each item can be rendered on a different audio channel.
All of the items can be selected or dragged through the mouse by holding down the left mouse button: items cannot overlap on the same track so, if you should need to have more items on the same timeline, each of them should be placed on a different track.
Important note about items overlapping
Overlapping of two items on the same track is now allowed so, in case of overlapping during a mouse drag and upon space availability, the item will be automatically moved to the next track or to the previous track; if both previous and next tracks should in any case suffer an overlapping, a new track will be automatically inserted on the nearest position.
As seen on the screenshot above, the Tracksboard user interface is made up of a window containing a set of different entities:
|•||Various tracks, each containing the waveform representation of one or more items; if enabled, each item can have a title text positioned on top or bottom of the waveform|
|•||Scrollbars positioned on top and bottom of the main window (inside the screenshot above the bottom scrollbar is hidden)|
|•||Horizontal time rulers placed between scrollbars and tracks|
|•||Vertical amplitude rulers placed on the left an on the right of the window (inside the screenshot above the right ruler is hidden)|
Settings of each of the entities described above can be customized through the following set of data structures:
|•||The TRACKSBOARD_GENERAL_SETTINGS data structure, that describes the window general settings, can be obtained through the TracksBoard.SettingsGeneralGet method and modified through the TracksBoard.SettingsGeneralSet method|
|•||The TRACKSBOARD_SCROLLBARS_SETTINGS data structure, that describes settings applied to scrollbars, can be obtained through the TracksBoard.SettingsScrollbarsGet method and modified through the TracksBoard.SettingsScrollbarsSet method|
|•||The TRACKSBOARD_RULERS_SETTINGS data structure, that describes settings applied to amplitude rulers and time rulers, can be obtained through the TracksBoard.SettingsRulersGet method and modified through the TracksBoard.SettingsRulersSet method|
|•||The TRACKSBOARD_ITEM_SETTINGS data structure, that describes settings used to render each item added to the session (apart from the waveform rendering), can be obtained through the TracksBoard.SettingsItemGet method and modified through the TracksBoard.SettingsItemSet method|
|•||The TRACKSBOARD_WAVEFORM_SETTINGS data structure, that describes settings used to render the waveform of each item, can be obtained through the TracksBoard.SettingsWaveGet method and modified through the TracksBoard.SettingsWaveSet method|
Zoom operations are supported programmatically through the TracksBoard.ZoomIn, TracksBoard.ZoomOut and TracksBoard.ZoomToFullSound methods or through the mouse by moving the scrollbars handles. In case you should need to display a specific range of the session, the TracksBoard.DisplayRangeSet would be the way to go. Once zoomed, the visible range of the session can be scrolled programmatically through the TracksBoard.Scroll method or through the mouse by moving the scrollbars thumbs; the zoom-in capability is limited to the number of peaks available for rendering the waveform of items added to the session so, when using the horizontal scrollbar, the zoom-in operation is automatically interrupted when there are not enough peaks to proceed further.
After a zoom or scroll operation the current displayed range can be obtained through the TracksBoard.DisplayRangeGet method.
When an item is selected through the mouse, it immediately appears surrounded by a tracker of a different color and a dotted rectangle extended to time rulers is displayed; further elements become visible; most of these elements can be dragged through the mouse:
|•||Resize handles, positioned on the left and right sides of the waveform, allow reducing or enlarging the portion of sound by keeping the left mouse button pressed|
|•||The amplitude line can be moved in order to attenuate or amplify the general volume by keeping the left mouse button pressed|
|•||Volume points can be added in order to define a better volume granularity|
|•||A single volume point can be selected through a mouse click and then dragged by keeping the left mouse button pressed|
|•||The volume line connects all of the available volume points: this line cannot be moved through the mouse|
As mentioned at the beginning of this tutorial, the following kind of items can be added to the session:
|•||Sound files stored inside disk files through the TracksBoard.ItemSoundFileAdd and TracksBoard.ItemSoundFileRawAdd methods|
|•||Sound files pasted from the clipboard into the session through the TracksBoard.ItemSoundFileFromClipboardPaste method|
|•||Sound files added to the session through a mouse drag & drop operation from Windows Explorer|
|•||Text to speech audio generated by the Microsoft Speech API through the TracksBoard.ItemSpeechFromFileAdd and TracksBoard.ItemSpeechFromStringAdd methods|
In all cases, items added to the session will be identified by a unique identification number created by aforementioned methods. Once added, several modifications can be applied to each item through the following method:
|•||TracksBoard.ItemsCountGet enumerates available items and TracksBoard.ItemUniqueIdGet obtains the unique identification number for each of them; in case you should already know you know the unique identification number, the TracksBoard.ItemIndexGet method allows to obtain the zero-based index within the list of session items|
|•||TracksBoard.ItemTypeGet obtains the type of item which could be a regular sound file, a raw sound file or the result of a text to speech|
|•||TracksBoard.ItemFriendlyNameSet modifies the friendly name while TracksBoard.ItemFriendlyNameGet obtains the current one|
|•||TracksBoard.ItemRemove removes an item from the session|
|•||TracksBoard.ItemClone clones an item of a given amount|
|•||TracksBoard.ItemAttachToNext moves the position of the given item in order to attach it to the next one on the same track|
|•||TracksBoard.ItemAttachToPrevious moves the position of the given item in order to attach it to the previous one on the same track or, in case no other item should be available, moves the item to the beginning of the track|
|•||TracksBoard.ItemAttachAllInTrack attaches al of the items available inside a given track|
|•||TracksBoard.ItemSplit splits the item at the given position and creates a new attached item|
|•||TracksBoard.ItemTrackSet changes the track on which the item is placed and TracksBoard.ItemTrackGet allows to obtain the current track|
|•||TracksBoard.ItemSelect selects an existing item and the TracksBoard.ItemSelectedGet method returns the currently selected item, if any|
|•||TracksBoard.ItemOffsetSet modifies the offset of the item respect to the beginning of the session and TracksBoard.ItemOffsetGet allows to obtain the current offset|
|•||TracksBoard.ItemOffsetMove moves the current offset of the item(s) backward or forward of a given amount|
|•||TracksBoard.ItemDurationStretch stretches the duration of the item by modifying its "tempo"|
|•||TracksBoard.ItemDurationGet obtains the duration of the item|
|•||TracksBoard.ItemSpeakerSet changes the speaker on which the item will be reproduced and TracksBoard.ItemSpeakerSet obtains the current speaker|
|•||TracksBoard.ItemLockStateSet changes the lock state of the item and TracksBoard.ItemLockStateGet obtains the current lock state|
|•||TracksBoard.ItemPositionLockStateSet changes the lock state of the item's position and TracksBoard.ItemPositionLockStateGet obtains the current lock state|
|•||TracksBoard.ItemMuteStateSet changes the mute state of the item and TracksBoard.ItemMuteStateGet obtains the current mute state|
|•||In case of items generated through text to speech, TracksBoard.ItemSpeechVoiceSet changes the speaking voice and TracksBoard.ItemSpeechVoiceGet obtains the current voice|
|•||TracksBoard.ItemWaveColorsSet allows modifying some of the default colors set into the TRACKSBOARD_WAVEFORM_SETTINGS and TRACKSBOARD_ITEM_SETTINGS data structures; modified colors can be obtained through the TracksBoard.ItemWaveColorsGet method|
Operations below can be optionally delayed in order to save some CPU and avoid too many refreshes of the waveform when invoked in sequence: in this case they will become effective after invoking the TracksBoard.ItemCompose method:
|•||TracksBoard.ItemSoundFileLoadRangeSet modifes the range of the original sound currently added to the session and TracksBoard.ItemSoundFileLoadRangeGet allows to obtain the current range; the range can be also modified through the mouse by selecting the item and then by moving one of its lateral resize handles: the change through the mouse is disabled when the item duration has been stretched through the TracksBoard.ItemDurationStretch method|
|•||TracksBoard.ItemAmplitudeSet modifies the amplification/attenuation applied to the item and TracksBoard.ItemAmplitudeGet obtains the current amplitude|
|•||TracksBoard.ItemVolumeFadingSet modifies a volume fade-in or fade-out at the beginning or at the end of the item; eventual current fade operations can be obtained through the TracksBoard.ItemVolumeFadingGet and removed through the TracksBoard.ItemVolumeFadingRemove|
|•||TracksBoard.ItemVolumeFadingRemove removes a fade-in or a fade-out previously set through the TracksBoard.ItemVolumeFadingSet method|
A certain amount of methods is dedicated to volume points management:
|•||TracksBoard.ItemVolumePointAdd adds a new volume point to a specific offset within the given item: this offset can be modified through the TracksBoard.ItemVolumePointPositionSet method: adding new volume points is disabled when the item duration has been stretched through the TracksBoard.ItemDurationStretch method|
|•||TracksBoard.ItemVolumePointRemove removes the given volume point|
should be set to "BOOL_FALSE", they could be invoked together and not immediately applied, allowing to save some CPU: in this case the TracksBoard.ItemVolumePointsApply method could apply their settings all at once.
|•||TracksBoard.ItemVolumePointAmplitudeSet modifies the amplitude of a specific volume point and the current amplitude can be obtained through the TracksBoard.ItemVolumePointAmplitudeGet method|
|•||TracksBoard.ItemVolumePointPositionSet modifies the position of a specific volume point and the current position can be obtained through the TracksBoard.ItemVolumePointPositionGet method|
|•||TracksBoard.ItemVolumePointCurveSet and TracksBoard.ItemVolumePointCurveSetEx modify the volume curve applied on exit from the given volume point to reach the volume of the next volume point and the current volume curve can be obtained through the TracksBoard.ItemVolumePointCurveGet method|
Methods listed above come with a bAutoRefresh parameter which allows deciding if the modification should be applied immediately or applied later when one of these methods should be invoked with the the bAutoRefresh parameter set to "BOOL_TRUE" or through a call to the TracksBoard.ItemVolumePointsApply method.
Existing volume points can be enumerated through the TracksBoard.ItemVolumePointCountGet method; in case one of the volume points should have been selected through the mouse, it could be obtained through the TracksBoard.ItemVolumePointSelectedGet method.
Each volume point can have its own friendly name originally assigned by the method: the current friendly name can be obtained through the TracksBoard.ItemVolumePointFriendlyNameGet and modified through the TracksBoard.ItemVolumePointFriendlyNameSet method.
As mentioned above, the TracksBoard.ItemVolumePointRemove method removes a specific volume point: in case the duration of the item should be modified by dragging one of its resize handles or through a call to the TracksBoard.ItemSoundFileLoadRangeSet method, volume points falling outside of the visible range of the item would be automatically removed.
Another set of methods is dedicated to management of vertical lines, which may be used as a sort of bookmarks, added through the TracksBoard.VerticalLineAdd method; on the screenshot below you can see a session with some vertical line, each having its own colors, setting and positioning:
For each of these vertical lines you can define a friendly name, a description, the exact position expressed in milliseconds, the colors used for being drawn and some more specific parameter.
The TracksBoard.VerticalLineAdd method returns a unique identification number that will be used by other methods to access settings of each vertical line at a later time; for example you may want to:
|•||obtain or change the friendly name through the TracksBoard.VerticalLineNameGet and TracksBoard.VerticalLineNameSet methods|
|•||obtain or change the description through the TracksBoard.VerticalLineDescriptionGet and TracksBoard.VerticalLineDescriptionSet methods|
|•||obtain or change the current settings of each single line through the TracksBoard.VerticalLineParamsGet and TracksBoard.VerticalLineParamsSet methods|
|•||obtain or change the current position through the TracksBoard.VerticalLinePositionGet and TracksBoard.VerticalLinePositionSet methods|
|•||change the visibility through the TracksBoard.VerticalLinesShow method|
|•||remove existing lines through the TracksBoard.VerticalLineRemove method|
Enumeration of existing vertical lines can be done using the TracksBoard.VerticalLinesCountGet method, the unique identification number of each vertical line can be obtained through the TracksBoard.VerticalLineUniqueIdGet method
The possibility to perform specific operations by clicking a button available on the user interface can be sometime faster than going through a regular menu; the component allows to add a few of these buttons, named "Control icons": each control icon can have two bitmaps representing two different situations.
Control icons can be added through one of the following methods:
|•||the TracksBoard.ControlIconAdd method takes its bitmaps from two bitmap handles (HBITMAP)|
|•||the TracksBoard.ControlIconAddFromFile method takes its bitmaps from two graphic files|
|•||the TracksBoard.ControlIconAddFromMemory takes its bitmaps from two memory buffers filled with graphic files data|
Once added, each control icon is immediately positioned on the left amplitude vertical ruler for each of the available tracks; for this reason the bVisibleLeft field of the TRACKSBOARD_RULERS_SETTINGS data structure must be set to "true".
The size of control icons is automatically resized to fit the space available from the left edge of the TracksBoard window to the text used to render amplitudes.
On the screenshot below, taken from the TracksBoard sample project available with the installer, two control icons are added, one providing the possibility to mute / unmute the track and the other one providing the possibility to lock / unlock the track; by default each track is in "unmute" status and in "unlock" status (status 1); when in status 1 the tooltip text represents what will happen after clicking the control icon with the mouse: once clicked, the bitmap will show the "mute" status (status 2) and the tooltip text will show that, by clicking the control again, the track will be brought back to the "unmute" status (status 1).
This is obviously a simple usage of control icons, you may decide to use these control icons for any purpose you may have.
The vertical and horizontal alignment of control icons can be modified through the TracksBoard.ControlIconsAlignmentSet method.
A set of callback delegates is provided for keeping the container application up to date respect to operations happening on the user interface of the TracksBoard:
|•||the CallbackTracksboardRange delegate, set through the CallbackTracksboardRangeSet method, reports that the session range displayed on the window has been modified, usually after a zoom operation|
|•||the CallbackTracksboardWidth delegate,set through the CallbackTracksboardWidthSet method, reports that the width of the user interface has been resized horizontally, usually after a call to the TracksBoard.Move method.|
|•||the CallbackTracksBoardMouseNotif delegate, set through the CallbackTracksBoardMouseNotifSet method, reports the exact position where the mouse was pressed on the waveform: accurate positioning is guaranteed also when the waveform is zoomed.|
|•||the CallbackTracksboardPlayHeadPos delegate, set through the CallbackTracksboardPlayHeadPosSet method, reports that the position of the play head line has changed after the click of the left button of the mouse on the user interface|
|•||the CallbackTracksboardPaintDone delegate, set through the CallbackTracksboardPaintDoneSet method, reports that the rendering of the user interface is completed, allowing to add eventual custom graphic elements directly from the container application's code|
|•||the CallbackTracksboardControl delegate, set through the CallbackTracksboardControlSet method, reports that one of the control icons has been pressed on a specific track|
A further set of events is dedicated to operations performed directly on items available inside the session:
|•||the CallbackTracksboardItemClicked delegate, set through the CallbackTracksboardItemClickedSet method, reports that a mouse button was clicked on a specific item|
|•||the CallbackTracksboardItemDblClicked delegate, set through the CallbackTracksboardItemDblClickedSet method, reports that a mouse button was double-clicked on a specific item|
|•||the CallbackTracksboardItemSelected delegate, set through the CallbackTracksboardItemSelectedSet method, reports that a specific item has been selected|
|•||the CallbackTracksboardItemMoved delegate, set through the CallbackTracksboardItemMovedSet method, reports that the move operation of a specific item is occurring|
|•||the CallbackTracksboardItemVolumeChanged delegate, set through the CallbackTracksboardItemVolumeChangedSet method, reports that a volume change was applied to the item, for example when the position of a volume point is modified or the vertical position of the amplitude line has been changed|
|•||the CallbackTracksboardLineReached delegate, set through the CallbackTracksboardLineReachedSet method, reports that a specific vertical lines has been moved through the mouse|
|•||the CallbackTracksboardLineMoved delegate, set through the CallbackTracksboardLineMovedSet method, reports that the position of a specific vertical lines has been reached during playback of the session|
A sample of usage of the TracksBoard class in Visual Basic.NET and Visual C# can be found inside the following sample installed with the product's setup package: