SpeexDecodeInputPin.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 "SpeexDecodeInputPin.h"
00034 
00035 
00036 SpeexDecodeInputPin::SpeexDecodeInputPin(AbstractTransformFilter* inFilter, CCritSec* inFilterLock, AbstractTransformOutputPin* inOutputPin, vector<CMediaType*> inAcceptableMediaTypes)
00037         :       AbstractTransformInputPin(inFilter, inFilterLock, inOutputPin, NAME("SpeexDecodeInputPin"), L"Speex In", inAcceptableMediaTypes)
00038         ,       mFishSound(NULL)
00039 
00040         ,       mNumChannels(0)
00041         ,       mFrameSize(0)
00042         ,       mSampleRate(0)
00043         ,       mUptoFrame(0)
00044 
00045         ,       mBegun(false)
00046 {
00047         ConstructCodec();
00048 }
00049 
00050 bool SpeexDecodeInputPin::ConstructCodec() {
00051         mFishSound = fish_sound_new (FISH_SOUND_DECODE, &mFishInfo);
00052 
00053         int i = 1;
00054         //FIX::: Use new API for interleave setting
00055         fish_sound_command(mFishSound, FISH_SOUND_SET_INTERLEAVE, &i, sizeof(int));
00056 
00057         fish_sound_set_decoded_callback (mFishSound, SpeexDecodeInputPin::SpeexDecoded, this);
00058         //FIX::: Proper return value
00059         return true;
00060 }
00061 void SpeexDecodeInputPin::DestroyCodec() {
00062         fish_sound_delete(mFishSound);
00063         mFishSound = NULL;
00064 }
00065 SpeexDecodeInputPin::~SpeexDecodeInputPin(void)
00066 {
00067         DestroyCodec();
00068 }
00069 
00070 STDMETHODIMP SpeexDecodeInputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00071 {
00072         if (riid == IID_IMediaSeeking) {
00073                 *ppv = (IMediaSeeking*)this;
00074                 ((IUnknown*)*ppv)->AddRef();
00075                 return NOERROR;
00076         }
00077 
00078         return CBaseInputPin::NonDelegatingQueryInterface(riid, ppv); 
00079 }
00080 STDMETHODIMP SpeexDecodeInputPin::NewSegment(REFERENCE_TIME inStartTime, REFERENCE_TIME inStopTime, double inRate) 
00081 {
00082         CAutoLock locLock(mStreamLock);
00083         //debugLog<<"New segment "<<inStartTime<<" - "<<inStopTime<<endl;
00084         mUptoFrame = 0;
00085         return AbstractTransformInputPin::NewSegment(inStartTime, inStopTime, inRate);
00086         
00087 }
00088 
00089 int SpeexDecodeInputPin::SpeexDecoded (FishSound* inFishSound, float** inPCM, long inFrames, void* inThisPointer) 
00090 {
00091         //Do we need to delete the pcm structure ???? 
00092         //More of this can go to the abstract class.
00093 
00094         //For convenience we do all these cast once and for all here.
00095         SpeexDecodeInputPin* locThis = reinterpret_cast<SpeexDecodeInputPin*> (inThisPointer);
00096         SpeexDecodeFilter* locFilter = reinterpret_cast<SpeexDecodeFilter*>(locThis->m_pFilter);
00097         
00098 
00099         if (! locThis->mBegun) {
00100         
00101                 fish_sound_command (locThis->mFishSound, FISH_SOUND_GET_INFO, &(locThis->mFishInfo), sizeof (FishSoundInfo)); 
00102                 locThis->mBegun = true;
00103                 
00104                 locThis->mNumChannels = locThis->mFishInfo.channels;
00105                 locThis->mFrameSize = locThis->mNumChannels * SIZE_16_BITS;
00106                 locThis->mSampleRate = locThis->mFishInfo.samplerate;
00107 
00108         }
00109         
00110         //TO DO::: Move this somewhere else
00111         unsigned long locActualSize = inFrames * locThis->mFrameSize;
00112         unsigned long locTotalFrameCount = inFrames * locThis->mNumChannels;
00113 
00114         REFERENCE_TIME locFrameStart = (((__int64)(locThis->mUptoFrame * UNITS)) / locThis->mSampleRate);
00115         //Increment the frame counter
00116         locThis->mUptoFrame += inFrames;
00117         //Make the end frame counter
00118 
00119         
00120         REFERENCE_TIME locFrameEnd = (((__int64)(locThis->mUptoFrame * UNITS)) / locThis->mSampleRate);
00121 
00122 
00123         IMediaSample* locSample;
00124         HRESULT locHR = locThis->mOutputPin->GetDeliveryBuffer(&locSample, &locFrameStart, &locFrameEnd, NULL);
00125 
00126         if (locHR != S_OK) {
00127                 return locHR;
00128         }       
00129         
00130         //Create pointers for the samples buffer to be assigned to
00131         BYTE* locBuffer = NULL;
00132         signed short* locShortBuffer = NULL;
00133         
00134         //Make our pointers set to point to the samples buffer
00135         locSample->GetPointer(&locBuffer);
00136         locShortBuffer = (short *) locBuffer;
00137         
00138         signed short tempInt = 0;
00139         float tempFloat = 0;
00140         
00141         //FIX:::Move the clipping to the abstract function
00142 
00143         if (locSample->GetSize() >= locActualSize) {
00144                 //Do float to int conversion with clipping
00145                 float SINT_MAX_AS_FLOAT = 32767.0f;
00146                 for (unsigned long i = 0; i < locTotalFrameCount; i++) {
00147                         //Clipping because vorbis puts out floats out of range -1 to 1
00148                         if (((float*)inPCM)[i] <= -1.0f) {
00149                                 tempInt = SINT_MIN;     
00150                         } else if (((float*)inPCM)[i] >= 1.0f) {
00151                                 tempInt = SINT_MAX;
00152                         } else {
00153                                 //FIX:::Take out the unnescessary variable.
00154                                 tempFloat = ((( (float*) inPCM )[i]) * SINT_MAX_AS_FLOAT);
00155                                 //ASSERT((tempFloat <= 32767.0f) && (tempFloat >= -32786.0f));
00156                                 tempInt = (signed short)(tempFloat);
00157                                 //tempInt = (signed short) ((( (float*) inPCM )[i]) * SINT_MAX_AS_FLOAT);
00158                         }
00159                         
00160                         *locShortBuffer = tempInt;
00161                         locShortBuffer++;
00162                 }
00163                 
00164                 //Set the sample parameters.
00165                 locThis->SetSampleParams(locSample, locActualSize, &locFrameStart, &locFrameEnd);
00166 
00167                 {
00168                         CAutoLock locLock(locThis->m_pLock);
00169                         HRESULT locHR = ((SpeexDecodeOutputPin*)(locThis->mOutputPin))->mDataQueue->Receive(locSample);
00170                         if (locHR != S_OK) {
00171                                 return locHR;                           
00172                         }
00173                 }
00174 
00175                 
00176                 return 0;
00177         } else {
00178                 throw 0;
00179         }
00180 
00181 }
00182 
00183 
00184 
00185 HRESULT SpeexDecodeInputPin::TransformData(BYTE* inBuf, long inNumBytes) 
00186 {
00187         long locErr = fish_sound_decode(mFishSound, inBuf, inNumBytes);
00188         if (locErr == 0) {
00189                 return S_OK;
00190         } else {
00191                 return S_FALSE;
00192         }
00193 }
00194 
00195 
00196 
00197 HRESULT SpeexDecodeInputPin::SetMediaType(const CMediaType* inMediaType) {
00198         //FIX:::Error checking
00199         //RESOLVED::: Bit better.
00200 
00201         if (inMediaType->subtype == MEDIASUBTYPE_Speex) {
00202                 ((SpeexDecodeFilter*)mParentFilter)->setSpeexFormat((sSpeexFormatBlock*)inMediaType->pbFormat);
00203 
00204         } else {
00205                 throw 0;
00206         }
00207         return CBaseInputPin::SetMediaType(inMediaType);
00208 }
00209 

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