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 //}