How to decode media files |
|
There could be situations in which the container application needs to gain access to uncompressed PCM sound data of a media file in order to perform some specific task: for this purpose the MediaFileDecoder COM object exposes a set of methods which ease this specific task.
The first mandatory step is to initialize the decoder through the MediaFileDecoder.Initialize method: after this operation you can start decoding single media files, where the term "media file" applies to both audio and video clips, through the MediaFileDecoder.FileOpen method or, for RAW audio files, through the MediaFileDecoder.FileOpenRaw method.
Once the file has been decoded, you can know its duration in milliseconds through the MediaFileDecoder.FileDurationGet method and you can start obtaining uncompressed PCM samples; the total uncompressed size in bytes of the decoded audio track can be obtained through the MediaFileDecoder.FileLengthGet method while the size of a specific portion of the decoded audio track can be obtained through the MediaFileDecoder.FileChunkLengthGet method.
Due to the fact that uncompressed PCM samples of audio tracks may require huge sized buffers for storage, you have the possibility to read smaller portions of the uncompressed samples through the MediaFileDecoder.FileDataGet method: this method receives in input a buffer of a predetermined length which be filled accordingly with the decoded PCM samples: each call to this method will automatically increment the position internal to the decoded audio track allowing to read the full audio track without the need to reposition the reader; in most cases the buffer will be smaller respect to the total size of the decoded audio track, so you will have to perform an adequate number of calls to this method, usually inside a loop, in order to scan the entire audio track.
Let's see a couple of small pieces of code (please, note that for simplicity the code below misses error checking):
Visual Basic 6 |
' create the decode stream Amp3dj1.MediaFileDecoder.FileOpen "c:\myfile.mp3"
' allocate the buffer that will receive uncompressed samples Dim buffer(20000) As Byte
' get the total length of the uncompressed audio track: we will use it for determining the current percentage Dim nFileLength As Long Amp3dj1.MediaFileDecoder.FileLengthGet nFileLength
Dim nBytesRead As Long nBytesRead = -1 Dim nTotalBytesRead As Currency nTotalBytesRead = 0
' loop until the MediaFileDecoder.FileDataGet method find some byte Do While nBytesRead <> 0 ' get samples from the decode stream and put them in buffer Amp3dj1.MediaFileDecoder.FileDataGet VarPtr(buffer(0)), 20000, DATA_TYPE_NATIVE, nBytesRead
' do something with the returned buffer [ ... ]
' calculate the current percentage of advancement: may be useful to drive a progress bar nTotalBytesRead = nTotalBytesRead + nBytesRead Dim nPercentage As Long nPercentage = CLng((nTotalBytesRead * 100) / nFileLength)
' in case you want to stop/exit... DoEvents Loop
|
Visual C++ |
// create the decode stream Amp3dj1.GetMediaFileDecoder().FileOpen("c:\\myfile.mp3");
// allocate the buffer that will receive uncompressed samples VARIANT buffer; VariantInit(&buffer); buffer.vt = VT_BYREF | VT_UI1; buffer.pbVal = (BYTE*) malloc (20000);
// get the total length of the uncompressed audio track: we will use it for determining the current percentage long nFileLength32; Amp3dj1.GetMediaFileDecoder().FileLengthGet (&nFileLength32);
__int64 nFileLength = nFileLength32; __int64 nTotalBytesRead = 0; long nBytesRead = 0;
// loop until the MediaFileDecoder.FileDataGet method find some byte do { // get samples from the decode stream and put them in buffer Amp3dj1.GetMediaFileDecoder().FileDataGet (buffer, 20000, DATA_TYPE_NATIVE, &nBytesRead);
// do something with the returned buffer [ ... ]
// calculate the current percentage of advancement: may be useful to drive a progress bar nTotalBytesRead += nBytesRead; long nPercentage = long ((nTotalBytesRead * 100) / nFileLength);
// in case you want to stop/exit... theApp.YieldControl (); } while (nBytesRead != 0);
free (buffer.pbVal);
|
In the code above we have seen how to read the uncompressed PCM samples for the entire media file: there may be situations in which you could need to read only a smaller portion of the media file; in this case you can know how many bytes should be read for a specific portion of the audio track through the MediaFileDecoder.FileChunkLengthGet method and to set the initial position where the reading will start within the media file through the MediaFileDecoder.FilePositionSet method; the code above could be then adapted to check how many bytes have been read in order to exit the loop when the length in bytes returned by the MediaFileDecoder.FileChunkLengthGet method is reached.
After the decoding of the audio track, you may obtain its sample rate and number of channels through the MediaFileDecoder.FileInfoGet method: this method will also return the bit depth (also known as "encode mode") of the decoded samples.
Once the decoded stream is no more needed, you can discard it from memory and free its resources by calling the MediaFileDecoder.FileClose method.