[xiph-commits] r17758 - in trunk/oggdsf: . src/lib/codecs/flac/filters/dsfNativeFLACSource src/lib/codecs/vorbis/filters/dsfVorbisDecoder src/lib/codecs/vorbis/libs/libOOVorbis src/lib/helper/common

cristianadam at svn.xiph.org cristianadam at svn.xiph.org
Wed Dec 15 12:24:02 PST 2010


Author: cristianadam
Date: 2010-12-15 12:24:02 -0800 (Wed, 15 Dec 2010)
New Revision: 17758

Added:
   trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/IDownmixAudio.h
Modified:
   trunk/oggdsf/ChangeLog.txt
   trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp
   trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.cpp
   trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.h
   trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.cpp
   trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.h
   trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeOutputPin.cpp
   trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncoder.cpp
   trunk/oggdsf/src/lib/helper/common/VorbisTypes.h
Log:
Merged patch from Google regarding multi channel Vorbis and stereo downmix. Downmix can be enabled by using the IDownmixAudio interface of the Vorbis decoder input pin.
Fixed #1748: opencodecs unable to cope with less usual audio setups (ogg 6.1, possibly 7.1 and other non-stereo ones)

Modified: trunk/oggdsf/ChangeLog.txt
===================================================================
--- trunk/oggdsf/ChangeLog.txt	2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/ChangeLog.txt	2010-12-15 20:24:02 UTC (rev 17758)
@@ -11,6 +11,8 @@
     * Theora Decoder filter can now be connected to the output of the Theora Encoder filter.
     * Fixed graph freeze when a Vorbis Decoder filter was connected to the output of a 
       Vorbis Encoder filter.
+    * Fixed #1748: opencodecs unable to cope with less usual audio setups (ogg 6.1, possibly 7.1 
+      and other non-stereo ones)
 
 Version 0.84.17359 - 04.08.2010
     

Modified: trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp	2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp	2010-12-15 20:24:02 UTC (rev 17758)
@@ -184,6 +184,10 @@
         case 6:
             formatEx->dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
             break;
+        case 7:
+            formatEx->dwChannelMask = KSAUDIO_SPEAKER_5POINT1_SURROUND 
+                                    | SPEAKER_BACK_CENTER;
+            break;
         case 8:
             formatEx->dwChannelMask = KSAUDIO_SPEAKER_7POINT1_SURROUND;
             break;

Added: trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/IDownmixAudio.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/IDownmixAudio.h	                        (rev 0)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/IDownmixAudio.h	2010-12-15 20:24:02 UTC (rev 17758)
@@ -0,0 +1,8 @@
+#pragma once
+
+//Interface to set/get downmix
+DECLARE_INTERFACE_(IDownmixAudio, IUnknown)
+{
+    virtual void __stdcall setDownmixAudio(const bool setDownmix) = 0;
+    virtual bool __stdcall getDownmixAudio() = 0;
+};

Modified: trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.cpp	2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.cpp	2010-12-15 20:24:02 UTC (rev 17758)
@@ -264,10 +264,10 @@
 
 void VorbisDecodeFilter::PrintVorbisFormatInfo()
 {
-    LOG(logINFO) << "Vorbis Version: " << mVorbisFormatInfo->vorbisVersion
-        << " Channels: " << mVorbisFormatInfo->numChannels
-        << " SamplesPerSec: " << mVorbisFormatInfo->samplesPerSec
-        << " MaxBitsPerSec: " << mVorbisFormatInfo->maxBitsPerSec
-        << " AvgBitsPerSec: " << mVorbisFormatInfo->avgBitsPerSec
-        << " MinBitsPerSec: " << mVorbisFormatInfo->minBitsPerSec;
+    LOG(logINFO) << "Vorbis Version: " << mVorbisFormatInfo->vorbisVersion;
+    LOG(logINFO) << "Channels: " << mVorbisFormatInfo->numChannels;
+    LOG(logINFO) << "SamplesPerSec: " << mVorbisFormatInfo->samplesPerSec;
+    LOG(logINFO) << "MaxBitsPerSec: " << mVorbisFormatInfo->maxBitsPerSec;
+    LOG(logINFO) << "AvgBitsPerSec: " << mVorbisFormatInfo->avgBitsPerSec;
+    LOG(logINFO) << "MinBitsPerSec: " << mVorbisFormatInfo->minBitsPerSec;
 }

Modified: trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.h	2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.h	2010-12-15 20:24:02 UTC (rev 17758)
@@ -89,6 +89,4 @@
 
 	//Format Block
 	VORBISFORMAT* mVorbisFormatInfo;
-
-    static const bool USE_CORRECT_VORBIS_CHANNEL_MAPPING = true;
 };

Modified: trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.cpp	2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.cpp	2010-12-15 20:24:02 UTC (rev 17758)
@@ -36,56 +36,61 @@
 
 #include <assert.h>
 
-VorbisDecodeInputPin::VorbisDecodeInputPin(AbstractTransformFilter* inFilter,	CCritSec* inFilterLock,	
+VorbisDecodeInputPin::VorbisDecodeInputPin(AbstractTransformFilter* inFilter,    CCritSec* inFilterLock,    
                                            AbstractTransformOutputPin* inOutputPin, 
-                                           vector<CMediaType*> inAcceptableMediaTypes) :	
-AbstractTransformInputPin (inFilter, inFilterLock,	inOutputPin, NAME("VorbisDecodeInputPin"),	
-                           L"Vorbis In", inAcceptableMediaTypes),	
-mBegun(false),	
-mNumChannels(0),	
-mFrameSize(0),	
+                                           vector<CMediaType*> inAcceptableMediaTypes) :    
+AbstractTransformInputPin (inFilter, inFilterLock,    inOutputPin, NAME("VorbisDecodeInputPin"),    
+                           L"Vorbis In", inAcceptableMediaTypes),    
+mBegun(false),    
+mNumChannels(0),    
+mFrameSize(0),    
 mSampleRate(0),
 // mUptoFrame(0),
-mSetupState(VSS_SEEN_NOTHING),	
-mDecodedBuffer(NULL),	
-mDecodedByteCount(0),	
-mRateNumerator(RATE_DENOMINATOR),	
-mOggOutputPinInterface(NULL),	
+mSetupState(VSS_SEEN_NOTHING),    
+mDecodedBuffer(NULL),    
+mDecodedByteCount(0),    
+mRateNumerator(RATE_DENOMINATOR),    
+mOggOutputPinInterface(NULL),    
 mSentStreamOffset(false),
-m_isVorbisFormat2(false)
+m_isVorbisFormat2(false),
+m_isDownmix(false)
 {
-	LOG(logDEBUG) << "Pin constructor";
-	ConstructCodec();
-	LOG(logDEBUG) << "Pin constructor - post construct codec";
+    LOG(logDEBUG) << "Pin constructor";
+    ConstructCodec();
+    LOG(logDEBUG) << "Pin constructor - post construct codec";
 
-	mDecodedBuffer = new unsigned char[DECODED_BUFFER_SIZE];
+    mDecodedBuffer = new unsigned char[DECODED_BUFFER_SIZE];
 }
 
 VorbisDecodeInputPin::~VorbisDecodeInputPin(void)
 {
-	DestroyCodec();
-	delete[] mDecodedBuffer;
+    DestroyCodec();
+    delete[] mDecodedBuffer;
 }
 
 //Is this needed ??
 STDMETHODIMP VorbisDecodeInputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
 {
-	if (riid == IID_IMediaSeeking) 
+    if (riid == IID_IMediaSeeking) 
     {
         return GetInterface((IMediaSeeking*)this, ppv);
-	} 
+    } 
     else if (riid == IID_IOggDecoder) 
     {
         return GetInterface((IOggDecoder*)this, ppv);
-	}
+    }
+    else if (riid == IID_IDownmixAudio)
+    {
+        return GetInterface((IDownmixAudio*)this, ppv);
+    }
 
-	return AbstractTransformInputPin::NonDelegatingQueryInterface(riid, ppv); 
+    return AbstractTransformInputPin::NonDelegatingQueryInterface(riid, ppv); 
 }
 
 bool VorbisDecodeInputPin::ConstructCodec() 
 {
-	return true;
-	//Vorbis decoder should be good to go
+    return true;
+    //Vorbis decoder should be good to go
 }
 
 void VorbisDecodeInputPin::DestroyCodec() 
@@ -95,30 +100,30 @@
 
 STDMETHODIMP VorbisDecodeInputPin::NewSegment(REFERENCE_TIME inStartTime, REFERENCE_TIME inStopTime, double inRate) 
 {
-	CAutoLock locLock(mStreamLock);
-	//LOG(logDEBUG) << "New segment " << inStartTime<< " - " << inStopTime;
-	//mUptoFrame = 0;
-	mRateNumerator = RATE_DENOMINATOR * inRate;
-	if (mRateNumerator > RATE_DENOMINATOR) 
+    CAutoLock locLock(mStreamLock);
+    //LOG(logDEBUG) << "New segment " << inStartTime<< " - " << inStopTime;
+    //mUptoFrame = 0;
+    mRateNumerator = RATE_DENOMINATOR * inRate;
+    if (mRateNumerator > RATE_DENOMINATOR) 
     {
-		mRateNumerator = RATE_DENOMINATOR;
-	}
-	return AbstractTransformInputPin::NewSegment(inStartTime, inStopTime, inRate);
+        mRateNumerator = RATE_DENOMINATOR;
+    }
+    return AbstractTransformInputPin::NewSegment(inStartTime, inStopTime, inRate);
 }
 
 STDMETHODIMP VorbisDecodeInputPin::EndFlush()
 {
-	CAutoLock locLock(m_pLock);
-	
-	HRESULT locHR = AbstractTransformInputPin::EndFlush();
-	mDecodedByteCount = 0;
+    CAutoLock locLock(m_pLock);
+    
+    HRESULT locHR = AbstractTransformInputPin::EndFlush();
+    mDecodedByteCount = 0;
 
     return locHR;
 }
 
 STDMETHODIMP VorbisDecodeInputPin::Receive(IMediaSample* inSample) 
 {
-	CAutoLock locLock(mStreamLock);
+    CAutoLock locLock(mStreamLock);
 
     HRESULT hr = CheckStreaming();
 
@@ -158,8 +163,8 @@
         if (hr != S_OK) 
             return hr;
 
-        //TODO: Handling multi-channels such as 5.1 or 7.1, right now only handle one or two channels.
-        memcpy((void*)buffer, (const void*)mDecodedBuffer, mDecodedByteCount);
+        reorderChannels(buffer, mDecodedBuffer, mDecodedByteCount);
+        //memcpy((void*)buffer, (const void*)mDecodedBuffer, mDecodedByteCount);
 
         sample->SetTime(&tStart, &tStop);
         sample->SetSyncPoint(TRUE);
@@ -179,7 +184,7 @@
         }
         if (tStop > 0) 
         {
-            //Can dump it all downstream now	
+            //Can dump it all downstream now    
             IMediaSample* sample;
             unsigned long bytesCopied = 0;
             unsigned long bytesToCopy = 0;
@@ -194,7 +199,7 @@
             if (!mSentStreamOffset && (mOggOutputPinInterface != NULL)) 
             {
                 mOggOutputPinInterface->notifyStreamBaseTime(tStart);
-                mSentStreamOffset = true;	
+                mSentStreamOffset = true;    
             }
 
             if (mOggOutputPinInterface != NULL) 
@@ -227,8 +232,6 @@
                 }
 
                 LOG(logDEBUG4) << __FUNCTIONW__ << " Bytes to copy: " << bytesToCopy;
-                LOG(logDEBUG4) << __FUNCTIONW__ << " Actual Buffer count = " << mOutputPin->actualBufferCount();
-                //bytesCopied += bytesToCopy;
 
                 sampleDuration = (((bytesToCopy/mFrameSize) * UNITS) / mSampleRate);
                 tStop = tStart + sampleDuration;
@@ -254,7 +257,7 @@
                         seekStripOffset += (mFrameSize - (seekStripOffset % mFrameSize));
                         __int64 strippedDuration = (((seekStripOffset/mFrameSize) * UNITS) / mSampleRate);
                         adjustedStart += strippedDuration;
-                    }					
+                    }                    
 
                     LOG(logDEBUG4) << __FUNCTIONW__ << " Seek strip offset: " << seekStripOffset;
 
@@ -284,6 +287,8 @@
 
             } while(bytesCopied < mDecodedByteCount);
 
+            LOG(logDEBUG4) << __FUNCTIONW__ << " Decoded byte count: " << mDecodedByteCount;
+
             mDecodedByteCount = 0;
 
         }
@@ -291,82 +296,134 @@
     return S_OK;
 }
 
+
+
 void VorbisDecodeInputPin::reorderChannels(unsigned char* inDestBuffer, const unsigned char* inSourceBuffer, unsigned long inNumBytes)
 {
-    //memcpy((void*)locBuffer, (const void*)&mDecodedBuffer[bytesCopied + seekStripOffset], bytesToCopy - seekStripOffset);
+    const short* channel_order;
+    const short channel_order_mono[] = {0};
+    const short channel_order_stereo[] = {0, 1};
+    const short channel_order_three[] = {0, 2, 1};
+    const short channel_order_four[] = {0, 1, 2, 3};
+    const short channel_order_five[] = {0, 2, 1, 3, 4};
+    const short channel_order_5_1[] = {0, 2, 1, 5, 3, 4};
+    const short channel_order_6_1[] = {0, 2, 1, 6, 5, 3, 4};
+    const short channel_order_7_1[] = {0, 2, 1, 7, 5, 6, 3, 4};
 
-    if (GetFilter()->USE_CORRECT_VORBIS_CHANNEL_MAPPING && 
-        (mNumChannels == 6  || mNumChannels == 3 || mNumChannels == 5)) 
-    {
-        //We only have to reorder the channels if we are using the extended format, we have declared that we want to map correctly
-        // and the number channels is 3 or 6. All other cases we just memcpy
-    
-        unsigned long locSampleCount = inNumBytes / (mNumChannels * sizeof(short));
+    switch (mNumChannels) {
+        case 1: // mono ch. 
+            channel_order = channel_order_mono;
+            break;
+        case 2: // stereo ch. 
+            channel_order = channel_order_stereo;
+            break;
+        case 3: // 3 ch. 
+            channel_order = channel_order_three;
+            break;
+        case 4: // 4 ch. 
+            channel_order = channel_order_four;
+            break;
+        case 5: // 5 ch. 
+            channel_order = channel_order_five;
+            break;
+        case 6: // 5.1 ch. 
+            channel_order = channel_order_5_1;
+            break;
+        case 7: // 6.1 ch. 
+            channel_order = channel_order_6_1;
+            break;
+        case 8: // 7.1 ch.
+            channel_order = channel_order_7_1;
+            break;
+        default:
+            memcpy((void*)inDestBuffer, (const void*)inSourceBuffer, inNumBytes);
+            return;
+    }
 
-        short* locDest = (short*)inDestBuffer;
-        const short* locSource = (short*)inSourceBuffer;
+    const unsigned long locSampleCount = inNumBytes / (mNumChannels * sizeof(short));
 
-        if (mNumChannels == 6)
-        {
-            for (unsigned long i = 0; i < locSampleCount; i++)
-            {
-                *locDest++ = *locSource;
-                *locDest++ = locSource[2];
-                *locDest++ = locSource[1];
-                *locDest++ = locSource[5];
-                *locDest++ = locSource[3];
-                *locDest++ = locSource[4];
+    short* locDest = (short*)inDestBuffer;
+    const short* locSource = (short*)inSourceBuffer;
 
-                locSource += 6;
-             }
+    //Test code
+    //bool setDownmix = true;
+    //setDownmixAudio(setDownmix);
 
-        } 
-        else if (mNumChannels == 3) 
+    if (getDownmixAudio()) 
+    {
+        for (unsigned long i = 0; i < locSampleCount; ++i) 
         {
-            //3 channels
-            for (unsigned long i = 0; i < locSampleCount; i++)
+            for (unsigned long chan = 0; chan < mNumChannels; ++chan) 
             {
-                *locDest++ = *locSource;
-                *locDest++ = locSource[2];
-                *locDest++ = locSource[1];
-                locSource += 3;
+                switch (mNumChannels) 
+                {
+                case 3: // 3 ch.
+                    locDest[0] = locSource[0] + static_cast<short>(0.7 * locSource[1]); 
+                    locDest[1] = locSource[2] + static_cast<short>(0.7 * locSource[1]); 
+                    break;
+                case 4: // 4 ch.
+                    locDest[0] = locSource[0] + locSource[2];
+                    locDest[1] = locSource[1] + locSource[3];
+                    break;
+                case 5: // 5 ch.
+                    locDest[0] = locSource[0] + static_cast<short>(0.7 * locSource[1]) + static_cast<short>(0.7 * locSource[3]);
+                    locDest[1] = locSource[2] + static_cast<short>(0.7 * locSource[1]) + static_cast<short>(0.7 * locSource[4]);
+                    break;
+                case 6: // 5.1 ch. 
+                    locDest[0] = locSource[0] + locSource[5] + static_cast<short>(0.7 * locSource[1])\
+                        + static_cast<short>(0.7 * locSource[3]); 
+                    locDest[1] = locSource[2] + locSource[5] + static_cast<short>(0.7 * locSource[1])\
+                        + static_cast<short>(0.7 * locSource[4]);
+                    break;
+                case 7: // 6.1 ch. 
+                    locDest[0] = locSource[0] + locSource[7] + static_cast<short>(0.7 * locSource[1])\
+                        + static_cast<short>(0.7 * locSource[3]) + static_cast<short>(0.7 * locSource[5]);
+                    locDest[1] = locSource[2] + locSource[7] + static_cast<short>(0.7 * locSource[1])\
+                        + static_cast<short>(0.7 * locSource[4]) + static_cast<short>(0.7 * locSource[6]);
+                    break;
+                case 8: // 7.1 ch. 
+                    locDest[0] = locSource[0] + locSource[7] + static_cast<short>(0.7 * locSource[1])\
+                        + static_cast<short>(0.7 * locSource[3]) + static_cast<short>(0.7 * locSource[5]);
+                    locDest[1] = locSource[2] + locSource[7] + static_cast<short>(0.7 * locSource[1])\
+                        + static_cast<short>(0.7 * locSource[4]) + static_cast<short>(0.7 * locSource[6]);
+                    break;
+                }
+                locDest += mNumChannels;
+                locSource += mNumChannels;
             }
-        } 
-        else 
+        }
+    }
+    else 
+    {
+        for (unsigned long i = 0; i < locSampleCount; ++i) 
         {
-            //5 channels
-            for (unsigned long i = 0; i < locSampleCount; i++)
+            for (unsigned long chan = 0; chan < mNumChannels; ++chan) 
             {
-                *locDest++ = *locSource;
-                *locDest++ = locSource[2];
-                *locDest++ = locSource[1];
-                *locDest++ = locSource[3];
-                *locDest++ = locSource[4];
-                locSource += 5;
+                *locDest++ = locSource[channel_order[chan]];
             }
+            locSource += mNumChannels;
         }
-        return;
     }
-    
-    memcpy((void*)inDestBuffer, (const void*)inSourceBuffer, inNumBytes);
+
+    return;
 }
 
 HRESULT VorbisDecodeInputPin::TransformData(BYTE* inBuf, long inNumBytes) 
 {
-	//TODO::: Return types !!!
+    //TODO::: Return types !!!
 
-	VorbisDecoder::eVorbisResult locResult;
-	unsigned long locNumSamples = 0;
-	locResult = mVorbisDecoder.DecodePacket(inBuf, inNumBytes,(short*) (mDecodedBuffer + mDecodedByteCount), locNumSamples);
+    VorbisDecoder::eVorbisResult locResult;
+    unsigned long locNumSamples = 0;
+    locResult = mVorbisDecoder.DecodePacket(inBuf, inNumBytes,(short*) (mDecodedBuffer + mDecodedByteCount), locNumSamples);
 
-	if (locResult == VorbisDecoder::VORBIS_DATA_OK) 
+    if (locResult == VorbisDecoder::VORBIS_DATA_OK) 
     {
-		mDecodedByteCount += locNumSamples * mFrameSize;
-		return S_OK;
-	}
+        mDecodedByteCount += locNumSamples * mFrameSize;
+        return S_OK;
+    }
 
-	//For now, just silently ignore busted packets.
-	return S_OK;
+    //For now, just silently ignore busted packets.
+    return S_OK;
 }
 
 HRESULT VorbisDecodeInputPin::TransformVorbis2(const BYTE* const buffer, const long length_of_buffer) 
@@ -393,15 +450,15 @@
 {
     LOG(logDEBUG) << __FUNCTIONW__;
 
-	//FIX:::Error checking
-	if (CheckMediaType(inMediaType) == S_OK) 
+    //FIX:::Error checking
+    if (CheckMediaType(inMediaType) == S_OK) 
     {
         if (inMediaType->majortype == MEDIATYPE_OggPacketStream &&
             inMediaType->formattype == FORMAT_OggIdentHeader &&
             inMediaType->cbFormat == VORBIS_IDENT_HEADER_SIZE) 
         {
             LOG(logINFO) << __FUNCTIONW__ << " MEDIATYPE_OggPacketStream, FORMAT_OggIdentHeader";
-		    GetFilter()->setVorbisFormat(inMediaType->pbFormat);
+            GetFilter()->setVorbisFormat(inMediaType->pbFormat);
         }
         else if (inMediaType->majortype == MEDIATYPE_Audio &&
                  inMediaType->subtype == MEDIASUBTYPE_Vorbis &&
@@ -421,28 +478,27 @@
             mVorbisDecoder.Init(reinterpret_cast<VORBISFORMAT2*>(inMediaType->pbFormat));
         }
 
-	} 
+    } 
     else 
     {
         LOG(logERROR) << __FUNCTIONW__ << " MediaType not OK, Exiting";
-		throw 0;
-	}
-	
+        throw 0;
+    }
+    
     return CBaseInputPin::SetMediaType(inMediaType);
 }
-
 HRESULT VorbisDecodeInputPin::CheckMediaType(const CMediaType *inMediaType)
 {
-	if (inMediaType->majortype == MEDIATYPE_OggPacketStream &&
+    if (inMediaType->majortype == MEDIATYPE_OggPacketStream &&
         inMediaType->formattype == FORMAT_OggIdentHeader &&
         inMediaType->cbFormat == VORBIS_IDENT_HEADER_SIZE) 
     {
-		if (strncmp((char*)inMediaType->pbFormat, "\001vorbis", 7) == 0) 
+        if (strncmp((char*)inMediaType->pbFormat, "\001vorbis", 7) == 0) 
         {
             LOG(logDEBUG) << "Check media type OK (MEDIATYPE_OggPacketStream)";
             return S_OK;
-		}
-	}
+        }
+    }
     else if (inMediaType->majortype == MEDIATYPE_Audio &&
              inMediaType->subtype == MEDIASUBTYPE_Vorbis &&
              inMediaType->formattype == FORMAT_Vorbis)
@@ -471,126 +527,126 @@
 
 HRESULT VorbisDecodeInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *outRequestedProps)
 {
-	outRequestedProps->cbBuffer = VORBIS_BUFFER_SIZE;
-	outRequestedProps->cBuffers = VORBIS_NUM_BUFFERS;
-	outRequestedProps->cbAlign = 1;
-	outRequestedProps->cbPrefix = 0;
+    outRequestedProps->cbBuffer = VORBIS_BUFFER_SIZE;
+    outRequestedProps->cBuffers = VORBIS_NUM_BUFFERS;
+    outRequestedProps->cbAlign = 1;
+    outRequestedProps->cbPrefix = 0;
 
-	return S_OK;
+    return S_OK;
 }
 
 LOOG_INT64 VorbisDecodeInputPin::convertGranuleToTime(LOOG_INT64 inGranule)
 {
-	if (mBegun) 
-    {	
-		return (inGranule * UNITS) / mSampleRate;
-	} 
+    if (mBegun) 
+    {    
+        return (inGranule * UNITS) / mSampleRate;
+    } 
     else 
     {
-		return -1;
-	}
+        return -1;
+    }
 }
 
 LOOG_INT64 VorbisDecodeInputPin::mustSeekBefore(LOOG_INT64 inGranule)
 {
-	//TODO::: Get adjustment from block size info... for now, it doesn't matter if no preroll
+    //TODO::: Get adjustment from block size info... for now, it doesn't matter if no preroll
     //return (inGranule <= 4096) ? 0 : (inGranule - 4096);
     return inGranule;
 }
 IOggDecoder::eAcceptHeaderResult VorbisDecodeInputPin::showHeaderPacket(OggPacket* inCodecHeaderPacket)
 {
     LOG(logDEBUG) << __FUNCTIONW__ << " SetupState: " << mSetupState;
-	unsigned long locDummy;
-	switch (mSetupState) 
+    unsigned long locDummy;
+    switch (mSetupState) 
     {
-		case VSS_SEEN_NOTHING:
-			if (strncmp((char*)inCodecHeaderPacket->packetData(), "\001vorbis", 7) == 0) 
+        case VSS_SEEN_NOTHING:
+            if (strncmp((char*)inCodecHeaderPacket->packetData(), "\001vorbis", 7) == 0) 
             {
-				//TODO::: Possibly verify version
-				if (mVorbisDecoder.DecodePacket(		inCodecHeaderPacket->packetData()
-													,	inCodecHeaderPacket->packetSize()
-													,	NULL
-													,	locDummy) == VorbisDecoder::VORBIS_HEADER_OK) {
-					mSetupState = VSS_SEEN_BOS;
-					LOG(logDEBUG) << "Saw first header";
-					return IOggDecoder::AHR_MORE_HEADERS_TO_COME;
-				}
-			}
-			return IOggDecoder::AHR_INVALID_HEADER;
-			
-			
-		case VSS_SEEN_BOS:
-			if (strncmp((char*)inCodecHeaderPacket->packetData(), "\003vorbis", 7) == 0) 
+                //TODO::: Possibly verify version
+                if (mVorbisDecoder.DecodePacket(        inCodecHeaderPacket->packetData()
+                                                    ,    inCodecHeaderPacket->packetSize()
+                                                    ,    NULL
+                                                    ,    locDummy) == VorbisDecoder::VORBIS_HEADER_OK) {
+                    mSetupState = VSS_SEEN_BOS;
+                    LOG(logDEBUG) << "Saw first header";
+                    return IOggDecoder::AHR_MORE_HEADERS_TO_COME;
+                }
+            }
+            return IOggDecoder::AHR_INVALID_HEADER;
+            
+            
+        case VSS_SEEN_BOS:
+            if (strncmp((char*)inCodecHeaderPacket->packetData(), "\003vorbis", 7) == 0) 
             {
-				if (mVorbisDecoder.DecodePacket(		inCodecHeaderPacket->packetData()
-													,	inCodecHeaderPacket->packetSize()
-													,	NULL
-													,	locDummy) == VorbisDecoder::VORBIS_COMMENT_OK) {
+                if (mVorbisDecoder.DecodePacket(        inCodecHeaderPacket->packetData()
+                                                    ,    inCodecHeaderPacket->packetSize()
+                                                    ,    NULL
+                                                    ,    locDummy) == VorbisDecoder::VORBIS_COMMENT_OK) {
 
-					mSetupState = VSS_SEEN_COMMENT;
-					LOG(logDEBUG) << "Saw second header";
-					return IOggDecoder::AHR_MORE_HEADERS_TO_COME;
-				}	
-			}
-			return IOggDecoder::AHR_INVALID_HEADER;
-			
-			
-		case VSS_SEEN_COMMENT:
-			if (strncmp((char*)inCodecHeaderPacket->packetData(), "\005vorbis", 7) == 0) 
+                    mSetupState = VSS_SEEN_COMMENT;
+                    LOG(logDEBUG) << "Saw second header";
+                    return IOggDecoder::AHR_MORE_HEADERS_TO_COME;
+                }    
+            }
+            return IOggDecoder::AHR_INVALID_HEADER;
+            
+            
+        case VSS_SEEN_COMMENT:
+            if (strncmp((char*)inCodecHeaderPacket->packetData(), "\005vorbis", 7) == 0) 
             {
-				if (mVorbisDecoder.DecodePacket(		inCodecHeaderPacket->packetData()
-													,	inCodecHeaderPacket->packetSize()
-													,	NULL
-													,	locDummy) == VorbisDecoder::VORBIS_CODEBOOK_OK) {
+                if (mVorbisDecoder.DecodePacket(        inCodecHeaderPacket->packetData()
+                                                    ,    inCodecHeaderPacket->packetSize()
+                                                    ,    NULL
+                                                    ,    locDummy) == VorbisDecoder::VORBIS_CODEBOOK_OK) {
 
-		
-					//Is mBegun useful ?
-					mBegun = true;
-			
-					mNumChannels = mVorbisDecoder.numChannels();
-					mFrameSize = mNumChannels * SIZE_16_BITS;
-					mSampleRate = mVorbisDecoder.sampleRate(); 
+        
+                    //Is mBegun useful ?
+                    mBegun = true;
+            
+                    mNumChannels = mVorbisDecoder.numChannels();
+                    mFrameSize = mNumChannels * SIZE_16_BITS;
+                    mSampleRate = mVorbisDecoder.sampleRate(); 
 
-		
-					mSetupState = VSS_ALL_HEADERS_SEEN;
-					LOG(logDEBUG) << "Saw third header";
-					return IOggDecoder::AHR_ALL_HEADERS_RECEIVED;
-				}
-				
-			}
-			return IOggDecoder::AHR_INVALID_HEADER;
-			
-		case VSS_ALL_HEADERS_SEEN:
-		case VSS_ERROR:
-		default:
-			return IOggDecoder::AHR_UNEXPECTED;
-	}
+        
+                    mSetupState = VSS_ALL_HEADERS_SEEN;
+                    LOG(logDEBUG) << "Saw third header";
+                    return IOggDecoder::AHR_ALL_HEADERS_RECEIVED;
+                }
+                
+            }
+            return IOggDecoder::AHR_INVALID_HEADER;
+            
+        case VSS_ALL_HEADERS_SEEN:
+        case VSS_ERROR:
+        default:
+            return IOggDecoder::AHR_UNEXPECTED;
+    }
 }
 
 string VorbisDecodeInputPin::getCodecShortName()
 {
-	return "vorbis";
+    return "vorbis";
 }
 
 string VorbisDecodeInputPin::getCodecIdentString()
 {
-	//TODO::: Get full ident string
-	return "vorbis";
+    //TODO::: Get full ident string
+    return "vorbis";
 }
 
 HRESULT VorbisDecodeInputPin::CompleteConnect(IPin *inReceivePin)
 {
-	IOggOutputPin* locOggOutput = NULL;
-	mSentStreamOffset = false;
-	HRESULT locHR = inReceivePin->QueryInterface(IID_IOggOutputPin, (void**)&locOggOutput);
-	if (locHR == S_OK) 
+    IOggOutputPin* locOggOutput = NULL;
+    mSentStreamOffset = false;
+    HRESULT locHR = inReceivePin->QueryInterface(IID_IOggOutputPin, (void**)&locOggOutput);
+    if (locHR == S_OK) 
     {
-		mOggOutputPinInterface = locOggOutput;	
-	} 
+        mOggOutputPinInterface = locOggOutput;    
+    } 
     else 
     {
-		mOggOutputPinInterface = NULL;
-	}
+        mOggOutputPinInterface = NULL;
+    }
     LOG(logDEBUG) << __FUNCTIONW__ << " QueryInterface(IOggOutputPin) " << std::boolalpha 
         << (mOggOutputPinInterface != NULL ? "succeeded" : "failed");
 
@@ -603,3 +659,14 @@
 
     return AbstractTransformInputPin::CompleteConnect(inReceivePin);
 }
+
+void VorbisDecodeInputPin::setDownmixAudio(const bool setDownmix)
+{
+     m_isDownmix = setDownmix;
+     return;
+}
+
+bool VorbisDecodeInputPin::getDownmixAudio()
+{
+    return m_isDownmix;
+}

Modified: trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.h	2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.h	2010-12-15 20:24:02 UTC (rev 17758)
@@ -37,95 +37,102 @@
 #include "VorbisDecodeInputPin.h"
 #include "VorbisDecodeFilter.h"
 #include "VorbisDecoder.h"
+#include "IDownmixAudio.h"
 
 class VorbisDecodeFilter;
 class VorbisDecodeOutputPin;
 
 class VorbisDecodeInputPin 
-	:	public AbstractTransformInputPin
-	,	public IOggDecoder
+    :    public AbstractTransformInputPin
+    ,    public IOggDecoder
+    ,    public IDownmixAudio
 {
 public:
 
-	DECLARE_IUNKNOWN
-	STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
+    DECLARE_IUNKNOWN
+    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
 
-	VorbisDecodeInputPin(AbstractTransformFilter* inFilter, CCritSec* inFilterLock, AbstractTransformOutputPin* inOutputPin, vector<CMediaType*> inAcceptableMediaTypes);
-	virtual ~VorbisDecodeInputPin(void);
+    VorbisDecodeInputPin(AbstractTransformFilter* inFilter, CCritSec* inFilterLock, AbstractTransformOutputPin* inOutputPin, vector<CMediaType*> inAcceptableMediaTypes);
+    virtual ~VorbisDecodeInputPin(void);
 
-	virtual HRESULT SetMediaType(const CMediaType* inMediaType);
-	virtual HRESULT CheckMediaType(const CMediaType *inMediaType);
-	virtual STDMETHODIMP NewSegment(REFERENCE_TIME inStartTime, REFERENCE_TIME inStopTime, double inRate);
-	virtual STDMETHODIMP EndFlush();
+    virtual HRESULT SetMediaType(const CMediaType* inMediaType);
+    virtual HRESULT CheckMediaType(const CMediaType *inMediaType);
+    virtual STDMETHODIMP NewSegment(REFERENCE_TIME inStartTime, REFERENCE_TIME inStopTime, double inRate);
+    virtual STDMETHODIMP EndFlush();
 
-	virtual STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES *outRequestedProps);
-	virtual HRESULT CompleteConnect(IPin *inReceivePin);
+    virtual STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES *outRequestedProps);
+    virtual HRESULT CompleteConnect(IPin *inReceivePin);
 
-	//Overriden from AbstractTransform input pin
-	virtual STDMETHODIMP Receive(IMediaSample* inSample);
+    //Overriden from AbstractTransform input pin
+    virtual STDMETHODIMP Receive(IMediaSample* inSample);
 
-	//IOggDecoder Interface
-	virtual LOOG_INT64 __stdcall convertGranuleToTime(LOOG_INT64 inGranule);
-	virtual LOOG_INT64 __stdcall mustSeekBefore(LOOG_INT64 inGranule);
-	virtual IOggDecoder::eAcceptHeaderResult __stdcall showHeaderPacket(OggPacket* inCodecHeaderPacket);
-	virtual string __stdcall getCodecShortName();
-	virtual string __stdcall getCodecIdentString();
+    //IOggDecoder Interface
+    virtual LOOG_INT64 __stdcall convertGranuleToTime(LOOG_INT64 inGranule);
+    virtual LOOG_INT64 __stdcall mustSeekBefore(LOOG_INT64 inGranule);
+    virtual IOggDecoder::eAcceptHeaderResult __stdcall showHeaderPacket(OggPacket* inCodecHeaderPacket);
+    virtual string __stdcall getCodecShortName();
+    virtual string __stdcall getCodecIdentString();
 
+    //IDownmixAudio Interface
+    virtual void __stdcall setDownmixAudio(const bool setDownmix);
+    virtual bool __stdcall getDownmixAudio();
+
 protected:
-	static const unsigned long DECODED_BUFFER_SIZE = 1<<20;		//1 Meg buffer
+    static const unsigned long DECODED_BUFFER_SIZE = 1<<21;        //2 Meg buffer
 
-	enum eVorbisSetupState {
-		VSS_SEEN_NOTHING,
-		VSS_SEEN_BOS,
-		VSS_SEEN_COMMENT,
-		VSS_ALL_HEADERS_SEEN,
-		VSS_ERROR
-	};
+    enum eVorbisSetupState {
+        VSS_SEEN_NOTHING,
+        VSS_SEEN_BOS,
+        VSS_SEEN_COMMENT,
+        VSS_ALL_HEADERS_SEEN,
+        VSS_ERROR
+    };
 
-	eVorbisSetupState mSetupState;
+    eVorbisSetupState mSetupState;
 
-	static const unsigned long VORBIS_IDENT_HEADER_SIZE = 30;
+    static const unsigned long VORBIS_IDENT_HEADER_SIZE = 30;
 
 #ifdef WINCE
-	static const unsigned long VORBIS_NUM_BUFFERS = 50;
-	static const unsigned long VORBIS_BUFFER_SIZE = 8192;
+    static const unsigned long VORBIS_NUM_BUFFERS = 50;
+    static const unsigned long VORBIS_BUFFER_SIZE = 8192;
 
 #else
-	static const unsigned long VORBIS_NUM_BUFFERS = 75;
-	static const unsigned long VORBIS_BUFFER_SIZE = 65536;
+    static const unsigned long VORBIS_NUM_BUFFERS = 75;
+    static const unsigned long VORBIS_BUFFER_SIZE = 65536;
 #endif
 
-	//Implementation of virtuals from AbstractTransform Filter
-	virtual bool ConstructCodec();
-	virtual void DestroyCodec();
-	virtual HRESULT TransformData(unsigned char* inBuf, long inNumBytes);
-	virtual HRESULT TransformVorbis2(const BYTE* const in_buffer, const long size_of_in_buffer); 
+    //Implementation of virtuals from AbstractTransform Filter
+    virtual bool ConstructCodec();
+    virtual void DestroyCodec();
+    virtual HRESULT TransformData(unsigned char* inBuf, long inNumBytes);
+    virtual HRESULT TransformVorbis2(const BYTE* const in_buffer, const long size_of_in_buffer); 
 
     void reorderChannels(unsigned char* inDestBuffer, const unsigned char* inSourceBuffer, unsigned long inNumBytes);
 
-	VorbisDecodeFilter* GetFilter();
+    VorbisDecodeFilter* GetFilter();
 
-	//TODO::: Are these needed?
-	bool mBegun;
-	//unsigned int mUptoFrame;
-	//HRESULT mHR;
+    //TODO::: Are these needed?
+    bool mBegun;
+    //unsigned int mUptoFrame;
+    //HRESULT mHR;
 
-	int mNumChannels;
-	int mFrameSize;
-	int mSampleRate;
+    int mNumChannels;
+    int mFrameSize;
+    int mSampleRate;
 
-	VorbisDecoder mVorbisDecoder;
+    VorbisDecoder mVorbisDecoder;
 
-	unsigned char* mDecodedBuffer;
-	unsigned long mDecodedByteCount;
+    unsigned char* mDecodedBuffer;
+    unsigned long mDecodedByteCount;
 
-	__int64 mRateNumerator;
-	static const __int64 RATE_DENOMINATOR = 65536;
+    __int64 mRateNumerator;
+    static const __int64 RATE_DENOMINATOR = 65536;
 
-	IOggOutputPin* mOggOutputPinInterface;
-	bool mSentStreamOffset;
+    IOggOutputPin* mOggOutputPinInterface;
+    bool mSentStreamOffset;
 
 private:
-	bool m_isVorbisFormat2;
+    bool m_isVorbisFormat2;
+    bool m_isDownmix;
 };
 

Modified: trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeOutputPin.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeOutputPin.cpp	2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeOutputPin.cpp	2010-12-15 20:24:02 UTC (rev 17758)
@@ -58,7 +58,8 @@
     HRESULT hr = AbstractTransformOutputPin::DecideBufferSize(inAllocator, inReqAllocProps);
 
     LOG(logINFO) << "Desired buffer size: " << mDesiredBufferSize << ", buffers: " << mDesiredBufferCount
-        << " Actual buffer size: " << mActualBufferSize << ", buffers: " << mActualBufferCount;
+        << " Actual buffer size: " << mActualBufferSize << ", buffers: " << mActualBufferCount
+        << " Result: 0x" << std::hex << hr;
     
     return hr;
 }
@@ -127,22 +128,26 @@
             break;
         case 3:
             formatEx->dwChannelMask = SPEAKER_FRONT_LEFT
-                | SPEAKER_FRONT_RIGHT
-                | SPEAKER_FRONT_CENTER;
+                                    | SPEAKER_FRONT_RIGHT
+                                    | SPEAKER_FRONT_CENTER;
             break;
         case 4:
             formatEx->dwChannelMask = KSAUDIO_SPEAKER_QUAD;
             break;
         case 5:
             formatEx->dwChannelMask = SPEAKER_FRONT_LEFT
-                | SPEAKER_FRONT_RIGHT
-                | SPEAKER_FRONT_CENTER
-                | SPEAKER_BACK_LEFT
-                | SPEAKER_BACK_RIGHT;
+                                    | SPEAKER_FRONT_RIGHT
+                                    | SPEAKER_FRONT_CENTER
+                                    | SPEAKER_BACK_LEFT
+                                    | SPEAKER_BACK_RIGHT;
             break;
         case 6:
             formatEx->dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
             break;
+        case 7:
+            formatEx->dwChannelMask = KSAUDIO_SPEAKER_5POINT1_SURROUND 
+                                    | SPEAKER_BACK_CENTER;
+            break;
         case 8:
             formatEx->dwChannelMask = KSAUDIO_SPEAKER_7POINT1_SURROUND;
             break;

Modified: trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncoder.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncoder.cpp	2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncoder.cpp	2010-12-15 20:24:02 UTC (rev 17758)
@@ -105,8 +105,6 @@
 
 vector<StampedOggPacket*> VorbisEncoder::encodeVorbis(const short* const inSampleBuffer, unsigned long inNumSamplesPerChannel)
 {
-    //TODO::: Handle 5 channel input
-
     if (inNumSamplesPerChannel == 0) {
         return vector<StampedOggPacket*>();
     }
@@ -115,8 +113,50 @@
 
     float* locOneOutputChannelBuffer = NULL;
     const short* locReadChannelBuffer = NULL;
+
+	const short* channel_order;
+	const short channel_order_mono[] = {0};
+	const short channel_order_stereo[] = {0, 1};
+	const short channel_order_three[] = {0, 2, 1};
+	const short channel_order_four[] = {0, 1, 2, 3};
+	const short channel_order_five[] = {0, 2, 1, 3, 4};
+	const short channel_order_5_1[] = {0, 2, 1, 5, 3, 4};
+	const short channel_order_6_1[] = {0, 2, 1, 6, 5, 3, 4};
+	const short channel_order_7_1[] = {0, 2, 1, 7, 5, 6, 3, 4};
+
+	switch (mSettings.mNumChannels) {
+        case 1: // mono ch. 
+		    channel_order = channel_order_mono;
+            break;
+        case 2: // stereo ch. 
+		    channel_order = channel_order_stereo;
+            break;
+        case 3: // 3 ch. 
+			channel_order = channel_order_three;
+            break;
+        case 4: // 4 ch. 
+			channel_order = channel_order_four;
+            break;
+        case 5: // 5 ch. 
+			channel_order = channel_order_five;
+            break;
+        case 6: // 5.1 ch. 
+			channel_order = channel_order_5_1;
+            break;
+        case 7: // 6.1 ch. 
+			channel_order = channel_order_6_1;
+            break;
+        case 8: // 7.1 ch.
+			channel_order = channel_order_7_1;
+            break;
+		default:
+			channel_order = channel_order_mono;  //?
+			break;
+	}
+
     for (unsigned long chan = 0; chan < mSettings.mNumChannels; chan++) {
-        locOneOutputChannelBuffer = locBuffer[chan];
+        //locOneOutputChannelBuffer = locBuffer[chan];
+        locOneOutputChannelBuffer = locBuffer[channel_order[chan]];
         locReadChannelBuffer = inSampleBuffer + chan;
 
         for (unsigned long sam = 0; sam < inNumSamplesPerChannel; sam++) {

Modified: trunk/oggdsf/src/lib/helper/common/VorbisTypes.h
===================================================================
--- trunk/oggdsf/src/lib/helper/common/VorbisTypes.h	2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/src/lib/helper/common/VorbisTypes.h	2010-12-15 20:24:02 UTC (rev 17758)
@@ -82,4 +82,8 @@
 DEFINE_GUID(CLSID_VorbisDecodeFilter, 
 0x5a1d945, 0xa794, 0x44ef, 0xb4, 0x1a, 0x2f, 0x85, 0x1a, 0x11, 0x71, 0x55);
 
+// {BFF86BE7-9E32-40EF-B200-7BCC7800CC72}
+DEFINE_GUID(IID_IDownmixAudio, 
+0xBFF86BE7, 0x9E32, 0x40EF, 0xB2, 0x00, 0x7B, 0xCC, 0x78, 0x00, 0xCC, 0x72);
+
 #endif // VORBISTYPES_H
\ No newline at end of file



More information about the commits mailing list