FLACStream.cpp

Go to the documentation of this file.
00001 //===========================================================================
00002 //Copyright (C) 2003, 2004 Zentaro Kavanagh
00003 //
00004 //Redistribution and use in source and binary forms, with or without
00005 //modification, are permitted provided that the following conditions
00006 //are met:
00007 //
00008 //- Redistributions of source code must retain the above copyright
00009 //  notice, this list of conditions and the following disclaimer.
00010 //
00011 //- Redistributions in binary form must reproduce the above copyright
00012 //  notice, this list of conditions and the following disclaimer in the
00013 //  documentation and/or other materials provided with the distribution.
00014 //
00015 //- Neither the name of Zentaro Kavanagh nor the names of contributors 
00016 //  may be used to endorse or promote products derived from this software 
00017 //  without specific prior written permission.
00018 //
00019 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020 //``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00022 //PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
00023 //CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00024 //EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00025 //PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00026 //PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00027 //LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00028 //NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 //===========================================================================
00031 
00032 #include "stdafx.h"
00033 #include "FLACstream.h"
00034 //#include "FLACMath.h"
00035 
00036 FLACStream::FLACStream(OggPage* inBOSPage, OggDemuxSourceFilter* inOwningFilter, bool inAllowSeek)
00037         :       OggStream(inBOSPage, inOwningFilter, inAllowSeek)
00038         ,       mFLACFormatBlock(NULL)
00039         //,     mNumHeaderPackets(0)
00040 {
00041         InitCodec(inBOSPage->getStampedPacket(0));
00042 }
00043 
00044 FLACStream::~FLACStream(void)
00045 {
00046         delete mFLACFormatBlock;
00047 }
00048 
00049 bool FLACStream::InitCodec(StampedOggPacket* inOggPacket) {
00050         //Can probably abstract this out of here too !
00051         mCodecHeaders = new StreamHeaders;
00052         mCodecHeaders->mCodecType = StreamHeaders::FLAC;
00053         mCodecHeaders->addPacket((StampedOggPacket*)inOggPacket->clone());
00054         //What to do with commment fields ??
00055         //We set this to 1... and we override the header processor
00056         //When we see the last header packet ie starts with 1xxxxxxx then we decrement it.
00057         mNumHeadersNeeded = 1;
00058         return true;
00059 }
00060 
00061 wstring FLACStream::getPinName() {
00062         wstring locName = L"FLAC Out";
00063         return locName;
00064 }
00065 
00066 bool FLACStream::createFormatBlock() {
00067         const unsigned char FLAC_CHANNEL_MASK = 14;  //00001110
00068         const unsigned char FLAC_BPS_START_MASK = 1; //00000001
00069         const unsigned char FLAC_BPS_END_MASK = 240;  //11110000
00070         mFLACFormatBlock = new sFLACFormatBlock;
00071         //Fix the format block data... use header version and other version.
00072         //mFLACFormatBlock->FLACVersion = FLACMath::charArrToULong(mCodecHeaders->getPacket(1)->packetData() + 28);
00073         mFLACFormatBlock->numChannels = (((mCodecHeaders->getPacket(1)->packetData()[16]) & FLAC_CHANNEL_MASK) >> 1) + 1;
00074         mFLACFormatBlock->samplesPerSec = (iBE_Math::charArrToULong(mCodecHeaders->getPacket(1)->packetData() + 14)) >> 12;
00075         
00076         mFLACFormatBlock->numBitsPerSample =    (((mCodecHeaders->getPacket(1)->packetData()[16] & FLAC_BPS_START_MASK) << 4)   |
00077                                                                                         ((mCodecHeaders->getPacket(1)->packetData()[17] & FLAC_BPS_END_MASK) >> 4)) + 1;        
00078         return true;
00079 }
00080 BYTE* FLACStream::getFormatBlock() {
00081 
00082         return (BYTE*)mFLACFormatBlock;
00083 
00084 
00085 }
00086 unsigned long FLACStream::getFormatBlockSize() {
00087         //Do something
00088         return sizeof(sFLACFormatBlock);
00089 }
00090 GUID FLACStream::getFormatGUID() {
00091         return FORMAT_FLAC;
00092 }
00093 GUID FLACStream::getSubtypeGUID() {
00094         return MEDIASUBTYPE_FLAC;
00095 }
00096 GUID FLACStream::getMajorTypeGUID() {
00097         return MEDIATYPE_Audio;
00098 }
00099 
00100 unsigned long FLACStream::getNumBuffers() {
00101         return FLAC_NUM_BUFFERS;
00102 }
00103 unsigned long FLACStream::getBufferSize() {
00104         return FLAC_BUFFER_SIZE;
00105 }
00106 
00107 //Need to override from oggstream because we have variable number of headers
00108 bool FLACStream::processHeaderPacket(StampedOggPacket* inPacket) {
00109         //FIX::: Return values
00110         const unsigned char MORE_HEADERS_MASK = 128;   //10000000
00111         //We don't delete the packet... the codecheader list will delete when it's done.
00112         //StampedOggPacket* locPacket = processPacket(inPacket);
00113         if (inPacket != NULL) {
00114                 //We got a comlpete packet
00115                 mCodecHeaders->addPacket(inPacket);
00116                 if ((inPacket->packetData()[0] & MORE_HEADERS_MASK) != 0) {
00117                         mNumHeadersNeeded--;
00118                         //mNumHeaderPackets++;
00119                 }
00120         }
00121         return true;
00122 }
00123 void FLACStream::setLastEndGranPos(__int64 inPos) {
00124         mLastEndGranulePos = (inPos * (__int64)mFLACFormatBlock->samplesPerSec)/ UNITS;
00125 }
00126 bool FLACStream::deliverCodecHeaders() {
00127         StampedOggPacket* locPacket = NULL;
00128         for (unsigned long i = 0; i < mCodecHeaders->numPackets(); i++) {
00129                 if (i==0) {
00130                         locPacket = (StampedOggPacket*)mCodecHeaders->getPacket(0)->clone();
00131                 } else {
00132                         locPacket->merge(mCodecHeaders->getPacket(i));
00133                 }
00134         }
00135         if (mCodecHeaders->numPackets() > 0) {
00136                 dispatchPacket(locPacket);
00137         }
00138         return true;
00139 }
00140 
00141 LONGLONG FLACStream::getCurrentPos() {
00142         return (mLastEndGranulePos * UNITS) / mFLACFormatBlock->samplesPerSec;
00143 }
00144 
00145 //unsigned long FLACStream::numCodecHeaders() {
00146 //      return mNumHeaderPackets;  //is this even needed ?
00147 //}

Generated on Tue Feb 15 14:54:19 2005 for oggdsf by  doxygen 1.3.9