[prev in list] [next in list] [prev in thread] [next in thread] 

List:       swiff-info
Subject:    [swiff-info] Re: mp3 streaming tags
From:       "Mark Zartler" <mzartler>
Date:       1999-10-19 14:44:05
[Download RAW message or body]

The mixer format tells the format that the audio device (waveOut, or
SndChannel) should be opened with.
Most computers support 8 bit or 16 bit, 11K - 44K mono or stereo.  It
specifies what sound format to use for playback. The first "mixer format"
like structure says the same thing, but it applies to the streaming audio,
ie. which format is it... They can be different and SWF will handle the
mixing (although poorly).

Hope this helps.


-----Original Message-----
From: David Michie <david_michie>
To: swiff-info@egroups.com <swiff-info@egroups.com>
Date: Tuesday, October 19, 1999 5:55 AM
Subject: [swiff-info] Re: mp3 streaming tags


>Hi Mark,
>
>I'm attempting to document SWF sound at the moment, so
>your contributions are timely.
>
>First, a dumb question about SoundStreamHead and
>SoundStreamHead2.  What does StreamSoundMixFormat do?
>The comment of "Recommended mixer format" is not
>exactly helpful.
>
>More dumb questions to follow...
>
>Thanks, David.
>
>
>--- Mark Zartler <mzartler> wrote:
>> It seems I've solved or worked around the
>> difficulties with streaming mp3's.
>>
>> I'm now successfully writing flash for files with
>> streaming mp3's.  Per David's request, I thought I'd
>> take a few moments to explain and what I found for
>> those who care, There are still some areas of
>> uncertainty which I will make note of. Regardless,
>> it seems to play back without issue. I have also
>> included some rather long-winded source code for
>> reading mp3 files for the purpose of adding mp3
>> frame blocks to a higher level streaming application
>> (in this case, flash). It adds to the message size,
>> but hopefully some of you may find it useful in the
>> future. I also include links to mp3 programming
>> resources for those who need more information or
>> example programs.
>> ---
>> To begin streaming, we need to write out a
>> StreamSoundHead2, which looks something like this
>> StreamSoundHead2 start tag
>> [MixerFormat1-Playback]
>>     4 bits    -    0        -- signifies non
>> compressed playback --
>>     2 bits     [0,1,2, 3] - signifies the sample
>> rate [5k,11k,22k,44k] respectively
>>     1 bit      [0,1]         - 0 -> 8 bit samples
>> 1-> 16 bit samples
>>     1 bit     [0,1]         - mono or stereo
>>
>> [MixerFormat2-Data format]
>>     4 bits    -   [0, 1, 2]        -- 0 -> non
>> compressed data -- 1 -> ADPCM 2 -> mp3
>>     2 bits     [0,1,2, 3] - signifies the sample
>> rate [5k,11k,22k,44k] respectively
>>     1 bit      [0,1]         - 0 -> 8 bit samples
>> 1-> 16 bit samples
>>     1 bit     [0,1]         - mono or stereo
>>
>> Number of samples (???)  Any value seems to work so
>> I'm not sure exactly how to intepret it.
>> I write the number for a given frame. Thus a frame
>> oriented sample rate.  I'd be interested in learning
>> the exact meaning for adpcm,mp3, but things seem to
>> work ...
>>
>> Thats it for the stream head.
>> A stream block for mp3 looks like this:
>> PutTag (stagSoundStreamBlock);
>> 32 bits  -  number of PCM samples (decoded) samples
>> in the this stream block). This is slightly
>> different from the output from flash four. They have
>> *something* encoded in the high order word. Mine is
>> zero, but it still plays.
>> Following this, is zero or more full mp3 encoded
>> frames.
>> In order to add mp3 to a flash movie, some knowledge
>> of the mp3 (specifically the frame header and
>> calculating the frame sizes) is essential.
>> I would recommend http://www.mp3tech.org for code
>> examples (some are very good) of encoding and
>> decoding mp3's.  I use netshow (ACM) to do my
>> encoding and then read the mp3 frames using the
>> snippet that follows.
>>
>> here is some code I've adapted for the purpose of
>> reading full frames from an mp3 file:
>> Two functions will be of use on a high level: First,
>> ReadMp3Frame will iterate all the frames
>> in an mp3 file. Second, GetMp3FrameSize will return
>> the size of an encoded frame, and the number of
>> samples in the decoded frame. You'll need this to
>> write out the 4 byte 'header' of an mp3 streamblock,
>> and the encoded size will help you figure out how to
>> best slice it to into streaming blocks:
>>
>> /* mp3 reading tables */
>> int vertab[4]={2,3,1,0};
>> int freqtab[4]={44100,48000,32000};
>> int ratetab[2][3][16]=
>> {
>>   {
>>     {  0, 32, 64,
>> 96,128,160,192,224,256,288,320,352,384,416,448,  0},
>>     {  0, 32, 48, 56, 64, 80,
>> 96,112,128,160,192,224,256,320,384,  0},
>>     {  0, 32, 40, 48, 56, 64, 80,
>> 96,112,128,160,192,224,256,320,  0},
>>   },
>>   {
>>     {  0, 32, 48, 56, 64, 80,
>> 96,112,128,144,160,176,192,224,256,  0},
>>     {  0,  8, 16, 24, 32, 40, 48, 56, 64, 80,
>> 96,112,128,144,160,  0},
>>     {  0,  8, 16, 24, 32, 40, 48, 56, 64, 80,
>> 96,112,128,144,160,  0},
>>   },
>> };
>>
>> BOOL CSWFSndUtil::SeekToNextValidHeader (
>> // Find the next valid header in the given file.
>> HMMIO hFile,
>> int &layer,
>> int &ver,
>> int &freq,
>> int &stereo,
>> int &rate)
>> {
>>     unsigned char hdr[4];
>>     long          nFileEnd, nCurPos = ::mmioSeek
>> (hFile, 0, SEEK_CUR);
>>     BOOL          bFound = FALSE;
>>     LONG          nRead;
>>     if (nCurPos == -1) return (FALSE);
>>     nFileEnd = ::mmioSeek (hFile, 0, SEEK_END);
>>
>>     /* what a mess */
>>     while (!bFound && nCurPos + 3 < nFileEnd)
>>     {
>>         ::mmioSeek (hFile, nCurPos, SEEK_SET);
>>         nRead = ::mmioRead (hFile, (char*)hdr,
>> sizeof (hdr));
>>         if (nRead != sizeof (hdr))
>>             return (FALSE);
>>         ver=vertab[((hdr[1]>>3)&3)];
>>         layer=3-((hdr[1]>>1)&3);
>>         int pad=(hdr[2]>>1)&1;
>>         stereo=((hdr[3]>>6)&3)!=3;
>>         if (hdr[0]!=0xFF || hdr [1] < 0xE0 || ver==3
>> || layer != 2)
>>         {   // not a header
>>             nCurPos++;
>>         }
>>         else
>>         {
>>             freq=freqtab[(hdr[2]>>2)&3]>>ver;
>>
>> rate=ratetab[ver?1:0][layer][(hdr[2]>>4)&15]*1000;
>>             if (!freq || !rate)
>>             {
>>                 nCurPos++;
>>             }
>>             else
>>

>>                 mmioSeek (hFile, nCurPos, SEEK_SET);
>>                 bFound = TRUE;
>>             }
>>         }
>>     }
>>     return (bFound);
>> }
>>
>>
>> SWFRESULT CSWFSndUtil::ReadMp3Frame (HMMIO hFile,
>> char *lpData, long *pnSize)
>> {
>>     int   nFrameSize = 0;
>>     long  lResult = 0;
>>     if (!hFile) return (WAVEERR_INVALIDFILE);
>>     int layer1, ver1, freq1, stereo1, rate1;
>>    *pnSize = 0;
>>     if (SeekToNextValidHeader (hFile, layer1, ver1,
>> freq1, stereo1, rate1))
>>     {
>>         nFrameSize = ((ver1?72:144)*rate1)/freq1;
>>         LONG nRead = mmioRead (hFile, lpData,
>> nFrameSize);
>>         // clear the padding bit
>>         if (nRead == nFrameSize)
>>         {
>>             if (lpData [2] & 2) // pad bit!
>>

>>                 nRead += mmioRead (hFile, &lpData
>> [nFrameSize], 1);
>>             }
>>             lResult = 0;
>>            *pnSize = nRead;
>>         }
>>     }
>>     return (lResult);
>> }
>>
>>
>>
>> SWFRESULT CSWFSndUtil::GetMp3FrameSize (char
>> *szMp3File, long *pnFrameSize, long *pnPCMFrameSize)
>> {
>>     HMMIO hFile = mmioOpen (szMp3File, NULL,
>> MMIO_READ);
>>     int layer, ver, freq, stereo, rate;
>>     *pnFrameSize = 0;
>>     if (!hFile) return (WAVEERR_INVALIDFILE);
>>     if (!SeekToNextValidHeader (hFile, layer, ver,
>> freq, stereo, rate))
>>     {
>>         return (WAVEERR_INVALIDFILE);
>>     }
>>     *pnFrameSize = ((ver?72:144)*rate)/freq;
>>     *pnPCMFrameSize = (576 * (stereo + 1));
>>     if (!ver)
>>       *pnPCMFrameSize *= 2;
>>
>=== message truncated ===
>
>
>=====
>
>__________________________________________________
>Do You Yahoo!?
>Bid and sell for free at http://auctions.yahoo.com
>
>------------------------------------------------------------------------
>
>eGroups.com home: http://www.egroups.com/group/swiff-info
>http://www.egroups.com - Simplifying group communications
>
>
>
>

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic