[xiph-commits] r11567 - branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource

illiminable at svn.xiph.org illiminable at svn.xiph.org
Tue Jun 13 12:49:36 PDT 2006


Author: illiminable
Date: 2006-06-13 12:49:25 -0700 (Tue, 13 Jun 2006)
New Revision: 11567

Modified:
   branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.cpp
   branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.h
   branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp
   branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.h
Log:
* 24/32 bit support to native flac.

Modified: branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.cpp
===================================================================
--- branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.cpp	2006-06-13 17:24:17 UTC (rev 11566)
+++ branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.cpp	2006-06-13 19:49:25 UTC (rev 11567)
@@ -61,6 +61,7 @@
 	,	mNumChannels(0)
 	,	mSampleRate(0)
 	,	mBitsPerSample(0)
+    ,   mSignificantBitsPerSample(0)
 	,	mBegun(false)
 	,	mUpto(0)
 	,	mJustSeeked(true)
@@ -150,7 +151,14 @@
 
 	mNumChannels = (((locBuff[20]) & FLAC_CHANNEL_MASK) >> 1) + 1;
 	mSampleRate = (iBE_Math::charArrToULong(&locBuff[18])) >> 12;
-	mBitsPerSample =	(((locBuff[20] & FLAC_BPS_START_MASK) << 4)	| ((locBuff[21] & FLAC_BPS_END_MASK) >> 4)) + 1;	
+	mSignificantBitsPerSample =	(((locBuff[20] & FLAC_BPS_START_MASK) << 4)	| ((locBuff[21] & FLAC_BPS_END_MASK) >> 4)) + 1;
+
+    mBitsPerSample = (mSignificantBitsPerSample + 7)  & 0xfffffff8UL;
+
+    if (mBitsPerSample == 24) {
+        mBitsPerSample = 32;
+    }
+
 	mTotalNumSamples = (((__int64)(locBuff[21] % 16)) << 32) + ((__int64)(iBE_Math::charArrToULong(&locBuff[22])));
 
 	//TODO::: NEed to handle the case where the number of samples is zero by making it non-seekable.
@@ -289,14 +297,14 @@
 {
 	
 
-    //WFE::: wave format extensible
+    
 	if (! mBegun) {
 		mBegun = true;
 		
-		const int SIZE_16_BITS = 2;
-		
+	
 		mNumChannels = inFrame->header.channels;
-		mFrameSize = mNumChannels * SIZE_16_BITS;
+        mFrameSize = mNumChannels * (mBitsPerSample >> 3);
+
 		mSampleRate = inFrame->header.sample_rate;
 	}
 
@@ -304,27 +312,96 @@
 	unsigned long locBufferSize = locNumFrames * mFrameSize;
 	unsigned long locTotalFrameCount = locNumFrames * mNumChannels;
 
-	//BUG::: There's a bug here. Implicitly assumes 2 channels. I think.
-	unsigned char* locBuff = new unsigned char[locBufferSize];			//Gives to the deliverdata method
-	//It could actually be a single buffer for the class.
 
-	signed short* locShortBuffer = (signed short*)locBuff;		//Don't delete this.
-	
-	signed short tempInt = 0;
-	int tempLong = 0;
-	float tempFloat = 0;
-	for(unsigned long i = 0; i < locNumFrames; i++) {
-		for (unsigned long j = 0; j < mNumChannels; j++) {
-			tempLong = inBuffer[j][i];
 
-			//FIX::: Why on earth are you dividing by 2 ? It does not make sense !
-			//tempInt = (signed short)(tempLong/2);
-			tempInt = (signed short)(tempLong);
-		
-			*locShortBuffer = tempInt;
-			locShortBuffer++;
-		}
-	}
+    // TODO::: It's not clear whether in the 32 bit flac sample, the significant bits are always rightmost (
+    //      ie justified into the least significant bits. They seem to be for nbits = 16. But it's unclear
+    //      whether eg a 20 bit sample is 0000 0000 1111 1111 1111 1111 1111 0000 so it's still a valid
+    //      24 bit sample, or whether it would require a 4 bit left shift to be a true 24 bit sample.
+
+    //      For now, working on the basis that it is truly right shifted.
+
+
+    //It could actually be a single buffer for the class.????
+    unsigned char* locBuff = new unsigned char[locBufferSize];			//Gives to the deliverdata method
+    unsigned long locLeftShift = mBitsPerSample - mSignificantBitsPerSample;
+
+    if (mBitsPerSample == 8) {
+        unsigned char* locByteBuffer = (unsigned char*)locBuff;
+
+        if (locLeftShift == 0) {
+	        for(unsigned long i = 0; i < locNumFrames; i++) {
+		        for (unsigned long j = 0; j < mNumChannels; j++) {
+                    *(locByteBuffer++) = (unsigned char)(inFrame + 128);
+                }
+
+            }
+        } else {
+	        for(unsigned long i = 0; i < locNumFrames; i++) {
+		        for (unsigned long j = 0; j < mNumChannels; j++) {
+                    *(locByteBuffer++) = (unsigned char)(inFrame + 128) << locLeftShift;
+                }
+
+            }
+
+        }
+
+
+    } else if (mBitsPerSample == 16) {
+	    signed short* locShortBuffer = (signed short*)locBuff;		//Don't delete this.
+        if (locLeftShift == 0) {
+        
+	        for(unsigned long i = 0; i < locNumFrames; i++) {
+		        for (unsigned long j = 0; j < mNumChannels; j++) {
+
+                    *(locShortBuffer++) = (signed short)inBuffer[j][i];
+			        //tempLong = inBuffer[j][i];
+
+			        ////FIX::: Why on earth are you dividing by 2 ? It does not make sense !
+			        ////tempInt = (signed short)(tempLong/2);
+			        //tempInt = (signed short)(tempLong);
+        		
+			        //*locShortBuffer = tempInt;
+			        //locShortBuffer++;
+		        }
+	        }
+        } else {
+	        for(unsigned long i = 0; i < locNumFrames; i++) {
+		        for (unsigned long j = 0; j < mNumChannels; j++) {
+
+                    *(locShortBuffer++) = (signed short)inBuffer[j][i] << locLeftShift;
+		        }
+	        }
+        }
+    } else if (mBitsPerSample == 32) {
+        signed long* locLongBuffer = (signed long*)locBuff;
+        if (locLeftShift == 8) {
+            //Special case for 24 bit, let the shift be hardcoded.
+            for(unsigned long i = 0; i < locNumFrames; i++) {
+		        for (unsigned long j = 0; j < mNumChannels; j++) {
+                    *(locLongBuffer++) = inBuffer[j][i] << 8;
+                }
+            }
+        } else if (locLeftShift == 0) {
+            //Real 32 bit data
+            for(unsigned long i = 0; i < locNumFrames; i++) {
+		        for (unsigned long j = 0; j < mNumChannels; j++) {
+                    *(locLongBuffer++) = inBuffer[j][i];
+                }
+            }
+
+        } else {
+            
+            for(unsigned long i = 0; i < locNumFrames; i++) {
+		        for (unsigned long j = 0; j < mNumChannels; j++) {
+                    *(locLongBuffer++) = inBuffer[j][i] << locLeftShift;
+                }
+            }
+
+        }
+    }
+
+
 	
 	mFLACSourcePin->deliverData(locBuff, locBufferSize, (mUpto*UNITS) / mSampleRate, ((mUpto+locNumFrames)*UNITS) / mSampleRate);
 	mUpto += locNumFrames;

Modified: branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.h
===================================================================
--- branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.h	2006-06-13 17:24:17 UTC (rev 11566)
+++ branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.h	2006-06-13 19:49:25 UTC (rev 11567)
@@ -147,6 +147,7 @@
 	unsigned long mFrameSize;
 	unsigned long mSampleRate;
 	unsigned long mBitsPerSample;
+    unsigned long mSignificantBitsPerSample;
 	__int64 mTotalNumSamples;
 
 	//Critical Section to protect codec.

Modified: branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp
===================================================================
--- branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp	2006-06-13 17:24:17 UTC (rev 11566)
+++ branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp	2006-06-13 19:49:25 UTC (rev 11567)
@@ -105,7 +105,20 @@
 	return CBaseOutputPin::BreakConnect();
 }
 
-	//CSourceStream virtuals
+
+
+HRESULT NativeFLACSourcePin::SetMediaType(const CMediaType* inMediaType)
+{
+
+    if (((WAVEFORMATEX*)inMediaType->pbFormat)->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
+        //mUsingExtendedWave = true;
+    } else if (((WAVEFORMATEX*)inMediaType->pbFormat)->wFormatTag == WAVE_FORMAT_PCM) {
+        //mUsingExtendedWave = false;
+    }
+
+    return CBaseOutputPin::SetMediaType(inMediaType);
+
+}
 HRESULT NativeFLACSourcePin::GetMediaType(int inPosition, CMediaType* outMediaType) 
 {
     //WFE::: Also offer extensible format
@@ -116,6 +129,49 @@
 		outMediaType->SetTemporalCompression(FALSE);
 		outMediaType->SetSampleSize(0);
 
+		WAVEFORMATEXTENSIBLE* locFormatEx = (WAVEFORMATEXTENSIBLE*)outMediaType->AllocFormatBuffer(sizeof(WAVEFORMATEXTENSIBLE));
+        
+		locFormatEx->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
+
+		locFormatEx->Format.nChannels = (WORD)mParentFilter->mNumChannels;
+		locFormatEx->Format.nSamplesPerSec =  mParentFilter->mSampleRate;
+
+        
+        locFormatEx->Samples.wValidBitsPerSample = (WORD)mParentFilter->mSignificantBitsPerSample;
+
+        //TODO::: Map this properly! What is the correct mapping ???
+        locFormatEx->dwChannelMask =        SPEAKER_FRONT_LEFT
+                                        |   SPEAKER_FRONT_RIGHT
+                                        |   SPEAKER_FRONT_CENTER
+                                        |   SPEAKER_LOW_FREQUENCY
+                                        |   SPEAKER_BACK_LEFT
+                                        |   SPEAKER_BACK_RIGHT
+                                        ;
+
+        ////TODO::: Round up to multiple of 8 or something
+        //if (mParentFilter->mBitsPerSample <= 16) {
+        //    //Round up to multiple of 8, ie 8 or 16
+        //    locFormatEx->Format.wBitsPerSample = (WORD)(mParentFilter->mBitsPerSample + 7) & 0xfff8;
+        //} else if (mParentFilter->mBitsPerSample <= 32) {
+        //    //Just use 32
+        //    locFormatEx->Format.wBitsPerSample = 32;
+        //}
+		locFormatEx->Format.wBitsPerSample = (WORD)mParentFilter->mBitsPerSample;
+		locFormatEx->Format.nBlockAlign = (WORD)((mParentFilter->mNumChannels) * (mParentFilter->mBitsPerSample >> 3));
+		locFormatEx->Format.nAvgBytesPerSec = ((mParentFilter->mNumChannels) * (mParentFilter->mBitsPerSample >> 3)) * mParentFilter->mSampleRate;
+		locFormatEx->Format.cbSize = 22; //sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
+        locFormatEx->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+
+        return S_OK;
+
+        //mUsingExtendedWav = true;
+    } else if (inPosition == 1) {
+		outMediaType->SetType(&MEDIATYPE_Audio);
+		outMediaType->SetSubtype(&MEDIASUBTYPE_PCM);
+		outMediaType->SetFormatType(&FORMAT_WaveFormatEx);
+		outMediaType->SetTemporalCompression(FALSE);
+		outMediaType->SetSampleSize(0);
+
 		WAVEFORMATEX* locFormat = (WAVEFORMATEX*)outMediaType->AllocFormatBuffer(sizeof(WAVEFORMATEX));
 		locFormat->wFormatTag = WAVE_FORMAT_PCM;
 
@@ -125,16 +181,20 @@
 		locFormat->nBlockAlign = (WORD)((mParentFilter->mNumChannels) * (mParentFilter->mBitsPerSample >> 3));
 		locFormat->nAvgBytesPerSec = ((mParentFilter->mNumChannels) * (mParentFilter->mBitsPerSample >> 3)) * mParentFilter->mSampleRate;
 		locFormat->cbSize = 0;
+        //mUsingExtendedWav = false;
 	
 		return S_OK;
-	} else {
+
+    } else {
 		return VFW_S_NO_MORE_ITEMS;
 	}
 }
 HRESULT NativeFLACSourcePin::CheckMediaType(const CMediaType* inMediaType) 
 {
     //WFE::: Do check for extensible type
-	if ((inMediaType->majortype == MEDIATYPE_Audio) && (inMediaType->subtype == MEDIASUBTYPE_PCM) && (inMediaType->formattype == FORMAT_WaveFormatEx)) {
+	if (               (inMediaType->majortype == MEDIATYPE_Audio) 
+                    &&  (inMediaType->subtype == MEDIASUBTYPE_PCM) 
+                    && (inMediaType->formattype == FORMAT_WaveFormatEx)) {
 		return S_OK;
 	} else {
 		return E_FAIL;

Modified: branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.h
===================================================================
--- branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.h	2006-06-13 17:24:17 UTC (rev 11566)
+++ branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.h	2006-06-13 19:49:25 UTC (rev 11567)
@@ -37,6 +37,10 @@
 //Library Includes
 #include "BasicSeekPassThrough.h"
 
+//Kernel streaming header for KSDATA_FORMAT_SUBTYPE_PCM
+#include "ks.h"
+#include "ksmedia.h"
+
 //Forward Declararions.
 class NativeFLACSourceFilter;
 class NativeFLACSourcePin
@@ -59,6 +63,7 @@
 
 	//CBaseOutputPin virtuals
 	virtual HRESULT GetMediaType(int inPosition, CMediaType* outMediaType);
+    virtual HRESULT SetMediaType(const CMediaType* inMediaType);
 	virtual HRESULT CheckMediaType(const CMediaType* inMediaType);
 	virtual HRESULT DecideBufferSize(IMemAllocator* inoutAllocator, ALLOCATOR_PROPERTIES* inoutInputRequest);
 



More information about the commits mailing list