Copyright © 2001-2011 MultiMedia Soft

How to obtain the sound's waveform

Previous pageReturn to chapter overviewNext page

After loading a sound inside a player, through the use of LoadSound, LoadSoundFromMemory or LoadTrackFromCd methods, the Waveform object allows generating a bitmap of the sound's waveform: this bitmap can represent the sound in its full length or, in alternative, one or more portions (also known as "views") of the same sound.

 

In order to generate one or more bitmaps of the loaded sound, the control needs to analyse the sound's contents: this task is performed through a call to the Waveform.AnalyzeFullSound method. The analysis can be more or less accurate depending upon the resolution passed to the nResolution parameter; higher resolutions will allow a better quality because more peaks will be detected: as a side effect, higher resolutions will require more memory and will generate larger bitmaps. The analysis can be aborted at any time through a call to the Waveform.AnalyzeAbort method.

 

After calling this method, the control will allow the container application to stay up-to-date about the analysis advancement through the following events:

 

WaveAnalysisStart: fired when the sound's analysis begins.
WaveAnalysisPerc: fired several times during the analysis in order to inform the container application about the percentage of advancement.
WaveAnalysisDone: fired when the sound's analysis is completed: after catching this event, it will be possible requesting to the control the creation of the waveform's bitmap through a call to the Waveform.BitmapViewSaveToFile or Waveform.BitmapViewSaveTomemory methods. It's important to note that this event will report the exact number of peaks detected inside the loaded sound and the exact duration in milliseconds of each peak. When generating the bitmap for the full sound's waveform, the reported number of peaks will be exactly equal to the width in pixels of the bitmap. In case you should create a view of a given sound's range, you could obtain the number of pixels needed to display the waveform's view through a call to the Waveform.BitmapViewGetWidth method.

 

After having analyzed a certain song, in order to save CPU time when you will load and analyze again the same song, you have the possibility to store analyzed waveform's peaks into a file using the Waveform.PeaksSave method and to retrieve them at a later time using the Waveform.PeaksLoad method: WaveAnalysisStart and WaveAnalysisDone events will be generated in this case also.

 

The generated waveform's bitmap will be represented using the Waveform.ColorLine and Waveform.ColorBackground colors.

 

Below you can see five bitmaps generated using the same sound (whose duration is around 2.4 seconds length) but with five different resolutions (just for your information the song used for generating these bitmaps is available on this link); all these bitmaps have been created using the same height of 100 pixels:

 

Resolution passed to AnalyzeFullSound method

Generated bitmap

 

 

WAVEFORM_RES_MAXIMUM

amp3dj_i00005f

WAVEFORM_RES_VERY_HIGH

amp3dj_i000060

WAVEFORM_RES_HIGH

amp3dj_i000061

WAVEFORM_RES_MIDDLE

amp3dj_i000062

WAVEFORM_RES_LOW

amp3dj_i000063

 

 

As mentioned before, you can also generate a "view" of a defined portion of the loaded sound: on the bitmap below you can see the original song in its full length (with WAVEFORM_RES_MAXIMUM resolution)

 

amp3dj_i00005f

 

and below you can see the view of the same song for the range between 500 and 1500 milliseconds

 

amp3dj_i000064

 

 

On the samples above we have used a very small song limited to 2.4 seconds: in case you should be in need of displaying the full waveform of a longer song on a space much smaller than the total number of required pixels, the Waveform.BitmapViewSaveToFile and Waveform.BitmapViewSaveToMemory methods will shrink the waveform in order to fit exactly inside the available space; in the example below you can see a 3 minutes song fitting inside a 455 pixels wide bitmap: the original full length bitmap, using the WAVEFORM_RES_MAXIMUM resolution, would require a width of 243,683 pixels.

 

amp3dj_i000065

 

VERY IMPORTANT: When using high resolutions and big sound files, keep count that the Windows operating system has limits on the size of bitmaps creation; this means that it would be better avoiding the creation of very large bitmaps: in this case it would be a better approach splitting the total song's bitmap into several smaller bitmaps, for example creating bitmaps whose width in pixels doesn't exceed the current screen width.

 

 

When dealing with video clips, after having loaded the video clip into a certain player, you can extract its audio track through the VideoPlayer.AudioTrackExtract method and, after completing the extraction, you can proceed to the sound waveform analysis as described for regular sound files.

 

Samples of waveform management in Visual C++ 6 and Visual Basic 6 can be found inside the following samples installed with the product's setup package:

- BeatsDetection

- Waveform

 

 

 

After catching the WaveAnalysisDone event, it will be also possible rendering the waveform directly inside a graphical device context (through its handle or HDC); this is quite useful if you need to perform real-time rendering of the waveform on the screen for example for creating a scrolling waveform during playback.

 

In case you should create a view of a given sound's range, you could obtain the number of pixels needed to display the waveform's view through a call to the Waveform.BitmapViewGetWidth method.

 

The generated waveform's bitmap will be rendered using colors set into the Waveform.ColorLine and Waveform.ColorBackground properties..

 

The rendering of the needed portion of sound can be performed through a call to the Waveform.BitmapViewDrawToHdc method. Positions determining the visible sound range can assume negative values for start and values higher respect to the effective sound duration: This allows displaying the current playback position on the center of the device context.

 

On the screenshots below you can see two portions of the same sound; in the first case the vertical white line (rendered through custom GDI+ inside the container applications' code) represents the position 0 ms of the song ranging from -5000 ms to +5000 ms; as you can see, the negative portion on the left, where no sound exists, is rendered as absence of audible sound.

 

 

In this seconds case the vertical white line represents the position 5000 ms of the song ranging from 0 ms to +10000 ms

 

 

 

As a further feature, vertical lines can be added/removed at specific positions through the Waveform.BitmapViewVerticalLineAdd and Waveform.BitmapViewVerticalLineRemove methods. Below an example of two vertical lines, rendered in red color, when the current center position of the bitmap view is set to 5000 ms.

 

 

Below the same exact red lines when the current center position has been moved to 6000 ms.

 

 

As you may understand, all of the features described above could be used to perform a custom rendering of a scrolling waveform during playback: what you would have to do would be:

 

define a range to display, for example 10 seconds (10000 ms)
set a timer object, initially disabled, with a tick raised every 15 ms
inside the timer tick function:
request the current playback position through the GetCurrentPos method
determine the rendering start position by subtracting 5000 ms to the current playback position and store it inside a variable named (for example) nStart
determine the rendering end position by adding 5000 ms to the current playback position and store it inside a variable named nEnd
call the Waveform.BitmapViewDrawToHdc method and set its nStartPos parameter to nStart and its nEndPos parameter to nEnd
after performing the sound analysis and catching the WaveAnalysisDone event you may enable the timer: the visible effect will be the waveform representation scrolling from right to left on the screen.

 

An example of usage of the solution described above can be seen inside the DjStudioDemo sample.

 

 

 

For further details about using the embedded Waveform refer to the Waveform object section.

For details about using Visual Feedbacks refer to the How to use the embedded Visual Feedbacks section.