mirror of
https://github.com/clangen/musikcube.git
synced 2025-03-14 13:21:13 +00:00
Fixed macOS compile and deleted a couple dead plugins.
This commit is contained in:
parent
f97f6ca86b
commit
99e7a48013
@ -61,7 +61,7 @@ static inline bool playable(snd_pcm_t* pcm) {
|
||||
state == SND_PCM_STATE_PREPARED;
|
||||
}
|
||||
|
||||
using namespace musik::core::audio;
|
||||
using namespace musik::core::sdk;
|
||||
|
||||
AlsaOut::AlsaOut()
|
||||
: pcmHandle(NULL)
|
||||
|
@ -44,8 +44,6 @@
|
||||
#include <boost/thread/condition.hpp>
|
||||
#include <list>
|
||||
|
||||
using namespace musik::core::audio;
|
||||
|
||||
class AlsaOut : public IOutput {
|
||||
public:
|
||||
AlsaOut();
|
||||
@ -58,17 +56,17 @@ class AlsaOut : public IOutput {
|
||||
virtual void Stop();
|
||||
|
||||
virtual bool Play(
|
||||
musik::core::audio::IBuffer *buffer,
|
||||
musik::core::audio::IBufferProvider *provider);
|
||||
musik::core::sdk::IBuffer *buffer,
|
||||
musik::core::sdk::IBufferProvider *provider);
|
||||
|
||||
private:
|
||||
struct BufferContext {
|
||||
musik::core::audio::IBuffer *buffer;
|
||||
musik::core::audio::IBufferProvider *provider;
|
||||
musik::core::sdk::IBuffer *buffer;
|
||||
musik::core::sdk::IBufferProvider *provider;
|
||||
};
|
||||
|
||||
size_t CountBuffersWithProvider(IBufferProvider* provider);
|
||||
void SetFormat(musik::core::audio::IBuffer *buffer);
|
||||
size_t CountBuffersWithProvider(musik::core::sdk::IBufferProvider* provider);
|
||||
void SetFormat(musik::core::sdk::IBuffer *buffer);
|
||||
void InitDevice();
|
||||
void CloseDevice();
|
||||
void WriteLoop();
|
||||
|
@ -37,17 +37,17 @@
|
||||
#include <core/sdk/IOutput.h>
|
||||
#include "AlsaOut.h"
|
||||
|
||||
class AlsaOutPlugin : public musik::core::IPlugin {
|
||||
class AlsaOutPlugin : public musik::core::sdk::IPlugin {
|
||||
virtual void Destroy() { delete this; };
|
||||
virtual const char* Name() { return "AlsaOut IOutput plugin"; }
|
||||
virtual const char* Version() { return "0.2"; }
|
||||
virtual const char* Version() { return "0.3"; }
|
||||
virtual const char* Author() { return "Julian Cromarty, clangen"; }
|
||||
};
|
||||
|
||||
extern "C" musik::core::IPlugin* GetPlugin() {
|
||||
extern "C" musik::core::sdk::IPlugin* GetPlugin() {
|
||||
return new AlsaOutPlugin();
|
||||
}
|
||||
|
||||
extern "C" musik::core::audio::IOutput* GetAudioOutput() {
|
||||
extern "C" musik::core::sdk::IOutput* GetAudioOutput() {
|
||||
return new AlsaOut();
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
||||
class CddaDecoderPlugin : public musik::core::sdk::IPlugin {
|
||||
void Destroy() { delete this; };
|
||||
const char* Name() { return "CD Audio (CDDA) IDecoder"; };
|
||||
const char* Version() { return "0.2"; };
|
||||
const char* Version() { return "0.3"; };
|
||||
const char* Author() { return "Björn Olievier, clangen"; };
|
||||
};
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
|
||||
#define BUFFER_COUNT 16
|
||||
|
||||
using namespace musik::core::audio;
|
||||
using namespace musik::core::sdk;
|
||||
|
||||
void audioCallback(void *customData, AudioQueueRef queue, AudioQueueBufferRef buffer) {
|
||||
CoreAudioOut* output = (CoreAudioOut *) customData;
|
||||
|
@ -44,11 +44,11 @@
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#include <CoreFoundation/CFRunLoop.h>
|
||||
|
||||
class CoreAudioOut : public musik::core::audio::IOutput {
|
||||
class CoreAudioOut : public musik::core::sdk::IOutput {
|
||||
public:
|
||||
struct BufferContext {
|
||||
musik::core::audio::IBuffer *buffer;
|
||||
musik::core::audio::IBufferProvider *provider;
|
||||
musik::core::sdk::IBuffer *buffer;
|
||||
musik::core::sdk::IBufferProvider *provider;
|
||||
};
|
||||
|
||||
CoreAudioOut();
|
||||
@ -61,8 +61,8 @@ class CoreAudioOut : public musik::core::audio::IOutput {
|
||||
virtual void Stop();
|
||||
|
||||
virtual bool Play(
|
||||
musik::core::audio::IBuffer *buffer,
|
||||
musik::core::audio::IBufferProvider *provider);
|
||||
musik::core::sdk::IBuffer *buffer,
|
||||
musik::core::sdk::IBufferProvider *provider);
|
||||
|
||||
void NotifyBufferCompleted(BufferContext *context);
|
||||
|
||||
|
@ -48,17 +48,17 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
||||
}
|
||||
#endif
|
||||
|
||||
class CoreAudioOutPlugin : public musik::core::IPlugin {
|
||||
class CoreAudioOutPlugin : public musik::core::sdk::IPlugin {
|
||||
void Destroy() { delete this; };
|
||||
const char* Name() { return "CoreAudio IOutput"; };
|
||||
const char* Version() { return "0.1"; };
|
||||
const char* Version() { return "0.2"; };
|
||||
const char* Author() { return "clangen"; };
|
||||
};
|
||||
|
||||
extern "C" DLLEXPORT musik::core::IPlugin* GetPlugin() {
|
||||
extern "C" DLLEXPORT musik::core::sdk::IPlugin* GetPlugin() {
|
||||
return new CoreAudioOutPlugin;
|
||||
}
|
||||
|
||||
extern "C" DLLEXPORT musik::core::audio::IOutput* GetAudioOutput() {
|
||||
extern "C" DLLEXPORT musik::core::sdk::IOutput* GetAudioOutput() {
|
||||
return new CoreAudioOut();
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
||||
class FlacPlugin : public musik::core::sdk::IPlugin {
|
||||
void Destroy() { delete this; };
|
||||
const char* Name() { return "FLAC IDecoder"; }
|
||||
const char* Version() { return "0.2"; }
|
||||
const char* Version() { return "0.3"; }
|
||||
const char* Author() { return "Daniel Önnerby, clangen"; }
|
||||
};
|
||||
|
||||
|
@ -53,7 +53,7 @@ class AacDecoderPlugin : public musik::core::sdk::IPlugin {
|
||||
public:
|
||||
virtual void Destroy() { delete this; };
|
||||
virtual const char* Name() { return "M4A IDecoder"; };
|
||||
virtual const char* Version() { return "0.2"; };
|
||||
virtual const char* Version() { return "0.3"; };
|
||||
virtual const char* Author() { return "Björn Olievier, clangen"; };
|
||||
};
|
||||
|
||||
|
@ -1,459 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2002 Tony Million
|
||||
|
||||
This software is provided 'as-is', without any express or
|
||||
implied warranty. In no event will the authors be held liable
|
||||
for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it
|
||||
and redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. The origin of this software must not be
|
||||
misrepresented; you must not claim that you wrote
|
||||
the original software. If you use this software in a
|
||||
product, an acknowledgment in the product
|
||||
documentation is required.
|
||||
|
||||
2. Altered source versions must be plainly marked as
|
||||
such, and must not be misrepresented as being the
|
||||
original software.
|
||||
|
||||
3. This notice may not be removed or altered from any
|
||||
source distribution.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <math.h>
|
||||
#include "BaseDecoder.h"
|
||||
|
||||
const float CBaseDecoder::D[512] =
|
||||
{
|
||||
0.000000000f, -0.000015259f, -0.000015259f, -0.000015259f, -0.000015259f, -0.000015259f, -0.000015259f, -0.000030518f,
|
||||
-0.000030518f, -0.000030518f, -0.000030518f, -0.000045776f, -0.000045776f, -0.000061035f, -0.000061035f, -0.000076294f,
|
||||
-0.000076294f, -0.000091553f, -0.000106812f, -0.000106812f, -0.000122070f, -0.000137329f, -0.000152588f, -0.000167847f,
|
||||
-0.000198364f, -0.000213623f, -0.000244141f, -0.000259399f, -0.000289917f, -0.000320435f, -0.000366211f, -0.000396729f,
|
||||
|
||||
-0.000442505f, -0.000473022f, -0.000534058f, -0.000579834f, -0.000625610f, -0.000686646f, -0.000747681f, -0.000808716f,
|
||||
-0.000885010f, -0.000961304f, -0.001037598f, -0.001113892f, -0.001205444f, -0.001296997f, -0.001388550f, -0.001480103f,
|
||||
-0.001586914f, -0.001693726f, -0.001785278f, -0.001907349f, -0.002014160f, -0.002120972f, -0.002243042f, -0.002349854f,
|
||||
-0.002456665f, -0.002578735f, -0.002685547f, -0.002792358f, -0.002899170f, -0.002990723f, -0.003082275f, -0.003173828f,
|
||||
|
||||
0.003250122f, 0.003326416f, 0.003387451f, 0.003433228f, 0.003463745f, 0.003479004f, 0.003479004f, 0.003463745f,
|
||||
0.003417969f, 0.003372192f, 0.003280640f, 0.003173828f, 0.003051758f, 0.002883911f, 0.002700806f, 0.002487183f,
|
||||
0.002227783f, 0.001937866f, 0.001617432f, 0.001266479f, 0.000869751f, 0.000442505f, -0.000030518f, -0.000549316f,
|
||||
-0.001098633f, -0.001693726f, -0.002334595f, -0.003005981f, -0.003723145f, -0.004486084f, -0.005294800f, -0.006118774f,
|
||||
|
||||
-0.007003784f, -0.007919312f, -0.008865356f, -0.009841919f, -0.010848999f, -0.011886597f, -0.012939453f, -0.014022827f,
|
||||
-0.015121460f, -0.016235352f, -0.017349243f, -0.018463135f, -0.019577026f, -0.020690918f, -0.021789551f, -0.022857666f,
|
||||
-0.023910522f, -0.024932861f, -0.025909424f, -0.026840210f, -0.027725220f, -0.028533936f, -0.029281616f, -0.029937744f,
|
||||
-0.030532837f, -0.031005859f, -0.031387329f, -0.031661987f, -0.031814575f, -0.031845093f, -0.031738281f, -0.031478882f,
|
||||
|
||||
0.031082153f, 0.030517578f, 0.029785156f, 0.028884888f, 0.027801514f, 0.026535034f, 0.025085449f, 0.023422241f,
|
||||
0.021575928f, 0.019531250f, 0.017257690f, 0.014801025f, 0.012115479f, 0.009231567f, 0.006134033f, 0.002822876f,
|
||||
-0.000686646f, -0.004394531f, -0.008316040f, -0.012420654f, -0.016708374f, -0.021179199f, -0.025817871f, -0.030609131f,
|
||||
-0.035552979f, -0.040634155f, -0.045837402f, -0.051132202f, -0.056533813f, -0.061996460f, -0.067520142f, -0.073059082f,
|
||||
|
||||
-0.078628540f, -0.084182739f, -0.089706421f, -0.095169067f, -0.100540161f, -0.105819702f, -0.110946655f, -0.115921021f,
|
||||
-0.120697021f, -0.125259399f, -0.129562378f, -0.133590698f, -0.137298584f, -0.140670776f, -0.143676758f, -0.146255493f,
|
||||
-0.148422241f, -0.150115967f, -0.151306152f, -0.151962280f, -0.152069092f, -0.151596069f, -0.150497437f, -0.148773193f,
|
||||
-0.146362305f, -0.143264771f, -0.139450073f, -0.134887695f, -0.129577637f, -0.123474121f, -0.116577148f, -0.108856201f,
|
||||
|
||||
0.100311279f, 0.090927124f, 0.080688477f, 0.069595337f, 0.057617187f, 0.044784546f, 0.031082153f, 0.016510010f,
|
||||
0.001068115f, -0.015228271f, -0.032379150f, -0.050354004f, -0.069168091f, -0.088775635f, -0.109161377f, -0.130310059f,
|
||||
-0.152206421f, -0.174789429f, -0.198059082f, -0.221984863f, -0.246505737f, -0.271591187f, -0.297210693f, -0.323318481f,
|
||||
-0.349868774f, -0.376800537f, -0.404083252f, -0.431655884f, -0.459472656f, -0.487472534f, -0.515609741f, -0.543823242f,
|
||||
|
||||
-0.572036743f, -0.600219727f, -0.628295898f, -0.656219482f, -0.683914185f, -0.711318970f, -0.738372803f, -0.765029907f,
|
||||
-0.791213989f, -0.816864014f, -0.841949463f, -0.866363525f, -0.890090942f, -0.913055420f, -0.935195923f, -0.956481934f,
|
||||
-0.976852417f, -0.996246338f, -1.014617920f, -1.031936646f, -1.048156738f, -1.063217163f, -1.077117920f, -1.089782715f,
|
||||
-1.101211548f, -1.111373901f, -1.120223999f, -1.127746582f, -1.133926392f, -1.138763428f, -1.142211914f, -1.144287109f,
|
||||
|
||||
1.144989014f, 1.144287109f, 1.142211914f, 1.138763428f, 1.133926392f, 1.127746582f, 1.120223999f, 1.111373901f,
|
||||
1.101211548f, 1.089782715f, 1.077117920f, 1.063217163f, 1.048156738f, 1.031936646f, 1.014617920f, 0.996246338f,
|
||||
0.976852417f, 0.956481934f, 0.935195923f, 0.913055420f, 0.890090942f, 0.866363525f, 0.841949463f, 0.816864014f,
|
||||
0.791213989f, 0.765029907f, 0.738372803f, 0.711318970f, 0.683914185f, 0.656219482f, 0.628295898f, 0.600219727f,
|
||||
|
||||
0.572036743f, 0.543823242f, 0.515609741f, 0.487472534f, 0.459472656f, 0.431655884f, 0.404083252f, 0.376800537f,
|
||||
0.349868774f, 0.323318481f, 0.297210693f, 0.271591187f, 0.246505737f, 0.221984863f, 0.198059082f, 0.174789429f,
|
||||
0.152206421f, 0.130310059f, 0.109161377f, 0.088775635f, 0.069168091f, 0.050354004f, 0.032379150f, 0.015228271f,
|
||||
-0.001068115f, -0.016510010f, -0.031082153f, -0.044784546f, -0.057617187f, -0.069595337f, -0.080688477f, -0.090927124f,
|
||||
|
||||
0.100311279f, 0.108856201f, 0.116577148f, 0.123474121f, 0.129577637f, 0.134887695f, 0.139450073f, 0.143264771f,
|
||||
0.146362305f, 0.148773193f, 0.150497437f, 0.151596069f, 0.152069092f, 0.151962280f, 0.151306152f, 0.150115967f,
|
||||
0.148422241f, 0.146255493f, 0.143676758f, 0.140670776f, 0.137298584f, 0.133590698f, 0.129562378f, 0.125259399f,
|
||||
0.120697021f, 0.115921021f, 0.110946655f, 0.105819702f, 0.100540161f, 0.095169067f, 0.089706421f, 0.084182739f,
|
||||
|
||||
0.078628540f, 0.073059082f, 0.067520142f, 0.061996460f, 0.056533813f, 0.051132202f, 0.045837402f, 0.040634155f,
|
||||
0.035552979f, 0.030609131f, 0.025817871f, 0.021179199f, 0.016708374f, 0.012420654f, 0.008316040f, 0.004394531f,
|
||||
0.000686646f, -0.002822876f, -0.006134033f, -0.009231567f, -0.012115479f, -0.014801025f, -0.017257690f, -0.019531250f,
|
||||
-0.021575928f, -0.023422241f, -0.025085449f, -0.026535034f, -0.027801514f, -0.028884888f, -0.029785156f, -0.030517578f,
|
||||
|
||||
0.031082153f, 0.031478882f, 0.031738281f, 0.031845093f, 0.031814575f, 0.031661987f, 0.031387329f, 0.031005859f,
|
||||
0.030532837f, 0.029937744f, 0.029281616f, 0.028533936f, 0.027725220f, 0.026840210f, 0.025909424f, 0.024932861f,
|
||||
0.023910522f, 0.022857666f, 0.021789551f, 0.020690918f, 0.019577026f, 0.018463135f, 0.017349243f, 0.016235352f,
|
||||
0.015121460f, 0.014022827f, 0.012939453f, 0.011886597f, 0.010848999f, 0.009841919f, 0.008865356f, 0.007919312f,
|
||||
|
||||
0.007003784f, 0.006118774f, 0.005294800f, 0.004486084f, 0.003723145f, 0.003005981f, 0.002334595f, 0.001693726f,
|
||||
0.001098633f, 0.000549316f, 0.000030518f, -0.000442505f, -0.000869751f, -0.001266479f, -0.001617432f, -0.001937866f,
|
||||
-0.002227783f, -0.002487183f, -0.002700806f, -0.002883911f, -0.003051758f, -0.003173828f, -0.003280640f, -0.003372192f,
|
||||
-0.003417969f, -0.003463745f, -0.003479004f, -0.003479004f, -0.003463745f, -0.003433228f, -0.003387451f, -0.003326416f,
|
||||
|
||||
0.003250122f, 0.003173828f, 0.003082275f, 0.002990723f, 0.002899170f, 0.002792358f, 0.002685547f, 0.002578735f,
|
||||
0.002456665f, 0.002349854f, 0.002243042f, 0.002120972f, 0.002014160f, 0.001907349f, 0.001785278f, 0.001693726f,
|
||||
0.001586914f, 0.001480103f, 0.001388550f, 0.001296997f, 0.001205444f, 0.001113892f, 0.001037598f, 0.000961304f,
|
||||
0.000885010f, 0.000808716f, 0.000747681f, 0.000686646f, 0.000625610f, 0.000579834f, 0.000534058f, 0.000473022f,
|
||||
|
||||
0.000442505f, 0.000396729f, 0.000366211f, 0.000320435f, 0.000289917f, 0.000259399f, 0.000244141f, 0.000213623f,
|
||||
0.000198364f, 0.000167847f, 0.000152588f, 0.000137329f, 0.000122070f, 0.000106812f, 0.000106812f, 0.000091553f,
|
||||
0.000076294f, 0.000076294f, 0.000061035f, 0.000061035f, 0.000045776f, 0.000045776f, 0.000030518f, 0.000030518f,
|
||||
0.000030518f, 0.000030518f, 0.000015259f, 0.000015259f, 0.000015259f, 0.000015259f, 0.000015259f, 0.000015259f
|
||||
};
|
||||
|
||||
|
||||
CBaseDecoder::CBaseDecoder()
|
||||
{
|
||||
int i,j;
|
||||
float t16[16][16], t8[8][8];
|
||||
|
||||
/* assign and clear the subband synthesis V buffer */
|
||||
|
||||
for(i = 0; i < 2; i++)
|
||||
for(j = 0; j < 1024; j++)
|
||||
V[i][j] = (float)0.0f;
|
||||
|
||||
/* create the 16 matrixes */
|
||||
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
for(j = 0; j < 16; j++)
|
||||
{
|
||||
A16[i][j] = (float)cos((2*j+1)*i*PI/32);
|
||||
if(i == j || j == (i + 1))
|
||||
G16[i][j] = 1.0f;
|
||||
else
|
||||
G16[i][j] = 0.0f;
|
||||
|
||||
if(i == j)
|
||||
H16[i][j] = 1.0f/(2.0f*(float)cos((2*i+1)*PI/64));
|
||||
else
|
||||
H16[i][j] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
/* create the 8 matrixes */
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
for(j = 0; j < 8; j++)
|
||||
{
|
||||
A8[i][j] = (float)cos((2*j+1)*i*PI/16);
|
||||
if(i == j || j == (i + 1))
|
||||
G8[i][j] = 1.0f;
|
||||
else
|
||||
G8[i][j] = 0.0f;
|
||||
|
||||
if(i == j)
|
||||
H8[i][j] = 1.0f/(2.0f*(float)cos((2*i+1)*PI/32));
|
||||
else
|
||||
H8[i][j] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/* generate the B matrixes */
|
||||
|
||||
MultiplyMatrix16(A16, H16, t16);
|
||||
MultiplyMatrix16(G16, t16, B16);
|
||||
|
||||
MultiplyMatrix8(A8, H8, t8);
|
||||
MultiplyMatrix8(G8, t8, B8);
|
||||
|
||||
int a, o = 0;
|
||||
|
||||
for (j = 0; j < 32; j++)
|
||||
{
|
||||
a = j;
|
||||
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
DTable[o] = D[a];
|
||||
o++;
|
||||
|
||||
DTable[o] = D[a+32];
|
||||
o++;
|
||||
|
||||
DTable[o] = D[a+64];
|
||||
o++;
|
||||
|
||||
DTable[o] = D[a+96];
|
||||
o++;
|
||||
|
||||
a+=128;
|
||||
}
|
||||
}
|
||||
|
||||
Vpointer[0] = 64;
|
||||
Vpointer[1] = 64;
|
||||
}
|
||||
|
||||
CBaseDecoder::~CBaseDecoder()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool CBaseDecoder::PerformSynthesis(float *InputFreq, float *ToHere, int Channel, int step)
|
||||
{
|
||||
if(Channel)
|
||||
ToHere ++;
|
||||
|
||||
/* We have 18 time-vectors of 32 subband magnitudes each. For every
|
||||
vector of 32 magnitudes, the subband synthesis generates 32
|
||||
PCM samples, so the result of 18 of these is 18*32=576 samples.
|
||||
*/
|
||||
|
||||
/* advance the buffer position */
|
||||
Vpointer[Channel] = (Vpointer[Channel] - 64) & 0x3ff;
|
||||
|
||||
IDCT(InputFreq, &V[ Channel ][ Vpointer[Channel] ]);
|
||||
|
||||
/* 32*16=512 mac's */
|
||||
|
||||
Window(Channel, ToHere, step);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
void __forceinline CBaseDecoder::IDCT(float *input, float *out)
|
||||
{
|
||||
float odd[16];
|
||||
float t[32];
|
||||
|
||||
float s1, s2;
|
||||
|
||||
int i;
|
||||
int offset1 = 0;
|
||||
int offset = 0;
|
||||
int ti = 0; // table index
|
||||
|
||||
float even[16], ee[8], eo[8];
|
||||
|
||||
/* input butterflies - level 1 */
|
||||
/* 32 adds */
|
||||
|
||||
even[0] = input[0] + input[31];
|
||||
even[1] = input[1] + input[30];
|
||||
even[2] = input[2] + input[29];
|
||||
even[3] = input[3] + input[28];
|
||||
even[4] = input[4] + input[27];
|
||||
even[5] = input[5] + input[26];
|
||||
even[6] = input[6] + input[25];
|
||||
even[7] = input[7] + input[24];
|
||||
even[8] = input[8] + input[23];
|
||||
even[9] = input[9] + input[22];
|
||||
even[10] = input[10] + input[21];
|
||||
even[11] = input[11] + input[20];
|
||||
even[12] = input[12] + input[19];
|
||||
even[13] = input[13] + input[18];
|
||||
even[14] = input[14] + input[17];
|
||||
even[15] = input[15] + input[16];
|
||||
|
||||
odd[0] = input[0] - input[31];
|
||||
odd[1] = input[1] - input[30];
|
||||
odd[2] = input[2] - input[29];
|
||||
odd[3] = input[3] - input[28];
|
||||
odd[4] = input[4] - input[27];
|
||||
odd[5] = input[5] - input[26];
|
||||
odd[6] = input[6] - input[25];
|
||||
odd[7] = input[7] - input[24];
|
||||
odd[8] = input[8] - input[23];
|
||||
odd[9] = input[9] - input[22];
|
||||
odd[10] = input[10] - input[21];
|
||||
odd[11] = input[11] - input[20];
|
||||
odd[12] = input[12] - input[19];
|
||||
odd[13] = input[13] - input[18];
|
||||
odd[14] = input[14] - input[17];
|
||||
odd[15] = input[15] - input[16];
|
||||
|
||||
/* input butterflies - level 2 */
|
||||
/* 16 adds */
|
||||
|
||||
ee[0] = even[0] + even[15];
|
||||
ee[1] = even[1] + even[14];
|
||||
ee[2] = even[2] + even[13];
|
||||
ee[3] = even[3] + even[12];
|
||||
ee[4] = even[4] + even[11];
|
||||
ee[5] = even[5] + even[10];
|
||||
ee[6] = even[6] + even[9];
|
||||
ee[7] = even[7] + even[8];
|
||||
|
||||
eo[0] = even[0] - even[15];
|
||||
eo[1] = even[1] - even[14];
|
||||
eo[2] = even[2] - even[13];
|
||||
eo[3] = even[3] - even[12];
|
||||
eo[4] = even[4] - even[11];
|
||||
eo[5] = even[5] - even[10];
|
||||
eo[6] = even[6] - even[9];
|
||||
eo[7] = even[7] - even[8];
|
||||
|
||||
|
||||
/* multiply the even_even vector (ee) with the ee matrix (A8) */
|
||||
/* multiply the even_odd vector (eo) with the eo matrix (B8) */
|
||||
/* 128 muls, 128 adds */
|
||||
|
||||
i=8;
|
||||
|
||||
do
|
||||
{
|
||||
s1 = A8[ti][0] * ee[0];
|
||||
s1 += A8[ti][1] * ee[1];
|
||||
s1 += A8[ti][2] * ee[2];
|
||||
s1 += A8[ti][3] * ee[3];
|
||||
s1 += A8[ti][4] * ee[4];
|
||||
s1 += A8[ti][5] * ee[5];
|
||||
s1 += A8[ti][6] * ee[6];
|
||||
s1 += A8[ti][7] * ee[7];
|
||||
|
||||
s2 = B8[ti][0] * eo[0];
|
||||
s2 += B8[ti][1] * eo[1];
|
||||
s2 += B8[ti][2] * eo[2];
|
||||
s2 += B8[ti][3] * eo[3];
|
||||
s2 += B8[ti][4] * eo[4];
|
||||
s2 += B8[ti][5] * eo[5];
|
||||
s2 += B8[ti][6] * eo[6];
|
||||
s2 += B8[ti][7] * eo[7];
|
||||
|
||||
t[offset1] = s1;
|
||||
t[offset1+2] = s2;
|
||||
|
||||
offset1 += 4;
|
||||
ti++;
|
||||
} while(--i);
|
||||
|
||||
|
||||
/* multiply the odd vector (odd) with the odd matrix (B16) */
|
||||
/* 256 muls, 256 adds */
|
||||
|
||||
i = 16;
|
||||
ti = 0;
|
||||
|
||||
do
|
||||
{
|
||||
s1 = B16[ti][0] * odd[0];
|
||||
s1 += B16[ti][1] * odd[1];
|
||||
s1 += B16[ti][2] * odd[2];
|
||||
s1 += B16[ti][3] * odd[3];
|
||||
s1 += B16[ti][4] * odd[4];
|
||||
s1 += B16[ti][5] * odd[5];
|
||||
s1 += B16[ti][6] * odd[6];
|
||||
s1 += B16[ti][7] * odd[7];
|
||||
s1 += B16[ti][8] * odd[8];
|
||||
s1 += B16[ti][9] * odd[9];
|
||||
s1 += B16[ti][10] * odd[10];
|
||||
s1 += B16[ti][11] * odd[11];
|
||||
s1 += B16[ti][12] * odd[12];
|
||||
s1 += B16[ti][13] * odd[13];
|
||||
s1 += B16[ti][14] * odd[14];
|
||||
s1 += B16[ti][15] * odd[15];
|
||||
|
||||
t[offset+1] = s1;
|
||||
|
||||
offset += 2;
|
||||
ti++;
|
||||
} while(--i);
|
||||
|
||||
/* the output vector t now is expanded to 64 values using the
|
||||
symmetric property of the cosinus function */
|
||||
|
||||
i = 16;
|
||||
ti = 0;
|
||||
|
||||
do
|
||||
{
|
||||
out[ti] = t[ti+16];
|
||||
out[ti+17] = -t[31-ti];
|
||||
out[ti+32] = -t[16-ti];
|
||||
out[ti+48] = -t[ti];
|
||||
|
||||
ti++;
|
||||
|
||||
} while(--i);
|
||||
|
||||
out[16] = 0.0;
|
||||
}
|
||||
|
||||
void __forceinline CBaseDecoder::Window(int ch, float *S, int step)
|
||||
{
|
||||
int j, k;
|
||||
register float sum;
|
||||
|
||||
//int a = 0;
|
||||
|
||||
/* calculate 32 samples. each sample is the sum of 16 terms */
|
||||
|
||||
/* 15 */
|
||||
/* Sj = E W((j*16)+i) */
|
||||
/* i=0 */
|
||||
|
||||
|
||||
k = Vpointer[ch];
|
||||
float * TV = V[ch];
|
||||
float * DT = DTable;
|
||||
|
||||
for(j = 0; j < 32; j++)
|
||||
{
|
||||
sum = DT[0x0] * TV[k];
|
||||
k = (k + 96) & 0x3ff;
|
||||
sum += DT[0x1] * TV[k];
|
||||
k = (k + 32) & 0x3ff;
|
||||
|
||||
sum += DT[0x2] * TV[k];
|
||||
k = (k + 96) & 0x3ff;
|
||||
sum += DT[0x3] * TV[k];
|
||||
k = (k + 32) & 0x3ff;
|
||||
|
||||
sum += DT[0x4] * TV[k];
|
||||
k = (k + 96) & 0x3ff;
|
||||
sum += DT[0x5] * TV[k];
|
||||
k = (k + 32) & 0x3ff;
|
||||
|
||||
sum += DT[0x6] * TV[k];
|
||||
k = (k + 96) & 0x3ff;
|
||||
sum += DT[0x7] * TV[k];
|
||||
k = (k + 32) & 0x3ff;
|
||||
|
||||
sum += DT[0x8] * TV[k];
|
||||
k = (k + 96) & 0x3ff;
|
||||
sum += DT[0x9] * TV[k];
|
||||
k = (k + 32) & 0x3ff;
|
||||
|
||||
sum += DT[0xA] * TV[k];
|
||||
k = (k + 96) & 0x3ff;
|
||||
sum += DT[0xB] * TV[k];
|
||||
k = (k + 32) & 0x3ff;
|
||||
|
||||
sum += DT[0xC] * TV[k];
|
||||
k = (k + 96) & 0x3ff;
|
||||
sum += DT[0xD] * TV[k];
|
||||
k = (k + 32) & 0x3ff;
|
||||
|
||||
sum += DT[0xE] * TV[k];
|
||||
k = (k + 96) & 0x3ff;
|
||||
sum += DT[0xF] * TV[k];
|
||||
k = (k + 32) & 0x3ff;
|
||||
|
||||
DT += 16;
|
||||
|
||||
|
||||
if( sum < -1.0 )
|
||||
sum = -1.0;
|
||||
else if( sum > 1.0 )
|
||||
sum = 1.0;
|
||||
*S = sum;
|
||||
|
||||
S+=step;
|
||||
k++;
|
||||
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2002 Tony Million
|
||||
|
||||
This software is provided 'as-is', without any express or
|
||||
implied warranty. In no event will the authors be held liable
|
||||
for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it
|
||||
and redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. The origin of this software must not be
|
||||
misrepresented; you must not claim that you wrote
|
||||
the original software. If you use this software in a
|
||||
product, an acknowledgment in the product
|
||||
documentation is required.
|
||||
|
||||
2. Altered source versions must be plainly marked as
|
||||
such, and must not be misrepresented as being the
|
||||
original software.
|
||||
|
||||
3. This notice may not be removed or altered from any
|
||||
source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IMPEGDecoder.h"
|
||||
|
||||
#define PI (3.1415926535897932384626433832795f)
|
||||
#define PI12 (0.2617993877991494365385536152732f)
|
||||
#define PI18 (0.17453292519943295769236907684886f)
|
||||
#define PI36 (0.0872664625997164788461845384244f)
|
||||
|
||||
#define SQRT2 (1.4142135623730950488016887242097f)
|
||||
|
||||
|
||||
class CBaseDecoder : public IMPEGDecoder
|
||||
{
|
||||
protected:
|
||||
float A16[16][16], A8[8][8]; /* DCT matrix */
|
||||
float G16[16][16], G8[8][8]; /* Output butterfly */
|
||||
float H16[16][16], H8[8][8]; /* Scaling */
|
||||
float B16[16][16], B8[8][8]; /* B = G * DCT * H */
|
||||
|
||||
float DTable[512];
|
||||
|
||||
float V[2][1024];
|
||||
int Vpointer[2];
|
||||
|
||||
static const float D[512];
|
||||
|
||||
void MultiplyMatrix16(float in1[16][16], float in2[16][16], float out[16][16])
|
||||
{
|
||||
int i,j,z;
|
||||
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
for(j = 0; j < 16; j++)
|
||||
{
|
||||
out[i][j] = 0.0;
|
||||
for(z = 0; z < 16; z++)
|
||||
out[i][j] += in1[i][z] * in2[z][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MultiplyMatrix8(float in1[8][8], float in2[8][8], float out[8][8])
|
||||
{
|
||||
int i,j,z;
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
for(j = 0; j < 8; j++)
|
||||
{
|
||||
out[i][j] = 0.0;
|
||||
for(z = 0; z < 8; z++)
|
||||
out[i][j] += in1[i][z] * in2[z][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IDCT(float *in, float *out);
|
||||
void Window(int ch, float *S, int step);
|
||||
bool PerformSynthesis(float *InputFreq, float *ToHere, int Channel, int step);
|
||||
|
||||
public:
|
||||
CBaseDecoder();
|
||||
virtual ~CBaseDecoder();
|
||||
|
||||
};
|
@ -1,144 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2002 Tony Million
|
||||
|
||||
This software is provided 'as-is', without any express or
|
||||
implied warranty. In no event will the authors be held liable
|
||||
for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it
|
||||
and redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. The origin of this software must not be
|
||||
misrepresented; you must not claim that you wrote
|
||||
the original software. If you use this software in a
|
||||
product, an acknowledgment in the product
|
||||
documentation is required.
|
||||
|
||||
2. Altered source versions must be plainly marked as
|
||||
such, and must not be misrepresented as being the
|
||||
original software.
|
||||
|
||||
3. This notice may not be removed or altered from any
|
||||
source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BitStream.h"
|
||||
|
||||
#define BITSTREAM_BUFSIZE 4096
|
||||
#define BITSTREAM_BUFSIZE_MASK (BITSTREAM_BUFSIZE-1)
|
||||
|
||||
class BitReservoir
|
||||
{
|
||||
private:
|
||||
|
||||
unsigned char m_Buffer[BITSTREAM_BUFSIZE];
|
||||
|
||||
long m_InputIndex;
|
||||
|
||||
long m_ByteIndex;
|
||||
long m_BitIndex;
|
||||
|
||||
public:
|
||||
|
||||
BitReservoir()
|
||||
{
|
||||
FlushBuffer();
|
||||
}
|
||||
|
||||
~BitReservoir()
|
||||
{
|
||||
}
|
||||
|
||||
void FlushBuffer()
|
||||
{
|
||||
for(unsigned long x=0; x<BITSTREAM_BUFSIZE; x++)
|
||||
{
|
||||
m_Buffer[x] = 0xff;
|
||||
}
|
||||
|
||||
m_InputIndex = 0;
|
||||
m_ByteIndex = 0;
|
||||
m_BitIndex = 0;
|
||||
}
|
||||
|
||||
void FillBitReserve(unsigned char * buffer, unsigned long numbytes)
|
||||
{
|
||||
m_ByteIndex = m_InputIndex;
|
||||
m_BitIndex = 0;
|
||||
|
||||
for(unsigned long x=0; x<numbytes; x++)
|
||||
{
|
||||
m_Buffer[m_InputIndex] = buffer[x];
|
||||
m_InputIndex ++;
|
||||
m_InputIndex &= BITSTREAM_BUFSIZE_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
bool BackStep(unsigned long backstep)
|
||||
{
|
||||
if(backstep)
|
||||
{
|
||||
m_ByteIndex -= backstep;
|
||||
m_ByteIndex &= BITSTREAM_BUFSIZE_MASK;
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
void RewindBits(int bits)
|
||||
{
|
||||
m_BitIndex -= bits;
|
||||
}
|
||||
|
||||
void FlushBits(int bits)
|
||||
{
|
||||
m_BitIndex += bits;
|
||||
}
|
||||
|
||||
unsigned long GetPos(void)
|
||||
{
|
||||
return(m_BitIndex);
|
||||
}
|
||||
|
||||
void SetPos(unsigned long pos)
|
||||
{
|
||||
m_BitIndex = pos;
|
||||
}
|
||||
|
||||
unsigned int ViewBits(int bits)
|
||||
{
|
||||
unsigned long rval;
|
||||
int pos;
|
||||
|
||||
if(!bits)
|
||||
return 0;
|
||||
|
||||
pos = (unsigned long)m_ByteIndex + (m_BitIndex >> 3);
|
||||
|
||||
rval = m_Buffer[(pos)&0xFFF] << 24 |
|
||||
m_Buffer[(pos+1)&0xFFF] << 16 |
|
||||
m_Buffer[(pos+2)&0xFFF] << 8 |
|
||||
m_Buffer[(pos+3)&0xFFF];
|
||||
|
||||
rval <<= m_BitIndex & 7;
|
||||
rval >>= 32-bits;
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
unsigned int GetBits(int bits)
|
||||
{
|
||||
unsigned long rval;
|
||||
|
||||
rval = ViewBits(bits);
|
||||
FlushBits(bits);
|
||||
|
||||
return rval;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2002 Tony Million
|
||||
|
||||
This software is provided 'as-is', without any express or
|
||||
implied warranty. In no event will the authors be held liable
|
||||
for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it
|
||||
and redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. The origin of this software must not be
|
||||
misrepresented; you must not claim that you wrote
|
||||
the original software. If you use this software in a
|
||||
product, an acknowledgment in the product
|
||||
documentation is required.
|
||||
|
||||
2. Altered source versions must be plainly marked as
|
||||
such, and must not be misrepresented as being the
|
||||
original software.
|
||||
|
||||
3. This notice may not be removed or altered from any
|
||||
source distribution.
|
||||
*/
|
||||
|
||||
#include "BitStream.h"
|
||||
|
||||
|
||||
BitStream::BitStream()
|
||||
{
|
||||
buffer = 0;
|
||||
bitindex = 0;
|
||||
}
|
||||
|
||||
BitStream::~BitStream()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
unsigned long BitStream::GetBits(unsigned long N)
|
||||
{
|
||||
unsigned long rval;
|
||||
int pos;
|
||||
|
||||
if(N == 0)
|
||||
return 0;
|
||||
|
||||
pos = (unsigned long)(bitindex >> 3);
|
||||
|
||||
rval = buffer[pos] << 24 |
|
||||
buffer[pos+1] << 16 |
|
||||
buffer[pos+2] << 8 |
|
||||
buffer[pos+3];
|
||||
|
||||
rval <<= bitindex & 7;
|
||||
rval >>= 32 - N;
|
||||
bitindex += N;
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
||||
bool BitStream::Load(unsigned char *FromHere)
|
||||
{
|
||||
buffer = FromHere;
|
||||
bitindex = 0;
|
||||
|
||||
return(true);
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2002 Tony Million
|
||||
|
||||
This software is provided 'as-is', without any express or
|
||||
implied warranty. In no event will the authors be held liable
|
||||
for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it
|
||||
and redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. The origin of this software must not be
|
||||
misrepresented; you must not claim that you wrote
|
||||
the original software. If you use this software in a
|
||||
product, an acknowledgment in the product
|
||||
documentation is required.
|
||||
|
||||
2. Altered source versions must be plainly marked as
|
||||
such, and must not be misrepresented as being the
|
||||
original software.
|
||||
|
||||
3. This notice may not be removed or altered from any
|
||||
source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class BitStream
|
||||
{
|
||||
protected:
|
||||
unsigned char * buffer;
|
||||
unsigned int bitindex;
|
||||
|
||||
public:
|
||||
BitStream();
|
||||
virtual ~BitStream();
|
||||
|
||||
bool Load(unsigned char * FromHere);
|
||||
unsigned long GetBits(unsigned long N);
|
||||
|
||||
};
|
@ -1,19 +0,0 @@
|
||||
set (mp3decoder_SOURCES
|
||||
BaseDecoder.cpp
|
||||
BitStream.cpp
|
||||
CRC.cpp
|
||||
Header.cpp
|
||||
Layer3Decoder.cpp
|
||||
mp3decoder_plugin.cpp
|
||||
Mp3Decoder.cpp
|
||||
MP3DecoderFactory.cpp
|
||||
SideInfo.cpp
|
||||
stdafx.cpp
|
||||
)
|
||||
|
||||
add_definitions(
|
||||
-D_DEBUG
|
||||
)
|
||||
|
||||
add_library(mp3decoder SHARED ${mp3decoder_SOURCES})
|
||||
target_link_libraries(mp3decoder ${musikbox_LINK_LIBS})
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2002 Tony Million
|
||||
|
||||
This software is provided 'as-is', without any express or
|
||||
implied warranty. In no event will the authors be held liable
|
||||
for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it
|
||||
and redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. The origin of this software must not be
|
||||
misrepresented; you must not claim that you wrote
|
||||
the original software. If you use this software in a
|
||||
product, an acknowledgment in the product
|
||||
documentation is required.
|
||||
|
||||
2. Altered source versions must be plainly marked as
|
||||
such, and must not be misrepresented as being the
|
||||
original software.
|
||||
|
||||
3. This notice may not be removed or altered from any
|
||||
source distribution.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "CRC.h"
|
||||
|
||||
CRC::CRC()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CRC::~CRC()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool CRC::Load(unsigned char *FromHere)
|
||||
{
|
||||
return(true);
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2002 Tony Million
|
||||
|
||||
This software is provided 'as-is', without any express or
|
||||
implied warranty. In no event will the authors be held liable
|
||||
for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it
|
||||
and redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. The origin of this software must not be
|
||||
misrepresented; you must not claim that you wrote
|
||||
the original software. If you use this software in a
|
||||
product, an acknowledgment in the product
|
||||
documentation is required.
|
||||
|
||||
2. Altered source versions must be plainly marked as
|
||||
such, and must not be misrepresented as being the
|
||||
original software.
|
||||
|
||||
3. This notice may not be removed or altered from any
|
||||
source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class CRC
|
||||
{
|
||||
public:
|
||||
CRC();
|
||||
virtual ~CRC();
|
||||
|
||||
bool Load(unsigned char * FromHere);
|
||||
};
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2002 Tony Million
|
||||
|
||||
This software is provided 'as-is', without any express or
|
||||
implied warranty. In no event will the authors be held liable
|
||||
for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it
|
||||
and redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. The origin of this software must not be
|
||||
misrepresented; you must not claim that you wrote
|
||||
the original software. If you use this software in a
|
||||
product, an acknowledgment in the product
|
||||
documentation is required.
|
||||
|
||||
2. Altered source versions must be plainly marked as
|
||||
such, and must not be misrepresented as being the
|
||||
original software.
|
||||
|
||||
3. This notice may not be removed or altered from any
|
||||
source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Header.h"
|
||||
#include "SideInfo.h"
|
||||
#include "CRC.h"
|
||||
|
||||
class Frame
|
||||
{
|
||||
public:
|
||||
Header m_Header;
|
||||
CRC m_CRC;
|
||||
|
||||
SideInfo m_SI;
|
||||
|
||||
unsigned char m_Data[1730]; // max. 1730 bytes per frame: 144 * 384kbit/s / 32000 Hz + 2 Bytes CRC
|
||||
};
|
@ -1,107 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2002 Tony Million
|
||||
|
||||
This software is provided 'as-is', without any express or
|
||||
implied warranty. In no event will the authors be held liable
|
||||
for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it
|
||||
and redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. The origin of this software must not be
|
||||
misrepresented; you must not claim that you wrote
|
||||
the original software. If you use this software in a
|
||||
product, an acknowledgment in the product
|
||||
documentation is required.
|
||||
|
||||
2. Altered source versions must be plainly marked as
|
||||
such, and must not be misrepresented as being the
|
||||
original software.
|
||||
|
||||
3. This notice may not be removed or altered from any
|
||||
source distribution.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "FrameSplitter.h"
|
||||
|
||||
CFrameSplitter::CFrameSplitter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CFrameSplitter::~CFrameSplitter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool CFrameSplitter::Process(HANDLE hRead, Frame & fr)
|
||||
{
|
||||
unsigned char headerbuf[4] = {0,0,0,0};
|
||||
unsigned char crcbuf[2];
|
||||
unsigned char sideInfoBuffer[32];
|
||||
unsigned long BytesRead;
|
||||
unsigned long NumErrors = 0;
|
||||
unsigned long CurrentOffset = SetFilePointer(hRead, 0, NULL, FILE_CURRENT);
|
||||
|
||||
if(!ReadFile(hRead, (char*)headerbuf, 4, &BytesRead, NULL))
|
||||
return false;
|
||||
if(BytesRead != 4)
|
||||
return false;
|
||||
|
||||
while(!fr.m_Header.Load(headerbuf))
|
||||
{
|
||||
headerbuf[0] = headerbuf[1];
|
||||
headerbuf[1] = headerbuf[2];
|
||||
headerbuf[2] = headerbuf[3];
|
||||
|
||||
if(!ReadFile(hRead, (char*)&headerbuf[3], 1, &BytesRead, NULL))
|
||||
return false;
|
||||
if(BytesRead != 1)
|
||||
return false;
|
||||
|
||||
if(NumErrors++ >= fr.m_Header.GetDataSize())
|
||||
{
|
||||
fr.m_Header.Reset();
|
||||
}
|
||||
|
||||
CurrentOffset++;
|
||||
}
|
||||
|
||||
// check we have enough for the whole of this frame...
|
||||
//if(BytesUsed <= ((int)Length - (int)FrameSize))
|
||||
|
||||
if(fr.m_Header.IsCRC())
|
||||
{
|
||||
if(!ReadFile(hRead, (char*)crcbuf, 2, &BytesRead, NULL))
|
||||
return false;
|
||||
if(BytesRead != 2)
|
||||
return false;
|
||||
|
||||
fr.m_CRC.Load(crcbuf);
|
||||
}
|
||||
|
||||
|
||||
if(fr.m_Header.GetLayer() == LAYER3)
|
||||
{
|
||||
// read side info for layer 3 files
|
||||
|
||||
if(!ReadFile(hRead, (char*)sideInfoBuffer, fr.m_Header.GetSideInfoSize(), &BytesRead, NULL))
|
||||
return false;
|
||||
if(BytesRead != fr.m_Header.GetSideInfoSize())
|
||||
return false;
|
||||
|
||||
if(!fr.m_SI.Load(&fr.m_Header, sideInfoBuffer))
|
||||
return(false);
|
||||
|
||||
}
|
||||
|
||||
if(!ReadFile(hRead, (char*)fr.m_Data, fr.m_Header.GetDataSize(), &BytesRead, NULL))
|
||||
return false;
|
||||
if(BytesRead != fr.m_Header.GetDataSize())
|
||||
return false;
|
||||
|
||||
return(true);
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2002 Tony Million
|
||||
|
||||
This software is provided 'as-is', without any express or
|
||||
implied warranty. In no event will the authors be held liable
|
||||
for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it
|
||||
and redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. The origin of this software must not be
|
||||
misrepresented; you must not claim that you wrote
|
||||
the original software. If you use this software in a
|
||||
product, an acknowledgment in the product
|
||||
documentation is required.
|
||||
|
||||
2. Altered source versions must be plainly marked as
|
||||
such, and must not be misrepresented as being the
|
||||
original software.
|
||||
|
||||
3. This notice may not be removed or altered from any
|
||||
source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Frame.h"
|
||||
|
||||
class CFrameSplitter
|
||||
{
|
||||
protected:
|
||||
|
||||
public:
|
||||
CFrameSplitter();
|
||||
virtual ~CFrameSplitter();
|
||||
|
||||
bool Process(HANDLE hRead, Frame & fr);
|
||||
};
|
@ -1,285 +0,0 @@
|
||||
// Header.cpp: implementation of the Header class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Header.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define HDRMAIN_BITS 0xfffffc00 // 1111 1111 1111 1111 1111 1100 0000 0000
|
||||
#define MPEG_BITS 0x00180000 // 0000 0000 0001 1000 0000 0000 0000 0000
|
||||
#define LAYER_BITS 0x00060000 // 0000 0000 0000 0110 0000 0000 0000 0000
|
||||
#define CRC_BIT 0x00010000 // 0000 0000 0000 0001 0000 0000 0000 0000
|
||||
#define BITRATE_BITS 0x0000f000 // 0000 0000 0000 0000 ffff 0000 0000 0000
|
||||
#define SAMP_BITS 0x00000C00 // 0000 0000 0000 0000 0000 1100 0000 0000
|
||||
#define PADING_BIT 0x00000200 // 0000 0000 0000 0000 0000 0010 0000 0000
|
||||
#define PRIVATE_BIT 0x00000100 // 0000 0000 0000 0000 0000 0001 0000 0000
|
||||
#define MODE_BITS 0x000000C0 // 0000 0000 0000 0000 0000 0000 1100 0000
|
||||
#define MODEEXT_BITS 0x00000030 // 0000 0000 0000 0000 0000 0000 0011 0000
|
||||
#define COPYRIGHT_BIT 0x00000008 // 0000 0000 0000 0000 0000 0000 0000 1000
|
||||
#define ORIGINAL_BIT 0x00000004 // 0000 0000 0000 0000 0000 0000 0000 0100
|
||||
#define EMPHASIS_BITS 0x00000003 // 0000 0000 0000 0000 0000 0000 0000 0011
|
||||
|
||||
#define CHECK_BITS 0xfffe0c00
|
||||
|
||||
#define MPEG_BITS_1 0x00180000
|
||||
#define MPEG_BITS_2 0x00100000
|
||||
#define MPEG_BITS_25 0x00000000
|
||||
|
||||
#define LAYER_BITS_1 0x00060000
|
||||
#define LAYER_BITS_2 0x00040000
|
||||
#define LAYER_BITS_3 0x00020000
|
||||
|
||||
|
||||
const unsigned long Header::BitRates[2][3][16] =
|
||||
{
|
||||
{
|
||||
{0 /*free format*/, 32000, 64000, 96000, 128000, 160000, 192000, 224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000, 0},
|
||||
{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 0},
|
||||
{0 /*free format*/, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 0}
|
||||
},
|
||||
{
|
||||
{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 176000, 192000, 224000, 256000, 0},
|
||||
{0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0},
|
||||
{0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}
|
||||
},
|
||||
};
|
||||
|
||||
const unsigned long Header::SampleRates[3][3] =
|
||||
{
|
||||
{
|
||||
44100, 48000, 32000
|
||||
},
|
||||
{
|
||||
22050, 24000, 16000
|
||||
},
|
||||
{
|
||||
11025, 12000, 8000
|
||||
}
|
||||
};
|
||||
|
||||
Header::Header()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
Header::~Header()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Header::Reset()
|
||||
{
|
||||
MpegVersion = -1;
|
||||
Layer = -1;
|
||||
SampleFrequency = -1;
|
||||
Mode = -1;
|
||||
}
|
||||
|
||||
bool Header::Load(unsigned char *FromHere)
|
||||
{
|
||||
bs.Load(FromHere);
|
||||
|
||||
if(bs.GetBits(11) != 0x7ff)
|
||||
return(false);
|
||||
|
||||
unsigned long OldMpeg = MpegVersion;
|
||||
if(bs.GetBits(1)) // mpeg 1 or 2
|
||||
{
|
||||
if(bs.GetBits(1))
|
||||
{
|
||||
MpegVersion = MPEG1;
|
||||
}
|
||||
else
|
||||
{
|
||||
MpegVersion = MPEG2;
|
||||
}
|
||||
}
|
||||
else // mpeg 2.5 or invalid
|
||||
{
|
||||
if(bs.GetBits(1))
|
||||
{
|
||||
MpegVersion = OldMpeg;
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
MpegVersion = MPEG25;
|
||||
}
|
||||
}
|
||||
|
||||
if(OldMpeg != -1)
|
||||
{
|
||||
if(MpegVersion != OldMpeg)
|
||||
{
|
||||
MpegVersion = OldMpeg;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned OldLayer = Layer;
|
||||
switch(bs.GetBits(2))
|
||||
{
|
||||
case 0:
|
||||
Layer = OldLayer;
|
||||
return(false);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
Layer = LAYER3;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
Layer = LAYER2;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
Layer = LAYER1;
|
||||
break;
|
||||
}
|
||||
if(OldLayer != -1)
|
||||
{
|
||||
if(Layer != OldLayer)
|
||||
{
|
||||
MpegVersion = OldMpeg;
|
||||
Layer = OldLayer;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ProtectionBit = !(bs.GetBits(1));
|
||||
|
||||
BitrateIndex = bs.GetBits(4);
|
||||
if(BitrateIndex == 15)
|
||||
{
|
||||
MpegVersion = OldMpeg;
|
||||
Layer = OldLayer;
|
||||
return(false);
|
||||
}
|
||||
|
||||
if(BitrateIndex == 0)
|
||||
{
|
||||
MpegVersion = OldMpeg;
|
||||
Layer = OldLayer;
|
||||
return(false);
|
||||
}
|
||||
|
||||
unsigned long OldSampleFrequency = SampleFrequency;
|
||||
SampleFrequency = bs.GetBits(2);
|
||||
if(OldSampleFrequency != -1)
|
||||
{
|
||||
if(SampleFrequency != OldSampleFrequency)
|
||||
{
|
||||
MpegVersion = OldMpeg;
|
||||
Layer = OldLayer;
|
||||
SampleFrequency = OldSampleFrequency;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(SampleFrequency == 3)
|
||||
{
|
||||
MpegVersion = OldMpeg;
|
||||
Layer = OldLayer;
|
||||
SampleFrequency = OldSampleFrequency;
|
||||
return false;
|
||||
}
|
||||
|
||||
PaddingBit = bs.GetBits(1);
|
||||
PrivateBit = bs.GetBits(1);
|
||||
|
||||
unsigned long OldMode = Mode;
|
||||
Mode = bs.GetBits(2);
|
||||
if(OldMode != -1)
|
||||
{
|
||||
if(OldMode != Mode)
|
||||
{
|
||||
MpegVersion = OldMpeg;
|
||||
Layer = OldLayer;
|
||||
SampleFrequency = OldSampleFrequency;
|
||||
Mode = OldMode;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Mode_Extension = bs.GetBits(2);
|
||||
|
||||
Copyright = bs.GetBits(1);
|
||||
Original = bs.GetBits(1);
|
||||
|
||||
Emphasis = bs.GetBits(2);
|
||||
if(Emphasis == EMPH_RESERVED)
|
||||
{
|
||||
MpegVersion = OldMpeg;
|
||||
Layer = OldLayer;
|
||||
SampleFrequency = OldSampleFrequency;
|
||||
Mode = OldMode;
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
if(Mode == MODE_MONO)
|
||||
Channels = 1;
|
||||
else
|
||||
Channels = 2;
|
||||
|
||||
|
||||
if(Layer == LAYER3)
|
||||
{
|
||||
if(MpegVersion == MPEG1)
|
||||
{
|
||||
if(Channels==1)
|
||||
SideInfoSize = 17;
|
||||
else
|
||||
SideInfoSize = 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Channels==1)
|
||||
SideInfoSize = 9;
|
||||
else
|
||||
SideInfoSize = 17;
|
||||
}
|
||||
}
|
||||
else
|
||||
SideInfoSize = 0;
|
||||
|
||||
unsigned long base;
|
||||
unsigned long Multiple;
|
||||
|
||||
if(Layer == LAYER1)
|
||||
{
|
||||
base = 12;
|
||||
Multiple = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// framesize is HALF of what it is for MPEG 1
|
||||
// really we should change that 144 * BitRate...
|
||||
// to be 72 * BitRate....
|
||||
if(MpegVersion != MPEG1)
|
||||
base = 72;
|
||||
else
|
||||
base = 144;
|
||||
|
||||
Multiple = 1;
|
||||
}
|
||||
|
||||
FrameSize = ((base * BitRates[MpegVersion == MPEG1 ? 0 : 1][Layer][BitrateIndex]) / SampleRates[MpegVersion][SampleFrequency]);
|
||||
if(PaddingBit)
|
||||
FrameSize++;
|
||||
|
||||
FrameSize *= Multiple;
|
||||
FrameSize -= 4; // for the Header;
|
||||
if(ProtectionBit)
|
||||
FrameSize -= 2;
|
||||
FrameSize -= SideInfoSize;
|
||||
|
||||
HeaderSize = 4;
|
||||
|
||||
return(true);
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2002 Tony Million
|
||||
|
||||
This software is provided 'as-is', without any express or
|
||||
implied warranty. In no event will the authors be held liable
|
||||
for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it
|
||||
and redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. The origin of this software must not be
|
||||
misrepresented; you must not claim that you wrote
|
||||
the original software. If you use this software in a
|
||||
product, an acknowledgment in the product
|
||||
documentation is required.
|
||||
|
||||
2. Altered source versions must be plainly marked as
|
||||
such, and must not be misrepresented as being the
|
||||
original software.
|
||||
|
||||
3. This notice may not be removed or altered from any
|
||||
source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BitStream.h"
|
||||
|
||||
#define LAYER1 0
|
||||
#define LAYER2 1
|
||||
#define LAYER3 2
|
||||
|
||||
#define MPEG1 0
|
||||
#define MPEG2 1
|
||||
#define MPEG25 2
|
||||
|
||||
#define MODE_STEREO 0
|
||||
#define MODE_JOINT_STEREO 1 // see MODE_EXT defines
|
||||
#define MODE_DUAL_CHANNEL 2
|
||||
#define MODE_MONO 3
|
||||
|
||||
//mode extensions
|
||||
|
||||
// for LAYER1 and LAYER2
|
||||
#define BOUND4 0
|
||||
#define BOUND8 1
|
||||
#define BOUND12 2
|
||||
#define BOUND16 3
|
||||
|
||||
// for LAYER3
|
||||
#define MODE_EXT_STEREO 0 // stream is actually MODE_STEREO
|
||||
#define MODE_EXT_IS 1 // Intensity stereo coding is used
|
||||
#define MODE_EXT_MS 2 // MS Stereo is used
|
||||
#define MODE_EXT_ISMS 3 // both Intensity and MS stereo are used
|
||||
|
||||
#define EMPH_NONE 0 // no deemphasis
|
||||
#define EMPH_5015 1 // 50/15 microseconds
|
||||
#define EMPH_RESERVED 2 // should never happen
|
||||
#define EMPH_CCITT 3 // CCITT j.17
|
||||
|
||||
class Header
|
||||
{
|
||||
protected:
|
||||
// Mpeg Header Stuff
|
||||
unsigned long MpegVersion;
|
||||
unsigned long Layer;
|
||||
unsigned long ProtectionBit;
|
||||
unsigned long BitrateIndex;
|
||||
unsigned long SampleFrequency;
|
||||
unsigned long PaddingBit;
|
||||
unsigned long PrivateBit;
|
||||
unsigned long Mode;
|
||||
unsigned long Mode_Extension;
|
||||
unsigned long Copyright;
|
||||
unsigned long Original;
|
||||
unsigned long Emphasis;
|
||||
|
||||
// Calculated stuff
|
||||
unsigned long FrameSize;
|
||||
unsigned long SideInfoSize;
|
||||
unsigned long Channels;
|
||||
|
||||
unsigned long HeaderSize;
|
||||
|
||||
unsigned char CRC[2];
|
||||
|
||||
static const unsigned long BitRates[2][3][16];
|
||||
static const unsigned long SampleRates[3][3];
|
||||
|
||||
BitStream bs;
|
||||
|
||||
public:
|
||||
Header();
|
||||
virtual ~Header();
|
||||
|
||||
void Reset();
|
||||
|
||||
bool Load(unsigned char * FromHere);
|
||||
|
||||
unsigned long GetHeaderSize(void) { return(HeaderSize); };
|
||||
unsigned long GetCRCSize() { if(IsCRC()) return 2; else return 0; };
|
||||
unsigned long GetSideInfoSize(void) { return(SideInfoSize); }
|
||||
unsigned long GetDataSize(void) { return(FrameSize); }
|
||||
|
||||
unsigned long GetMpegVersion() { return MpegVersion; };
|
||||
unsigned long GetMode() { return Mode; };
|
||||
unsigned long GetModeExtension() { return Mode_Extension; };
|
||||
unsigned long GetLayer() { return Layer; };
|
||||
unsigned long GetChannels() { return Channels; };
|
||||
unsigned long GetSampleFrequencyIndex() { return SampleFrequency; };
|
||||
unsigned long GetSampleFrequency() { return SampleRates[MpegVersion][SampleFrequency]; };
|
||||
unsigned long IsCRC() { return( ProtectionBit ); };
|
||||
|
||||
unsigned long GetTotalFrameSize() { return( GetHeaderSize() + GetCRCSize() + GetSideInfoSize() + GetDataSize() ); }
|
||||
|
||||
unsigned long GetBitrate() { return( BitRates[MpegVersion == MPEG1 ? 0 : 1][Layer][BitrateIndex] ); };
|
||||
};
|
@ -1,36 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2002 Tony Million
|
||||
|
||||
This software is provided 'as-is', without any express or
|
||||
implied warranty. In no event will the authors be held liable
|
||||
for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it
|
||||
and redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. The origin of this software must not be
|
||||
misrepresented; you must not claim that you wrote
|
||||
the original software. If you use this software in a
|
||||
product, an acknowledgment in the product
|
||||
documentation is required.
|
||||
|
||||
2. Altered source versions must be plainly marked as
|
||||
such, and must not be misrepresented as being the
|
||||
original software.
|
||||
|
||||
3. This notice may not be removed or altered from any
|
||||
source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Frame.h"
|
||||
|
||||
class IMPEGDecoder
|
||||
{
|
||||
public:
|
||||
virtual ~IMPEGDecoder() { };
|
||||
virtual bool ProcessFrame(Frame * fr, float * PCMSamples, unsigned long * NumSamples) = 0;
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -1,77 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "BaseDecoder.h"
|
||||
#include "BitReservoir.h"
|
||||
#include "SideInfo.h"
|
||||
|
||||
class CLayer3Decoder : public CBaseDecoder
|
||||
{
|
||||
protected:
|
||||
|
||||
typedef struct _SBI_
|
||||
{
|
||||
unsigned short Long[23];
|
||||
unsigned short Short[14];
|
||||
} SBI;
|
||||
|
||||
|
||||
BitReservoir br;
|
||||
Frame * m_fr;
|
||||
|
||||
|
||||
unsigned long m_Part2Start[2];
|
||||
unsigned long m_MixedBandLimit[2];
|
||||
unsigned long m_NonZero[2];
|
||||
|
||||
unsigned long m_MpegVer;
|
||||
unsigned long m_SampleFrequency;
|
||||
unsigned long m_Channels;
|
||||
unsigned long m_Granules;
|
||||
unsigned long m_Mode;
|
||||
unsigned long m_ModeExt;
|
||||
|
||||
int is[2][576];
|
||||
float xr[2][576]; // Dequantized
|
||||
float xrr[2][576]; // reordered
|
||||
float xir[2][576]; // IMDCT'd
|
||||
|
||||
float kl[576];
|
||||
float kr[576];
|
||||
float prevblck[2][576]; // overlapped
|
||||
float IMDCTwin[4][36]; // used for windowing the IMDCT samples
|
||||
|
||||
|
||||
// calculated at runtime
|
||||
float PowerTableMinus2[64]; /* (2^(-2))^i */
|
||||
float PowerTableMinus05[64]; /* (2^(-0.5))^i */
|
||||
float GainTable[256];
|
||||
float TanPi12Table[16]; // mpeg1 tan(is * PI/12);
|
||||
float Cs[8], Ca[8];
|
||||
float IMDCT9x8Table[72];
|
||||
|
||||
static const SBI sfBandIndex[3][3];
|
||||
static const float ShortTwiddles[];
|
||||
static const float NormalTwiddles[];
|
||||
|
||||
void DecodeScalefactors(unsigned long ch, unsigned long gr);
|
||||
|
||||
bool HuffmanDecode(unsigned long TableNum, int * x, int * y, int * v, int * w);
|
||||
bool ReadHuffman(unsigned long ch, unsigned long gr);
|
||||
void DequantizeSample(int ch, int gr);
|
||||
void Reorder(unsigned int ch, unsigned int gr);
|
||||
void CalculateK(int index, int is_pos, int intensity_scale);
|
||||
void Stereo(unsigned int gr);
|
||||
void AntiAlias(unsigned int ch, unsigned int gr);
|
||||
void FreqencyInverse(int gr, int ch);
|
||||
|
||||
void IMDCT(float *in, float *out, int block_type);
|
||||
void Hybrid(int ch, float *xfrom, float *xto, int blocktype, int windowswitching, int mixedblock);
|
||||
|
||||
public:
|
||||
CLayer3Decoder();
|
||||
virtual ~CLayer3Decoder();
|
||||
|
||||
public:
|
||||
bool ProcessFrame(Frame * fr, float * PCMSamples, unsigned long * NumSamples);
|
||||
|
||||
};
|
@ -1,280 +0,0 @@
|
||||
#include "StdAfx.h"
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include "mp3decoder.h"
|
||||
|
||||
static bool splitFrame(musik::core::io::IDataStream *dataStream, Frame &fr) {
|
||||
if (dataStream->Eof()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char headerbuf[4] = { 0, 0, 0, 0 };
|
||||
unsigned char crcbuf[2];
|
||||
unsigned char sideInfoBuffer[32];
|
||||
unsigned long bytesRead;
|
||||
unsigned long errorCount = 0;
|
||||
unsigned long currentOffset = dataStream->Position();
|
||||
|
||||
if (dataStream->Read(headerbuf, 4) != 4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!fr.m_Header.Load(headerbuf)) {
|
||||
headerbuf[0] = headerbuf[1];
|
||||
headerbuf[1] = headerbuf[2];
|
||||
headerbuf[2] = headerbuf[3];
|
||||
|
||||
if (dataStream->Read(&headerbuf[3], 1) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (errorCount++ >= fr.m_Header.GetDataSize()) {
|
||||
fr.m_Header.Reset();
|
||||
}
|
||||
|
||||
currentOffset++;
|
||||
}
|
||||
|
||||
if (fr.m_Header.IsCRC()) {
|
||||
if (dataStream->Read(crcbuf, 2) != 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fr.m_CRC.Load(crcbuf);
|
||||
}
|
||||
|
||||
if (fr.m_Header.GetLayer() == LAYER3) {
|
||||
unsigned count = fr.m_Header.GetSideInfoSize();
|
||||
|
||||
if (dataStream->Read(sideInfoBuffer, count) != count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!fr.m_SI.Load(&fr.m_Header, sideInfoBuffer)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned frameBytes = fr.m_Header.GetDataSize();
|
||||
if (dataStream->Read(fr.m_Data, frameBytes) != frameBytes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Mp3Decoder::Mp3Decoder()
|
||||
: decoder(NULL) {
|
||||
}
|
||||
|
||||
Mp3Decoder::~Mp3Decoder() {
|
||||
delete decoder;
|
||||
}
|
||||
|
||||
unsigned long Mp3Decoder::GetID3HeaderLength(unsigned char * buffer) {
|
||||
unsigned char VerMajor;
|
||||
unsigned char VerMinor;
|
||||
unsigned char Flags;
|
||||
unsigned long Length;
|
||||
|
||||
if( (toupper(buffer[0]) == 'I') &&
|
||||
(toupper(buffer[1]) == 'D') &&
|
||||
(toupper(buffer[2]) == '3'))
|
||||
{
|
||||
VerMajor = buffer[3];
|
||||
VerMinor = buffer[4];
|
||||
Flags = buffer[5];
|
||||
|
||||
Length = (buffer[6] << 21) | (buffer[7] << 14) | (buffer[8] << 7) | buffer[9];
|
||||
Length += 10; // the header
|
||||
|
||||
return(Length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Mp3Decoder::GetXingHeader(unsigned char * xingBuffer) {
|
||||
#define FRAMES_FLAG 0x0001
|
||||
#define BYTES_FLAG 0x0002
|
||||
#define TOC_FLAG 0x0004
|
||||
#define VBR_SCALE_FLAG 0x0008
|
||||
#define GET_INT32BE(b) (i = (b[0] << 24) | (b[1] << 16) | b[2] << 8 | b[3], b += 4, i) /* windows only? */
|
||||
|
||||
unsigned long i;
|
||||
|
||||
this->xingValid = false;
|
||||
|
||||
if (strncmp((char *) xingBuffer, "Xing", 4)) {
|
||||
if (strncmp((char *)xingBuffer, "Info", 4)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
xingBuffer += 4;
|
||||
|
||||
unsigned long headFlags = GET_INT32BE(xingBuffer);
|
||||
|
||||
this->numFrames = 0;
|
||||
if (headFlags & FRAMES_FLAG) {
|
||||
this->numFrames = GET_INT32BE(xingBuffer);
|
||||
}
|
||||
|
||||
if (this->numFrames < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->streamDataLength = 0;
|
||||
if (headFlags & BYTES_FLAG) {
|
||||
this->streamDataLength = GET_INT32BE(xingBuffer);
|
||||
}
|
||||
|
||||
if (headFlags & TOC_FLAG) {
|
||||
for (i = 0; i < 100; i++) {
|
||||
this->toc[i] = xingBuffer[i];
|
||||
}
|
||||
|
||||
xingBuffer += 100;
|
||||
}
|
||||
|
||||
this->vbrScale = -1;
|
||||
if (headFlags & VBR_SCALE_FLAG) {
|
||||
this->vbrScale = GET_INT32BE(xingBuffer);
|
||||
}
|
||||
|
||||
this->xingValid = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Mp3Decoder::GetStreamData() {
|
||||
unsigned char tbuf[11];
|
||||
unsigned long bytesread;
|
||||
Frame fr;
|
||||
|
||||
this->dataStream->Read(tbuf, 10);
|
||||
this->id3v2Length = GetID3HeaderLength(tbuf);
|
||||
this->dataStream->SetPosition(this->id3v2Length);
|
||||
|
||||
if (splitFrame(this->dataStream, fr)) {
|
||||
unsigned char * pHeader = fr.m_Data;
|
||||
if(!GetXingHeader(pHeader)) {
|
||||
this->dataStream->SetPosition(this->id3v2Length);
|
||||
|
||||
// just guesstimate the number of frames!
|
||||
/* DANGEROUS -- ASSUMES FINITE LENGTH*/
|
||||
this->streamDataLength = this->dataStream->Length() - this->id3v2Length;
|
||||
|
||||
// TODO: check for ID3 TAG at the end of the file and subtract
|
||||
// also remove the size of this current header
|
||||
this->streamDataLength -= fr.m_Header.GetTotalFrameSize();
|
||||
this->numFrames = this->streamDataLength / fr.m_Header.GetTotalFrameSize();
|
||||
}
|
||||
else {
|
||||
if (!this->xingValid) {
|
||||
std::cout << "Mp3Decoder.cpp: Mp3 has Xing header but it is invalid.";
|
||||
}
|
||||
}
|
||||
|
||||
double bs[3] = { 384.0, 1152.0, 1152.0 };
|
||||
double timePerFrame = (double)bs[fr.m_Header.GetLayer()] / (((double)fr.m_Header.GetSampleFrequency() / 1000.0));
|
||||
|
||||
this->streamLengthMs = timePerFrame * this->numFrames;
|
||||
|
||||
if (fr.m_Header.GetMpegVersion() != MPEG1) {
|
||||
this->streamLengthMs /= 2;
|
||||
}
|
||||
|
||||
this->sampleRate = fr.m_Header.GetSampleFrequency();
|
||||
this->numChannels = fr.m_Header.GetChannels();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Mp3Decoder::Open(musik::core::io::IDataStream *dataStream) {
|
||||
this->dataStream = dataStream;
|
||||
this->lastLayer = -1;
|
||||
return GetStreamData();
|
||||
}
|
||||
|
||||
void Mp3Decoder::Destroy() {
|
||||
delete this;
|
||||
}
|
||||
|
||||
#define MP3_BUFFER_FLOAT_ALLOWANCE 2304 /* why? */
|
||||
|
||||
bool Mp3Decoder::GetBuffer(IBuffer *buffer) {
|
||||
buffer->SetChannels(this->numChannels);
|
||||
buffer->SetSamples(MP3_BUFFER_FLOAT_ALLOWANCE / buffer->Channels());
|
||||
buffer->SetSampleRate(this->sampleRate);
|
||||
|
||||
if (splitFrame(this->dataStream, this->frame)) {
|
||||
/* bail if the mpeg layer is incorrect*/
|
||||
if ((this->frame.m_Header.GetLayer() != this->lastLayer) || (this->decoder == NULL)) {
|
||||
switch (this->frame.m_Header.GetLayer()) {
|
||||
case LAYER3: {
|
||||
delete this->decoder;
|
||||
this->decoder = NULL;
|
||||
this->decoder = new CLayer3Decoder();
|
||||
this->lastLayer = LAYER3;
|
||||
}
|
||||
break;
|
||||
|
||||
default: {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* we have an mp3... */
|
||||
unsigned long bufferCount = 0;
|
||||
if (!this->decoder->ProcessFrame(&this->frame, buffer->BufferPointer(), &bufferCount)) {
|
||||
this->frame.m_Header.Reset(); /* we're done if ProcessFrame returns false */
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer->SetSamples(bufferCount / buffer->Channels());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
double Mp3Decoder::SetPosition(double seconds) {
|
||||
float milliseconds = (float) seconds * 1000.0f;
|
||||
float percent = 100.00f * ((float) milliseconds / (float) this->streamLengthMs);
|
||||
unsigned long offset;
|
||||
|
||||
if (this->xingValid) {
|
||||
/* interpolate in TOC to get file seek point in bytes */
|
||||
int a = std::min(percent, 99.0f);
|
||||
float fa, fb, fx;
|
||||
|
||||
fa = this->toc[a];
|
||||
|
||||
if (a < 99) {
|
||||
fb = this->toc[a + 1];
|
||||
}
|
||||
else {
|
||||
fb = 256;
|
||||
}
|
||||
|
||||
fx = fa + (fb - fa) * (percent - a);
|
||||
offset = (1.0f / 256.0f) * fx * this->streamDataLength;
|
||||
}
|
||||
else {
|
||||
offset = (float) this->streamDataLength * (float)(percent/ 100.0f) ;
|
||||
}
|
||||
|
||||
this->dataStream->SetPosition(offset + this->id3v2Length);
|
||||
bool result = splitFrame(this->dataStream, this->frame);
|
||||
|
||||
delete this->decoder;
|
||||
this->decoder = NULL;
|
||||
|
||||
return result ? seconds : -1;
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <core/sdk/IDecoder.h>
|
||||
#include "Layer3Decoder.h"
|
||||
|
||||
using namespace musik::core::audio;
|
||||
|
||||
class Mp3Decoder : public IDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
Mp3Decoder();
|
||||
virtual ~Mp3Decoder();
|
||||
|
||||
bool Open(musik::core::io::IDataStream *dataStream);
|
||||
double SetPosition(double seconds);
|
||||
bool GetBuffer(IBuffer *buffer);
|
||||
void Destroy();
|
||||
|
||||
private:
|
||||
bool GetXingHeader(unsigned char * XingBuffer);
|
||||
bool GetStreamData();
|
||||
unsigned long GetID3HeaderLength(unsigned char * buffer);
|
||||
|
||||
musik::core::io::IDataStream *dataStream;
|
||||
|
||||
IMPEGDecoder *decoder;
|
||||
Frame frame;
|
||||
|
||||
unsigned long lastLayer;
|
||||
unsigned long sampleRate;
|
||||
unsigned long numChannels;
|
||||
unsigned long id3v2Length;
|
||||
unsigned long streamLengthMs;
|
||||
unsigned long numFrames;
|
||||
unsigned long streamDataLength;
|
||||
unsigned long vbrScale;
|
||||
unsigned char toc[100];
|
||||
bool xingValid;
|
||||
};
|
@ -1,71 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright <20> 2007, Bj<42>rn Olievier
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "boost/algorithm/string.hpp"
|
||||
#include "boost/filesystem.hpp"
|
||||
|
||||
#include "Mp3DecoderFactory.h"
|
||||
#include "Mp3Decoder.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
Mp3DecoderFactory::Mp3DecoderFactory() {
|
||||
}
|
||||
|
||||
Mp3DecoderFactory::~Mp3DecoderFactory() {
|
||||
}
|
||||
|
||||
void Mp3DecoderFactory::Destroy() {
|
||||
delete this;
|
||||
}
|
||||
|
||||
IDecoder* Mp3DecoderFactory::CreateDecoder() {
|
||||
return new Mp3Decoder();
|
||||
}
|
||||
|
||||
bool Mp3DecoderFactory::CanHandle(const char* source) const {
|
||||
std::string str(type);
|
||||
std::transform(str.begin(), str.end(), str.begin(), tolower);
|
||||
|
||||
if (musik::sdk::endsWith(str, ".mp3") ||
|
||||
str.find("audio/mpeg3") != std::string::npos ||
|
||||
str.find("audio/x-mpeg-3") != std::string::npos ||
|
||||
str.find("audio/mp3") != std::string::npos)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright <20> 2007, Bj<42>rn Olievier
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <core/sdk/IDecoderFactory.h>
|
||||
|
||||
using namespace musik::core::audio;
|
||||
|
||||
class Mp3DecoderFactory : public IDecoderFactory {
|
||||
public:
|
||||
Mp3DecoderFactory();
|
||||
virtual ~Mp3DecoderFactory();
|
||||
|
||||
IDecoder* CreateDecoder();
|
||||
void Destroy();
|
||||
bool CanHandle(const char* type) const;
|
||||
};
|
@ -1,189 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2002 Tony Million
|
||||
|
||||
This software is provided 'as-is', without any express or
|
||||
implied warranty. In no event will the authors be held liable
|
||||
for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it
|
||||
and redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. The origin of this software must not be
|
||||
misrepresented; you must not claim that you wrote
|
||||
the original software. If you use this software in a
|
||||
product, an acknowledgment in the product
|
||||
documentation is required.
|
||||
|
||||
2. Altered source versions must be plainly marked as
|
||||
such, and must not be misrepresented as being the
|
||||
original software.
|
||||
|
||||
3. This notice may not be removed or altered from any
|
||||
source distribution.
|
||||
*/
|
||||
|
||||
#include "SideInfo.h"
|
||||
|
||||
SideInfo::SideInfo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SideInfo::~SideInfo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool SideInfo::Load(Header * pHead, unsigned char *FromHere)
|
||||
{
|
||||
unsigned long ch, gr, scfsi_band, region, window;
|
||||
|
||||
bs.Load(FromHere);
|
||||
|
||||
if(pHead->GetMpegVersion() == MPEG1)
|
||||
{
|
||||
MainDataBegin = bs.GetBits(9);
|
||||
|
||||
if(pHead->GetMode() == MODE_MONO)
|
||||
{
|
||||
PrivateBits = bs.GetBits(5);
|
||||
}
|
||||
else
|
||||
PrivateBits = bs.GetBits(3);
|
||||
|
||||
for(ch=0; ch<pHead->GetChannels(); ch++)
|
||||
for(scfsi_band=0; scfsi_band<4; scfsi_band++)
|
||||
ScfSi[ch][scfsi_band] = bs.GetBits(1);
|
||||
|
||||
for(gr=0; gr<2; gr++)
|
||||
{
|
||||
for(ch=0; ch<pHead->GetChannels(); ch++)
|
||||
{
|
||||
grinf[gr][ch].Part23Length = bs.GetBits(12);
|
||||
grinf[gr][ch].BigValues = bs.GetBits(9);
|
||||
grinf[gr][ch].GlobalGain = bs.GetBits(8);
|
||||
|
||||
grinf[gr][ch].ScalefacCompress = bs.GetBits(4);
|
||||
|
||||
grinf[gr][ch].WindowSwitchingFlag = bs.GetBits(1);
|
||||
|
||||
if(grinf[gr][ch].WindowSwitchingFlag == 1)
|
||||
{
|
||||
grinf[gr][ch].BlockType = bs.GetBits(2);
|
||||
if(grinf[gr][ch].BlockType == 0)
|
||||
return false;
|
||||
|
||||
grinf[gr][ch].MixedBlockFlag = bs.GetBits(1);
|
||||
|
||||
grinf[gr][ch].TableSelect[0] = bs.GetBits(5);
|
||||
grinf[gr][ch].TableSelect[1] = bs.GetBits(5);
|
||||
grinf[gr][ch].TableSelect[2] = 0;
|
||||
|
||||
grinf[gr][ch].SubblockGain[0] = bs.GetBits(3);
|
||||
grinf[gr][ch].SubblockGain[1] = bs.GetBits(3);
|
||||
grinf[gr][ch].SubblockGain[2] = bs.GetBits(3);
|
||||
|
||||
// not used in short blocks
|
||||
if( (grinf[gr][ch].BlockType == BLOCKTYPE_3WIN) &&
|
||||
(grinf[gr][ch].MixedBlockFlag == 0) )
|
||||
{
|
||||
grinf[gr][ch].Region0Count = 8;
|
||||
}
|
||||
else
|
||||
grinf[gr][ch].Region0Count = 7;
|
||||
|
||||
grinf[gr][ch].Region1Count = 20 - grinf[gr][ch].Region0Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
grinf[gr][ch].BlockType = 0;
|
||||
grinf[gr][ch].MixedBlockFlag = 0;
|
||||
|
||||
grinf[gr][ch].TableSelect[0] = bs.GetBits(5);
|
||||
grinf[gr][ch].TableSelect[1] = bs.GetBits(5);
|
||||
grinf[gr][ch].TableSelect[2] = bs.GetBits(5);
|
||||
|
||||
grinf[gr][ch].SubblockGain[0] = 0;
|
||||
grinf[gr][ch].SubblockGain[1] = 0;
|
||||
grinf[gr][ch].SubblockGain[2] = 0;
|
||||
|
||||
grinf[gr][ch].Region0Count = bs.GetBits(4);
|
||||
grinf[gr][ch].Region1Count = bs.GetBits(3);
|
||||
}
|
||||
|
||||
grinf[gr][ch].PreFlag = bs.GetBits(1);
|
||||
grinf[gr][ch].ScalefacScale = bs.GetBits(1);
|
||||
grinf[gr][ch].Count1Table_Select = bs.GetBits(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MainDataBegin = bs.GetBits(8);
|
||||
|
||||
if(pHead->GetMode() == MODE_MONO)
|
||||
PrivateBits = bs.GetBits(1);
|
||||
else
|
||||
PrivateBits = bs.GetBits(2);
|
||||
|
||||
gr=0;
|
||||
|
||||
for(ch=0; ch<pHead->GetChannels(); ch++)
|
||||
{
|
||||
grinf[gr][ch].Part23Length = bs.GetBits(12);
|
||||
grinf[gr][ch].BigValues = bs.GetBits(9);
|
||||
grinf[gr][ch].GlobalGain = bs.GetBits(8);
|
||||
|
||||
grinf[gr][ch].ScalefacCompress = bs.GetBits(9);
|
||||
|
||||
grinf[gr][ch].WindowSwitchingFlag = bs.GetBits(1);
|
||||
|
||||
if(grinf[gr][ch].WindowSwitchingFlag == 1)
|
||||
{
|
||||
grinf[gr][ch].BlockType = bs.GetBits(2);
|
||||
grinf[gr][ch].MixedBlockFlag = bs.GetBits(1);
|
||||
|
||||
for(region = 0; region < 2; region++)
|
||||
{
|
||||
grinf[gr][ch].TableSelect[region] = bs.GetBits(5);
|
||||
}
|
||||
grinf[gr][ch].TableSelect[2] = 0;
|
||||
|
||||
for(window = 0; window < 3; window++)
|
||||
{
|
||||
grinf[gr][ch].SubblockGain[window] = bs.GetBits(3);
|
||||
}
|
||||
|
||||
// not used in short blocks
|
||||
if( (grinf[gr][ch].BlockType == BLOCKTYPE_3WIN) &&
|
||||
(grinf[gr][ch].MixedBlockFlag == 0) )
|
||||
{
|
||||
grinf[gr][ch].Region0Count = 8;
|
||||
}
|
||||
else
|
||||
grinf[gr][ch].Region0Count = 7;
|
||||
|
||||
grinf[gr][ch].Region1Count = 20 - grinf[gr][ch].Region0Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
grinf[gr][ch].BlockType = 0;
|
||||
|
||||
for(region = 0; region < 3; region++)
|
||||
{
|
||||
grinf[gr][ch].TableSelect[region] = bs.GetBits(5);
|
||||
}
|
||||
|
||||
grinf[gr][ch].Region0Count = bs.GetBits(4);
|
||||
grinf[gr][ch].Region1Count = bs.GetBits(3);
|
||||
}
|
||||
|
||||
grinf[gr][ch].ScalefacScale = bs.GetBits(1);
|
||||
grinf[gr][ch].Count1Table_Select = bs.GetBits(1);
|
||||
}
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2002 Tony Million
|
||||
|
||||
This software is provided 'as-is', without any express or
|
||||
implied warranty. In no event will the authors be held liable
|
||||
for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it
|
||||
and redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. The origin of this software must not be
|
||||
misrepresented; you must not claim that you wrote
|
||||
the original software. If you use this software in a
|
||||
product, an acknowledgment in the product
|
||||
documentation is required.
|
||||
|
||||
2. Altered source versions must be plainly marked as
|
||||
such, and must not be misrepresented as being the
|
||||
original software.
|
||||
|
||||
3. This notice may not be removed or altered from any
|
||||
source distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BitStream.h" // Added by ClassView
|
||||
#include "Header.h"
|
||||
|
||||
/* used in Granule.block_type */
|
||||
#define BLOCKTYPE_NORMAL 0
|
||||
#define BLOCKTYPE_START 1
|
||||
#define BLOCKTYPE_3WIN 2
|
||||
#define BLOCKTYPE_STOP 3
|
||||
|
||||
#define MAXCH 2
|
||||
#define MAXGR 2
|
||||
#define MAXSCFCI 4
|
||||
|
||||
class SideInfo
|
||||
{
|
||||
protected:
|
||||
struct GranuleInfo
|
||||
{
|
||||
unsigned int Part23Length; // number of bits used for scalefactors and huffmancode data
|
||||
unsigned int BigValues;
|
||||
unsigned int GlobalGain;
|
||||
|
||||
unsigned int ScalefacCompress;
|
||||
unsigned int WindowSwitchingFlag;
|
||||
|
||||
unsigned int BlockType;
|
||||
unsigned int MixedBlockFlag;
|
||||
|
||||
unsigned int TableSelect[4];
|
||||
unsigned int SubblockGain[4];
|
||||
|
||||
unsigned int Region0Count;
|
||||
unsigned int Region1Count;
|
||||
|
||||
unsigned int PreFlag;
|
||||
|
||||
unsigned int ScalefacScale;
|
||||
unsigned int Count1Table_Select;
|
||||
|
||||
unsigned int Scalefac_Long[23]; /* actual scalefactors for this granule */
|
||||
unsigned int Scalefac_Short[13][3]; /* scalefactors used in short windows */
|
||||
|
||||
unsigned int IntensityScale;
|
||||
unsigned int is_max[21];
|
||||
};
|
||||
|
||||
BitStream bs;
|
||||
|
||||
public:
|
||||
SideInfo();
|
||||
virtual ~SideInfo();
|
||||
|
||||
bool Load(Header * pHead, unsigned char * FromHere);
|
||||
|
||||
public:
|
||||
unsigned int MainDataBegin;
|
||||
unsigned int PrivateBits;
|
||||
|
||||
unsigned int ScfSi[MAXCH][MAXSCFCI];
|
||||
|
||||
GranuleInfo grinf[MAXGR][MAXCH];
|
||||
};
|
@ -1,286 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8,00"
|
||||
Name="mp3decoder"
|
||||
ProjectGUID="{293471C3-93F8-4C70-AC2B-9F9211529C3B}"
|
||||
RootNamespace="mp3decoder"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)/bin/$(ConfigurationName)/plugins"
|
||||
IntermediateDirectory="$(SolutionDir)/obj/$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=".;../..;../../3rdparty/include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="shlwapi.lib"
|
||||
AdditionalLibraryDirectories="../../3rdparty/lib"
|
||||
GenerateDebugInformation="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)/bin/$(ConfigurationName)/plugins"
|
||||
IntermediateDirectory="$(SolutionDir)/obj/$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=".;../..;../../3rdparty/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="shlwapi.lib"
|
||||
AdditionalLibraryDirectories="../../3rdparty/lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="decoder"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\BaseDecoder.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BaseDecoder.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BitReservoir.H"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BitStream.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BitStream.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CRC.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CRC.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Frame.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\FrameSplitter.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\FrameSplitter.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Header.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Header.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\IMPEGDecoder.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Layer3Decoder.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Layer3Decoder.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\resource.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SideInfo.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SideInfo.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="plugin"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\MP3Decoder.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MP3Decoder.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\mp3decoder_plugin.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MP3SourceSupplier.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MP3SourceSupplier.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@ -1,124 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{293471C3-93F8-4C70-AC2B-9F9211529C3B}</ProjectGuid>
|
||||
<RootNamespace>mp3decoder</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)/bin/$(Configuration)/plugins\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">./obj/$(Configuration)\</IntDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)/bin/$(Configuration)/plugins\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">./obj/$(Configuration)\</IntDir>
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>.;../..;../../3rdparty/include;../../../../boost_1_60_0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>../../3rdparty/lib;../../../../boost_1_60_0/lib32-msvc-14.0;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>.;../..;../../3rdparty/include;../../../../boost_1_60_0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>../../3rdparty/lib;../../../../boost_1_60_0/lib32-msvc-14.0;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="BaseDecoder.cpp" />
|
||||
<ClCompile Include="BitStream.cpp" />
|
||||
<ClCompile Include="CRC.cpp" />
|
||||
<ClCompile Include="FrameSplitter.cpp" />
|
||||
<ClCompile Include="Header.cpp" />
|
||||
<ClCompile Include="Layer3Decoder.cpp" />
|
||||
<ClCompile Include="Mp3Decoder.cpp" />
|
||||
<ClCompile Include="SideInfo.cpp" />
|
||||
<ClCompile Include="mp3decoder_plugin.cpp" />
|
||||
<ClCompile Include="Mp3DecoderFactory.cpp" />
|
||||
<ClCompile Include="stdafx.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="BaseDecoder.h" />
|
||||
<ClInclude Include="BitReservoir.H" />
|
||||
<ClInclude Include="BitStream.h" />
|
||||
<ClInclude Include="CRC.h" />
|
||||
<ClInclude Include="Frame.h" />
|
||||
<ClInclude Include="FrameSplitter.h" />
|
||||
<ClInclude Include="Header.h" />
|
||||
<ClInclude Include="IMPEGDecoder.h" />
|
||||
<ClInclude Include="Layer3Decoder.h" />
|
||||
<ClInclude Include="Mp3Decoder.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="SideInfo.h" />
|
||||
<ClInclude Include="Mp3DecoderFactory.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -1,94 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="decoder">
|
||||
<UniqueIdentifier>{33848a4c-c2ee-4abc-927c-2cf8f79efb14}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="plugin">
|
||||
<UniqueIdentifier>{afc1b3ef-4536-45a9-b6c5-babca17d9a10}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="BaseDecoder.cpp">
|
||||
<Filter>decoder</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BitStream.cpp">
|
||||
<Filter>decoder</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CRC.cpp">
|
||||
<Filter>decoder</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FrameSplitter.cpp">
|
||||
<Filter>decoder</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Header.cpp">
|
||||
<Filter>decoder</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Layer3Decoder.cpp">
|
||||
<Filter>decoder</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SideInfo.cpp">
|
||||
<Filter>decoder</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mp3decoder_plugin.cpp">
|
||||
<Filter>plugin</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>plugin</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Mp3DecoderFactory.cpp">
|
||||
<Filter>plugin</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Mp3Decoder.cpp">
|
||||
<Filter>plugin</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="BaseDecoder.h">
|
||||
<Filter>decoder</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BitReservoir.H">
|
||||
<Filter>decoder</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BitStream.h">
|
||||
<Filter>decoder</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CRC.h">
|
||||
<Filter>decoder</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Frame.h">
|
||||
<Filter>decoder</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FrameSplitter.h">
|
||||
<Filter>decoder</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Header.h">
|
||||
<Filter>decoder</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IMPEGDecoder.h">
|
||||
<Filter>decoder</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Layer3Decoder.h">
|
||||
<Filter>decoder</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>decoder</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SideInfo.h">
|
||||
<Filter>decoder</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>plugin</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Mp3DecoderFactory.h">
|
||||
<Filter>plugin</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Mp3Decoder.h">
|
||||
<Filter>plugin</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,68 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright © 2008, Björn Olievier
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <core/sdk/IPlugin.h>
|
||||
#include <core/sdk/IDecoder.h>
|
||||
#include "Mp3DecoderFactory.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define DLLEXPORT
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
class MP3DecoderPlugin : public musik::core::IPlugin
|
||||
{
|
||||
void Destroy() { delete this; }
|
||||
const char* Name() { return "MP3 IDecoder"; };
|
||||
const char* Version() { return "0.2"; };
|
||||
const char* Author() { return "Björn Olievier, clangen"; };
|
||||
};
|
||||
|
||||
extern "C" DLLEXPORT musik::core::IPlugin* GetPlugin() {
|
||||
return new MP3DecoderPlugin();
|
||||
}
|
||||
|
||||
extern "C" DLLEXPORT IDecoderFactory* GetDecoderFactory() {
|
||||
return new Mp3DecoderFactory();
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by oggPlugin.rc
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
@ -1,8 +0,0 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// oggPlugin.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <core/sdk/config.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <shlwapi.h>
|
||||
#else
|
||||
#define __forceinline inline
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
@ -51,7 +51,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
||||
class Mpg123Plugin : public musik::core::sdk::IPlugin {
|
||||
virtual void Destroy() { delete this; }
|
||||
virtual const char* Name() { return "mpg123 IDecoder"; }
|
||||
virtual const char* Version() { return "0.2"; }
|
||||
virtual const char* Version() { return "0.3"; }
|
||||
virtual const char* Author() { return "Daniel Önnerby, clangen"; }
|
||||
};
|
||||
|
||||
|
@ -52,7 +52,7 @@ class OggDecoderPlugin : public musik::core::sdk::IPlugin {
|
||||
public:
|
||||
void Destroy() { delete this; };
|
||||
const char* Name() { return "Ogg IDecoder"; };
|
||||
const char* Version() { return "0.2"; };
|
||||
const char* Version() { return "0.3"; };
|
||||
const char* Author() { return "Björn Olievier, clangen"; };
|
||||
};
|
||||
|
||||
|
@ -1,7 +0,0 @@
|
||||
set (pulseout_SOURCES
|
||||
pulseout_plugin.cpp
|
||||
PulseOut.cpp
|
||||
)
|
||||
|
||||
add_library(pulseout SHARED ${pulseout_SOURCES})
|
||||
target_link_libraries(pulseout ${musikbox_LINK_LIBS} pulse)
|
@ -1,512 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2007-2016 musikcube team
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "PulseOut.h"
|
||||
#include <iostream>
|
||||
|
||||
#define BUFFER_COUNT 8 /* seems to work well? */
|
||||
|
||||
using namespace musik::core::audio;
|
||||
|
||||
/* a little RAII type that ensures the main loop is locked immediately,
|
||||
and automatically unlocked when the instances goes out of scope */
|
||||
class MainLoopLock {
|
||||
public:
|
||||
MainLoopLock(pa_threaded_mainloop* mainLoop) {
|
||||
this->mainLoop = mainLoop;
|
||||
pa_threaded_mainloop_lock(mainLoop);
|
||||
}
|
||||
|
||||
~MainLoopLock() {
|
||||
pa_threaded_mainloop_unlock(this->mainLoop);
|
||||
}
|
||||
|
||||
private:
|
||||
pa_threaded_mainloop* mainLoop;
|
||||
};
|
||||
|
||||
/* utility method to block waiting for a pa_operation to complete */
|
||||
static inline bool waitForCompletion(pa_operation *op, pa_threaded_mainloop *loop) {
|
||||
if (op) {
|
||||
pa_operation_state_t state;
|
||||
while ((state = pa_operation_get_state(op)) == PA_OPERATION_RUNNING) {
|
||||
pa_threaded_mainloop_wait(loop);
|
||||
}
|
||||
|
||||
pa_operation_unref(op);
|
||||
return (state == PA_OPERATION_DONE);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void notifyBufferCompleted(PulseOut::BufferContext* context) {
|
||||
IBufferProvider* provider = context->provider;
|
||||
IBuffer* buffer = context->buffer;
|
||||
provider->OnBufferProcessed(buffer);
|
||||
}
|
||||
|
||||
PulseOut::PulseOut() {
|
||||
this->volume = 1.0f;
|
||||
|
||||
this->bytesConsumed = 0;
|
||||
this->bytesWritten = 0;
|
||||
|
||||
this->pulse.loop = NULL;
|
||||
this->pulse.context = NULL;
|
||||
this->pulse.stream = NULL;
|
||||
this->pulse.format.format = PA_SAMPLE_FLOAT32LE;
|
||||
this->pulse.format.rate = 0;
|
||||
this->pulse.format.channels = 0;
|
||||
|
||||
this->quit = false;
|
||||
|
||||
this->InitPulse();
|
||||
}
|
||||
|
||||
PulseOut::~PulseOut() {
|
||||
this->Stop();
|
||||
this->DeinitPulse();
|
||||
this->quit = true;
|
||||
this->thread->join();
|
||||
}
|
||||
|
||||
void PulseOut::Destroy() {
|
||||
delete this;
|
||||
}
|
||||
|
||||
void PulseOut::Pause() {
|
||||
this->SetPaused(true);
|
||||
}
|
||||
|
||||
void PulseOut::Resume() {
|
||||
this->SetPaused(false);
|
||||
}
|
||||
|
||||
void PulseOut::SetVolume(double volume) {
|
||||
this->volume = volume;
|
||||
|
||||
boost::recursive_mutex::scoped_lock bufferLock(this->mutex);
|
||||
|
||||
if (this->pulse.stream) {
|
||||
pa_cvolume vol;
|
||||
|
||||
pa_cvolume_set(&vol, 2, pa_sw_volume_from_linear(volume));
|
||||
|
||||
MainLoopLock loopLock(this->pulse.loop);
|
||||
|
||||
pa_context_set_sink_input_volume(
|
||||
this->pulse.context,
|
||||
pa_stream_get_index(this->pulse.stream),
|
||||
&vol,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void PulseOut::Stop() {
|
||||
std::deque<std::shared_ptr<BufferContext> > toNotify;
|
||||
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock bufferLock(this->mutex);
|
||||
std::swap(this->buffers, toNotify);
|
||||
|
||||
if (this->pulse.stream) {
|
||||
/* unset the callback so we don't try to immediately re-fill
|
||||
the buffer. or, worse, deadlock */
|
||||
pa_stream_set_write_callback(
|
||||
this->pulse.stream, NULL, NULL);
|
||||
|
||||
pa_operation* flushOp = NULL;
|
||||
|
||||
{
|
||||
MainLoopLock loopLock(this->pulse.loop);
|
||||
|
||||
flushOp = pa_stream_flush(
|
||||
this->pulse.stream,
|
||||
&PulseOut::OnPulseStreamSuccess,
|
||||
this);
|
||||
|
||||
if (flushOp) {
|
||||
waitForCompletion(flushOp, this->pulse.loop);
|
||||
}
|
||||
}
|
||||
|
||||
/* reset the callback */
|
||||
pa_stream_set_write_callback(
|
||||
this->pulse.stream,
|
||||
&PulseOut::OnPulseStreamWrite,
|
||||
this);
|
||||
}
|
||||
|
||||
this->bytesConsumed = 0;
|
||||
this->bytesWritten = 0;
|
||||
}
|
||||
|
||||
/* all buffers are dead. notify the IBufferProvider */
|
||||
auto it = toNotify.begin();
|
||||
while (it != toNotify.end()) {
|
||||
notifyBufferCompleted((*it).get());
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
bool PulseOut::Play(IBuffer *buffer, IBufferProvider *provider) {
|
||||
if (!this->pulse.stream ||
|
||||
this->pulse.format.rate != buffer->SampleRate() ||
|
||||
this->pulse.format.channels != buffer->Channels())
|
||||
{
|
||||
if (this->pulse.stream) {
|
||||
std::cerr << "PulseOut: stream switched formats; not handled\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
this->DeinitPulseStream();
|
||||
if (!this->InitPulseStream(buffer->SampleRate(), buffer->Channels())) {
|
||||
std::cerr << "PulseOut: could not initialize stream for playback\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->CountBuffersWithProvider(provider) >= BUFFER_COUNT) {
|
||||
// std::cerr << "PulseOut: buffers are full!\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<BufferContext> context(new BufferContext());
|
||||
context->output = this;
|
||||
context->buffer = buffer;
|
||||
context->provider = provider;
|
||||
context->lastByte = this->bytesWritten + buffer->Bytes();
|
||||
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock bufferLock(this->mutex);
|
||||
this->buffers.push_back(context);
|
||||
}
|
||||
|
||||
MainLoopLock loopLock(this->pulse.loop);
|
||||
|
||||
int error =
|
||||
pa_stream_write(
|
||||
this->pulse.stream,
|
||||
static_cast<void*>(buffer->BufferPointer()),
|
||||
buffer->Bytes(),
|
||||
NULL,
|
||||
0,
|
||||
PA_SEEK_RELATIVE);
|
||||
|
||||
if (error) {
|
||||
std::cerr << "PulseOut: FAILED!! this should not happen." << error << std::endl;
|
||||
notifyBufferCompleted(context.get());
|
||||
}
|
||||
else {
|
||||
boost::recursive_mutex::scoped_lock bufferLock(this->mutex);
|
||||
this->bytesWritten += buffer->Bytes();
|
||||
}
|
||||
|
||||
return !error;
|
||||
}
|
||||
|
||||
void PulseOut::SetPaused(bool paused) {
|
||||
boost::recursive_mutex::scoped_lock bufferLock(this->mutex);
|
||||
|
||||
if (this->pulse.stream) {
|
||||
pa_operation* corkOp = NULL;
|
||||
|
||||
{
|
||||
MainLoopLock loopLock(this->pulse.loop);
|
||||
|
||||
corkOp = pa_stream_cork(
|
||||
this->pulse.stream,
|
||||
paused ? 1 : 0,
|
||||
&PulseOut::OnPulseStreamSuccess,
|
||||
this);
|
||||
|
||||
if (corkOp) {
|
||||
waitForCompletion(corkOp, this->pulse.loop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PulseOut::OnPulseStreamWrite(pa_stream *s, size_t bytes, void *data) {
|
||||
PulseOut* out = static_cast<PulseOut*>(data);
|
||||
std::list<std::shared_ptr<BufferContext> > toNotify;
|
||||
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock bufferLock(out->mutex);
|
||||
|
||||
out->bytesConsumed += bytes;
|
||||
|
||||
auto it = out->buffers.begin();
|
||||
while (it != out->buffers.end()) {
|
||||
if (out->bytesConsumed >= (*it)->lastByte) {
|
||||
toNotify.push_back(*it);
|
||||
it = out->buffers.erase(it);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* actually notify here */
|
||||
auto it = toNotify.begin();
|
||||
while (it != toNotify.end()) {
|
||||
notifyBufferCompleted((*it).get());
|
||||
++it;
|
||||
}
|
||||
|
||||
// std::cerr << bytes << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void PulseOut::OnPulseContextStateChanged(pa_context *context, void *data) {
|
||||
PulseOut* out = static_cast<PulseOut*>(data);
|
||||
|
||||
const pa_context_state_t state = pa_context_get_state(context);
|
||||
|
||||
std::cerr << "PulseOut: context connection state changed: " << state << std::endl;
|
||||
|
||||
switch (state) {
|
||||
case PA_CONTEXT_READY:
|
||||
case PA_CONTEXT_FAILED:
|
||||
case PA_CONTEXT_TERMINATED:
|
||||
pa_threaded_mainloop_signal(out->pulse.loop, 0);
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void PulseOut::OnPulseStreamStateChanged(pa_stream *stream, void *data) {
|
||||
PulseOut* out = static_cast<PulseOut*>(data);
|
||||
|
||||
const pa_stream_state_t state = pa_stream_get_state(stream);
|
||||
|
||||
std::cerr << "PulseOut: stream connection state changed: " << state << std::endl;
|
||||
|
||||
switch (state) {
|
||||
case PA_STREAM_READY:
|
||||
case PA_STREAM_FAILED:
|
||||
case PA_STREAM_TERMINATED:
|
||||
pa_threaded_mainloop_signal(out->pulse.loop, 0);
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void PulseOut::OnPulseStreamSuccess(pa_stream *s, int success, void *data) {
|
||||
PulseOut* out = static_cast<PulseOut*>(data);
|
||||
pa_threaded_mainloop_signal(out->pulse.loop, 0);
|
||||
}
|
||||
|
||||
void PulseOut::InitPulse() {
|
||||
if (!this->InitPulseEventLoopAndContext()) {
|
||||
this->DeinitPulse();
|
||||
}
|
||||
}
|
||||
|
||||
bool PulseOut::InitPulseEventLoopAndContext() {
|
||||
std::cerr << "PulseOut: init...\n";
|
||||
|
||||
this->pulse.loop = pa_threaded_mainloop_new();
|
||||
|
||||
if (this->pulse.loop) {
|
||||
std::cerr << "PulseOut: init ok, starting...\n";
|
||||
|
||||
int error = pa_threaded_mainloop_start(this->pulse.loop);
|
||||
if (error) {
|
||||
pa_threaded_mainloop_free(this->pulse.loop);
|
||||
this->pulse.loop = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cerr << "PulseOut: started ok.\n";
|
||||
}
|
||||
|
||||
pa_mainloop_api* api = pa_threaded_mainloop_get_api(this->pulse.loop);
|
||||
|
||||
MainLoopLock loopLock(this->pulse.loop);
|
||||
|
||||
this->pulse.context = pa_context_new(api, "musikcube");
|
||||
|
||||
if (this->pulse.context) {
|
||||
std::cerr << "PulseOut: context created";
|
||||
|
||||
pa_context_set_state_callback(
|
||||
this->pulse.context,
|
||||
&PulseOut::OnPulseContextStateChanged,
|
||||
this);
|
||||
|
||||
int error =
|
||||
pa_context_connect(
|
||||
this->pulse.context,
|
||||
NULL,
|
||||
PA_CONTEXT_NOFAIL,
|
||||
NULL);
|
||||
|
||||
bool connected = false;
|
||||
while (!error && !connected) {
|
||||
pa_context_state_t state =
|
||||
pa_context_get_state(this->pulse.context);
|
||||
|
||||
if (state == PA_CONTEXT_READY) {
|
||||
std::cerr << "PulseOut: connected!\n";
|
||||
connected = true;
|
||||
}
|
||||
else if (!PA_CONTEXT_IS_GOOD(state)) {
|
||||
std::cerr << "PulseOut: corrupted state! bailing.\n";
|
||||
error = true;
|
||||
}
|
||||
else {
|
||||
std::cerr << "PulseOut: waiting for connection...\n";
|
||||
pa_threaded_mainloop_wait(this->pulse.loop);
|
||||
}
|
||||
}
|
||||
|
||||
if (connected && !error) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PulseOut::InitPulseStream(size_t rate, size_t channels) {
|
||||
bool ready = false;
|
||||
|
||||
{
|
||||
MainLoopLock loopLock(this->pulse.loop);
|
||||
|
||||
this->pulse.format.rate = rate;
|
||||
this->pulse.format.channels = channels;
|
||||
|
||||
this->pulse.stream = pa_stream_new(
|
||||
this->pulse.context,
|
||||
"musikcube PulseOut stream",
|
||||
&this->pulse.format,
|
||||
NULL); /* channel mapping */
|
||||
|
||||
std::cerr << "PulseOut: creating stream...\n";
|
||||
|
||||
if (this->pulse.stream) {
|
||||
std::cerr << "PulseOut: stream created.\n";
|
||||
|
||||
pa_stream_set_state_callback(
|
||||
this->pulse.stream,
|
||||
&PulseOut::OnPulseStreamStateChanged,
|
||||
this);
|
||||
|
||||
pa_stream_set_write_callback(
|
||||
this->pulse.stream,
|
||||
&PulseOut::OnPulseStreamWrite,
|
||||
this);
|
||||
|
||||
int flags =
|
||||
PA_STREAM_AUTO_TIMING_UPDATE |
|
||||
PA_STREAM_INTERPOLATE_TIMING;
|
||||
|
||||
std::cerr << "PulseOut: connecting the stream for playing...\n";
|
||||
|
||||
int error = pa_stream_connect_playback(
|
||||
this->pulse.stream,
|
||||
NULL, /* device id */
|
||||
NULL, /* buffering attributes */
|
||||
(pa_stream_flags_t) flags, /* additional flags */
|
||||
NULL, /* initial volume. docs suggest NULL. */
|
||||
NULL); /* stream to synchronize with. */
|
||||
|
||||
if (!error) {
|
||||
std::cerr << "PulseOut: connected. waiting for the stream to become ready\n";
|
||||
|
||||
pa_threaded_mainloop_wait(this->pulse.loop);
|
||||
ready = pa_stream_get_state(this->pulse.stream) == PA_STREAM_READY;
|
||||
|
||||
std::cerr << (ready ? "PulseOut: stream is ready!" : "stream failed") << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ready) {
|
||||
this->SetVolume(this->volume);
|
||||
this->Resume();
|
||||
}
|
||||
|
||||
return ready;
|
||||
}
|
||||
|
||||
void PulseOut::DeinitPulseStream() {
|
||||
if (this->pulse.stream) {
|
||||
std::cerr << "PulseOut: freeing stream...\n";
|
||||
MainLoopLock loopLock(this->pulse.loop);
|
||||
pa_stream_disconnect(this->pulse.stream);
|
||||
pa_stream_unref(this->pulse.stream);
|
||||
this->pulse.stream = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void PulseOut::DeinitPulse() {
|
||||
this->DeinitPulseStream();
|
||||
|
||||
if (this->pulse.context) {
|
||||
std::cerr << "PulseOut: freeing context...\n";
|
||||
MainLoopLock loopLock(this->pulse.loop);
|
||||
pa_context_disconnect(this->pulse.context);
|
||||
pa_context_unref(this->pulse.context);
|
||||
this->pulse.context = NULL;
|
||||
}
|
||||
|
||||
if (this->pulse.loop) {
|
||||
std::cerr << "PulseOut: stopping...\n";
|
||||
pa_threaded_mainloop_stop(this->pulse.loop);
|
||||
pa_threaded_mainloop_free(this->pulse.loop);
|
||||
this->pulse.loop = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t PulseOut::CountBuffersWithProvider(IBufferProvider* provider) {
|
||||
boost::recursive_mutex::scoped_lock bufferLock(this->mutex);
|
||||
|
||||
size_t count = 0;
|
||||
auto it = this->buffers.begin();
|
||||
while (it != this->buffers.end()) {
|
||||
if ((*it)->provider == provider) {
|
||||
++count;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2007-2016 musikcube team
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <core/sdk/IOutput.h>
|
||||
#include <core/sdk/IBufferProvider.h>
|
||||
#include <deque>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/thread/condition.hpp>
|
||||
#include <boost/thread/recursive_mutex.hpp>
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
class PulseOut : public musik::core::audio::IOutput {
|
||||
public:
|
||||
struct BufferContext {
|
||||
PulseOut *output;
|
||||
musik::core::audio::IBuffer *buffer;
|
||||
musik::core::audio::IBufferProvider *provider;
|
||||
unsigned long long lastByte;
|
||||
};
|
||||
|
||||
PulseOut();
|
||||
virtual ~PulseOut();
|
||||
|
||||
virtual void Destroy();
|
||||
virtual void Pause();
|
||||
virtual void Resume();
|
||||
virtual void SetVolume(double volume);
|
||||
virtual void Stop();
|
||||
|
||||
virtual bool Play(
|
||||
musik::core::audio::IBuffer *buffer,
|
||||
musik::core::audio::IBufferProvider *provider);
|
||||
|
||||
private:
|
||||
struct Pulse {
|
||||
pa_threaded_mainloop* loop;
|
||||
pa_stream* stream;
|
||||
pa_context* context;
|
||||
pa_sample_spec format;
|
||||
};
|
||||
|
||||
static void OnPulseContextStateChanged(pa_context *c, void *data);
|
||||
static void OnPulseStreamStateChanged(pa_stream *s, void *data);
|
||||
static void OnPulseStreamSuccess(pa_stream *s, int success, void *data);
|
||||
static void OnPulseBufferPlayed(void *data);
|
||||
static void OnPulseStreamWrite(pa_stream *s, size_t bytes, void *data);
|
||||
|
||||
size_t CountBuffersWithProvider(musik::core::audio::IBufferProvider *provider);
|
||||
|
||||
void InitPulse();
|
||||
bool InitPulseEventLoopAndContext();
|
||||
bool InitPulseStream(size_t rate, size_t channels);
|
||||
void DeinitPulseStream();
|
||||
void DeinitPulse();
|
||||
void SetPaused(bool paused);
|
||||
|
||||
double volume;
|
||||
std::deque<std::shared_ptr<BufferContext> > buffers;
|
||||
std::unique_ptr<boost::thread> thread;
|
||||
boost::recursive_mutex mutex;
|
||||
Pulse pulse;
|
||||
unsigned long long bytesWritten;
|
||||
unsigned long long bytesConsumed;
|
||||
volatile bool quit;
|
||||
};
|
@ -1,64 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2007-2016 musikcube team
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <core/sdk/IPlugin.h>
|
||||
#include <core/sdk/IOutput.h>
|
||||
#include "PulseOut.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define DLLEXPORT
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
class CoreAudioOutPlugin : public musik::core::IPlugin {
|
||||
void Destroy() { delete this; };
|
||||
const char* Name() { return "PulseAudio IOutput"; };
|
||||
const char* Version() { return "0.1"; };
|
||||
const char* Author() { return "clangen"; };
|
||||
};
|
||||
|
||||
extern "C" DLLEXPORT musik::core::IPlugin* GetPlugin() {
|
||||
return new CoreAudioOutPlugin;
|
||||
}
|
||||
|
||||
extern "C" DLLEXPORT musik::core::audio::IOutput* GetAudioOutput() {
|
||||
return new PulseOut();
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
set ( stdout_SOURCES
|
||||
stdout_plugin.cpp
|
||||
StdOut.cpp
|
||||
StdOutBuffer.cpp
|
||||
)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
add_definitions(-DWIN32)
|
||||
if(NOT DEFINED MINGW)
|
||||
|
||||
endif(NOT DEFINED MINGW)
|
||||
else(CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -fpermissive)
|
||||
endif(CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
|
||||
add_definitions(
|
||||
-DXML_STATIC
|
||||
-D_CRT_SECURE_NO_DEPRECATE
|
||||
-D_DEBUG
|
||||
)
|
||||
|
||||
#include_directories( ../../core )
|
||||
include_directories(/usr/include)
|
||||
|
||||
add_library( stdout SHARED ${stdout_SOURCES} )
|
||||
target_link_libraries( stdout ${musikCube_LINK_LIBS} )
|
||||
|
||||
|
@ -1,216 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2007, Daniel nnerby
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include "StdOut.h"
|
||||
|
||||
StdOut::StdOut()
|
||||
:waveHandle(NULL)
|
||||
,maxBuffers(32)
|
||||
,currentVolume(1.0)
|
||||
,addToRemovedBuffers(false)
|
||||
,device("default")
|
||||
,output(stdout)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "StdOut::StdOut() called" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
StdOut::~StdOut(){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "StdOut::~StdOut() called" << std::endl;
|
||||
#endif
|
||||
this->ClearBuffers();
|
||||
}
|
||||
|
||||
void* StdOut::getWaveHandle() {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "StdOut::getWaveHandle() called" << std::endl;
|
||||
#endif
|
||||
return this->waveHandle;
|
||||
}
|
||||
|
||||
void StdOut::Destroy(){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "StdOut::Destroy() called" << std::endl;
|
||||
#endif
|
||||
delete this;
|
||||
}
|
||||
|
||||
void StdOut::Pause(){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "StdOut::Pause() called" << std::endl;
|
||||
#endif
|
||||
//TODO: Do something here
|
||||
}
|
||||
|
||||
void StdOut::Resume(){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "StdOut::Resume() called" << std::endl;
|
||||
#endif
|
||||
//TODO: Do something here
|
||||
}
|
||||
|
||||
void StdOut::SetVolume(double volume){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "StdOut::SetVolume() called" << std::endl;
|
||||
#endif
|
||||
this->currentVolume = volume; //TODO: Finish SetVolume() function
|
||||
}
|
||||
|
||||
void StdOut::ClearBuffers(){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "StdOut::ClearBuffers() called" << std::endl;
|
||||
#endif
|
||||
//TODO: Clear buffers
|
||||
}
|
||||
|
||||
void StdOut::RemoveBuffer(StdOutBuffer *buffer){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "StdOut::RemoveBuffer() called" << std::endl;
|
||||
#endif
|
||||
BufferList clearBuffers;
|
||||
{
|
||||
boost::mutex::scoped_lock lock(this->mutex);
|
||||
bool found(false);
|
||||
for(BufferList::iterator buf=this->buffers.begin();buf!=this->buffers.end() && !found;){
|
||||
if(buf->get()==buffer){
|
||||
// if( !(*buf)->ReadyToRelease() ){
|
||||
this->removedBuffers.push_back(*buf);
|
||||
// }
|
||||
clearBuffers.push_back(*buf);
|
||||
buf=this->buffers.erase(buf);
|
||||
found=true;
|
||||
}else{
|
||||
++buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StdOut::ReleaseBuffers(){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "StdOut::ReleaseBuffers() called" << std::endl;
|
||||
#endif
|
||||
BufferList clearBuffers;
|
||||
{
|
||||
boost::mutex::scoped_lock lock(this->mutex);
|
||||
for(BufferList::iterator buf=this->removedBuffers.begin();buf!=this->removedBuffers.end();){
|
||||
clearBuffers.push_back(*buf);
|
||||
buf = this->removedBuffers.erase(buf);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool StdOut::PlayBuffer(IBuffer *buffer,IPlayer *player){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "StdOut::PlayBuffer() called" << std::endl;
|
||||
#endif
|
||||
|
||||
size_t bufferSize = 0;
|
||||
{
|
||||
boost::mutex::scoped_lock lock(this->mutex);
|
||||
bufferSize = this->buffers.size();
|
||||
}
|
||||
|
||||
// if the format should change, wait for all buffers to be released
|
||||
if(bufferSize>0 && (this->currentChannels!=buffer->Channels() || this->currentSampleRate!=buffer->SampleRate())){
|
||||
// Format has changed
|
||||
// this->player->Notify()
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(bufferSize<this->maxBuffers){
|
||||
|
||||
// Add to the waveout internal buffers
|
||||
StdOutBufferPtr outBuffer(new StdOutBuffer(this,buffer,player));
|
||||
|
||||
// Header should now be prepared, lets add to waveout
|
||||
if( outBuffer->AddToOutput() ){
|
||||
// Add to the buffer list
|
||||
{
|
||||
boost::mutex::scoped_lock lock(this->mutex);
|
||||
this->buffers.push_back(outBuffer);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void StdOut::SetFormat(IBuffer *buffer){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "StdOut::SetFormat() called" << std::endl;
|
||||
#endif
|
||||
if(this->currentChannels!=buffer->Channels() || this->currentSampleRate!=buffer->SampleRate() ||this->waveHandle==NULL){
|
||||
this->currentChannels = buffer->Channels();
|
||||
this->currentSampleRate = buffer->SampleRate();
|
||||
|
||||
// Close old waveout
|
||||
if(this->waveHandle!=NULL){
|
||||
this->waveHandle = NULL;
|
||||
}
|
||||
/*
|
||||
// Create a new waveFormat
|
||||
ZeroMemory(&this->waveFormat, sizeof(this->waveFormat));
|
||||
DWORD speakerconfig;
|
||||
|
||||
// Set speaker configuration
|
||||
switch(buffer->Channels()){
|
||||
case 1:
|
||||
speakerconfig = KSAUDIO_SPEAKER_MONO;
|
||||
break;
|
||||
case 2:
|
||||
speakerconfig = KSAUDIO_SPEAKER_STEREO;
|
||||
break;
|
||||
case 4:
|
||||
speakerconfig = KSAUDIO_SPEAKER_QUAD;
|
||||
break;
|
||||
case 5:
|
||||
speakerconfig = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT);
|
||||
break;
|
||||
case 6:
|
||||
speakerconfig = KSAUDIO_SPEAKER_5POINT1;
|
||||
break;
|
||||
default:
|
||||
speakerconfig = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
// Set the volume if it's not already set
|
||||
this->SetVolume(this->currentVolume);
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright © 2009, Julian Cromarty
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "pch.h"
|
||||
#include "StdOutBuffer.h"
|
||||
|
||||
#include <core/audio/IOutput.h>
|
||||
#include <list>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
using namespace musik::core::audio;
|
||||
|
||||
class StdOut : public IOutput{
|
||||
public:
|
||||
StdOut();
|
||||
~StdOut();
|
||||
|
||||
virtual void Destroy();
|
||||
//virtual void Initialize(IPlayer *player);
|
||||
virtual void Pause();
|
||||
virtual void Resume();
|
||||
virtual void SetVolume(double volume);
|
||||
virtual void ClearBuffers();
|
||||
virtual bool PlayBuffer(IBuffer *buffer,IPlayer *player);
|
||||
virtual void ReleaseBuffers();
|
||||
|
||||
void* getWaveHandle();
|
||||
|
||||
public:
|
||||
typedef boost::shared_ptr<StdOutBuffer> StdOutBufferPtr;
|
||||
|
||||
//static void CALLBACK WaveCallback(HWAVEOUT hWave, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD dw2);
|
||||
void RemoveBuffer(StdOutBuffer *buffer);
|
||||
|
||||
private:
|
||||
void SetFormat(IBuffer *buffer);
|
||||
char *device; /* playback device */
|
||||
|
||||
protected:
|
||||
friend class StdOutBuffer;
|
||||
|
||||
// Audio stuff
|
||||
void* waveHandle;
|
||||
FILE* output;
|
||||
|
||||
// Current format
|
||||
int currentChannels;
|
||||
long currentSampleRate;
|
||||
double currentVolume;
|
||||
|
||||
typedef std::list<StdOutBufferPtr> BufferList;
|
||||
BufferList buffers;
|
||||
BufferList removedBuffers;
|
||||
size_t maxBuffers;
|
||||
|
||||
boost::mutex mutex;
|
||||
|
||||
bool addToRemovedBuffers;
|
||||
|
||||
};
|
@ -1,75 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright ﺏ 2007, Daniel ﺿnnerby
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include "StdOutBuffer.h"
|
||||
#include "StdOut.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
StdOutBuffer::StdOutBuffer(StdOut *stdOut,IBuffer *buffer,IPlayer *player)
|
||||
:waveOut(stdOut)
|
||||
,buffer(buffer)
|
||||
,player(player)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "StdOutBuffer::StdOutBuffer()" << std::endl;
|
||||
#endif
|
||||
this->PrepareBuffer();
|
||||
}
|
||||
|
||||
void StdOutBuffer::PrepareBuffer(){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "StdOutBuffer::PrepareBuffer()" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
StdOutBuffer::~StdOutBuffer(void)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "StdOutBuffer::~StdOutBuffer()" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool StdOutBuffer::AddToOutput(){
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "StdOutBuffer::AddToOutput()" << std::endl;
|
||||
#endif
|
||||
void* wHandle = waveOut->getWaveHandle();
|
||||
if (wHandle == NULL) {
|
||||
printf("Error. No device handle \n");
|
||||
return false;
|
||||
}
|
||||
wHandle << (void*)data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,66 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright <20> 2007, Daniel <20>nnerby
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include <core/audio/IBuffer.h>
|
||||
#include <core/audio/IPlayer.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Forward declare
|
||||
class StdOut;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using namespace musik::core::audio;
|
||||
|
||||
class StdOutBuffer
|
||||
{
|
||||
public:
|
||||
StdOutBuffer(StdOut *waveOut,IBuffer *buffer,IPlayer *player);
|
||||
~StdOutBuffer(void);
|
||||
|
||||
bool AddToOutput();
|
||||
void PrepareBuffer();
|
||||
|
||||
StdOut *waveOut;
|
||||
IBuffer *buffer;
|
||||
IPlayer *player;
|
||||
|
||||
|
||||
private:
|
||||
float* data;
|
||||
int bufferLength;
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
@ -1,43 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright <20> 2008, Bj<42>rn Olievier
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Precompiled headers
|
||||
#pragma once
|
||||
|
||||
#include <core/config.h>
|
||||
#include <core/audio/IOutput.h>
|
||||
#include <iostream>
|
||||
|
@ -1,73 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright © 2009, Julian Cromarty
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include <core/IPlugin.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "StdOut.h"
|
||||
|
||||
class StdOutPlugin : public musik::core::IPlugin
|
||||
{
|
||||
void Destroy() { delete this; };
|
||||
|
||||
const utfchar* Name() { return TEXT("StdOut output plugin"); };
|
||||
const utfchar* Version() { return TEXT("0.1"); };
|
||||
const utfchar* Author() { return TEXT("Julian Cromarty"); };
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
musik::core::IPlugin* GetPlugin()
|
||||
{
|
||||
return new StdOutPlugin();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
extern "C" {
|
||||
musik::core::audio::IAudioOutputSupplier* CreateAudioOutputSupplier()
|
||||
{
|
||||
return new StdOutSupplier();
|
||||
}
|
||||
}*/
|
||||
|
||||
extern "C" {
|
||||
musik::core::audio::IOutput* GetAudioOutput()
|
||||
{
|
||||
return new StdOut();
|
||||
}
|
||||
}
|
@ -52,7 +52,7 @@ class TaglibPlugin : public musik::core::sdk::IPlugin {
|
||||
public:
|
||||
virtual void Destroy() { delete this; }
|
||||
virtual const char* Name() { return "Taglib 1.11 IMetadataReader"; }
|
||||
virtual const char* Version() { return "0.2"; }
|
||||
virtual const char* Version() { return "0.3"; }
|
||||
virtual const char* Author() { return "Daniel Önnerby, clangen"; }
|
||||
};
|
||||
|
||||
|
@ -44,7 +44,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
||||
class WaveOutPlugin : public musik::core::sdk::IPlugin {
|
||||
void Destroy() { delete this; };
|
||||
const char* Name() { return "WaveOut IOutput"; };
|
||||
const char* Version() { return "0.2"; };
|
||||
const char* Version() { return "0.3"; };
|
||||
const char* Author() { return "Björn Olievier, clangen"; };
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user