mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-18 00:45:46 -04:00
Initial community commit
This commit is contained in:
70
Src/mp3-mpg123/MP4Factory.cpp
Normal file
70
Src/mp3-mpg123/MP4Factory.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
#include "api__mp3-mpg123.h"
|
||||
#include "MP4Factory.h"
|
||||
#include "mp3_in_mp4.h"
|
||||
|
||||
static const char serviceName[] = "MP4 MP3 Decoder";
|
||||
static const char testString[] = "mp4a";
|
||||
|
||||
// {ADBFEC60-41B4-4903-980B-0FA7E33D3567}
|
||||
static const GUID MPEG4_MP3_GUID =
|
||||
{ 0xadbfec60, 0x41b4, 0x4903, { 0x98, 0xb, 0xf, 0xa7, 0xe3, 0x3d, 0x35, 0x67 } };
|
||||
|
||||
FOURCC MPEG4Factory::GetServiceType()
|
||||
{
|
||||
return WaSvc::MP4AUDIODECODER;
|
||||
}
|
||||
|
||||
const char *MPEG4Factory::GetServiceName()
|
||||
{
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
GUID MPEG4Factory::GetGUID()
|
||||
{
|
||||
return MPEG4_MP3_GUID;
|
||||
}
|
||||
|
||||
void *MPEG4Factory::GetInterface(int global_lock)
|
||||
{
|
||||
return new MPEG4_MP3;
|
||||
}
|
||||
|
||||
int MPEG4Factory::SupportNonLockingInterface()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int MPEG4Factory::ReleaseInterface(void *ifc)
|
||||
{
|
||||
//plugin.service->service_unlock(ifc);
|
||||
MP4AudioDecoder *decoder = static_cast<MP4AudioDecoder *>(ifc);
|
||||
MPEG4_MP3 *mp3Decoder = static_cast<MPEG4_MP3 *>(decoder);
|
||||
delete mp3Decoder;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *MPEG4Factory::GetTestString()
|
||||
{
|
||||
return testString;
|
||||
}
|
||||
|
||||
int MPEG4Factory::ServiceNotify(int msg, int param1, int param2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef CBCLASS
|
||||
#undef CBCLASS
|
||||
#endif
|
||||
|
||||
#define CBCLASS MPEG4Factory
|
||||
START_DISPATCH;
|
||||
CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType)
|
||||
CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName)
|
||||
CB(WASERVICEFACTORY_GETGUID, GetGUID)
|
||||
CB(WASERVICEFACTORY_GETINTERFACE, GetInterface)
|
||||
CB(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface)
|
||||
CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface)
|
||||
CB(WASERVICEFACTORY_GETTESTSTRING, GetTestString)
|
||||
CB(WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify)
|
||||
END_DISPATCH;
|
24
Src/mp3-mpg123/MP4Factory.h
Normal file
24
Src/mp3-mpg123/MP4Factory.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef NULLSOFT_MP3_MP4FACTORY_H
|
||||
#define NULLSOFT_MP3_MP4FACTORY_H
|
||||
|
||||
#include <api/service/waservicefactory.h>
|
||||
#include <api/service/services.h>
|
||||
|
||||
class MPEG4Factory : public waServiceFactory
|
||||
{
|
||||
public:
|
||||
FOURCC GetServiceType();
|
||||
const char *GetServiceName();
|
||||
GUID GetGUID();
|
||||
void *GetInterface(int global_lock);
|
||||
int SupportNonLockingInterface();
|
||||
int ReleaseInterface(void *ifc);
|
||||
const char *GetTestString();
|
||||
int ServiceNotify(int msg, int param1, int param2);
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
26
Src/mp3-mpg123/NSVFactory.cpp
Normal file
26
Src/mp3-mpg123/NSVFactory.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
#include "NSVFactory.h"
|
||||
#include "nsvmain.h"
|
||||
#include "api__mp3-mpg123.h"
|
||||
#include "../nsv/nsvlib.h"
|
||||
|
||||
IAudioDecoder *NSVFactory::CreateAudioDecoder(FOURCC format, IAudioOutput **output)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case NSV_MAKETYPE('M', 'P', '3', ' '):
|
||||
{
|
||||
MP3_Decoder *dec;
|
||||
WASABI_API_MEMMGR->New(&dec);
|
||||
return dec;
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define CBCLASS NSVFactory
|
||||
START_DISPATCH;
|
||||
CB(SVC_NSVFACTORY_CREATEAUDIODECODER, CreateAudioDecoder)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
19
Src/mp3-mpg123/NSVFactory.h
Normal file
19
Src/mp3-mpg123/NSVFactory.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "../nsv/svc_nsvFactory.h"
|
||||
|
||||
// {66AFC6B1-BFFD-49e2-BA71-62009F5266B0}
|
||||
static const GUID mp3_nsv_guid =
|
||||
{ 0x66afc6b1, 0xbffd, 0x49e2, { 0xba, 0x71, 0x62, 0x0, 0x9f, 0x52, 0x66, 0xb0 } };
|
||||
|
||||
|
||||
class NSVFactory : public svc_nsvFactory
|
||||
{
|
||||
public:
|
||||
static const char *getServiceName() { return "MP3 NSV Decoder"; }
|
||||
static GUID getServiceGuid() { return mp3_nsv_guid; }
|
||||
IAudioDecoder *CreateAudioDecoder(FOURCC format, IAudioOutput **output) override;
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
279
Src/mp3-mpg123/adts_mpg123.cpp
Normal file
279
Src/mp3-mpg123/adts_mpg123.cpp
Normal file
@ -0,0 +1,279 @@
|
||||
#include "ADTS_MPG123.h"
|
||||
#include "../winamp/wa_ipc.h"
|
||||
#include <math.h>
|
||||
#include "../nsutil/pcm.h"
|
||||
#include <assert.h>
|
||||
|
||||
ADTS_MPG123::ADTS_MPG123() : decoder(0), gain(1.f)
|
||||
{
|
||||
decoderDelay = 529;
|
||||
|
||||
bitsPerSample = 0;
|
||||
allowRG = false;
|
||||
useFloat = false;
|
||||
channels = 0;
|
||||
sampleRate = 0;
|
||||
decode_buffer = 0;
|
||||
decode_buffer_length = 0;
|
||||
}
|
||||
|
||||
ADTS_MPG123::~ADTS_MPG123()
|
||||
{
|
||||
if (decoder) {
|
||||
mpg123_delete(decoder);
|
||||
decoder = 0;
|
||||
}
|
||||
free(decode_buffer);
|
||||
}
|
||||
|
||||
int ADTS_MPG123::Initialize(bool forceMono, bool reverseStereo, bool allowSurround, int maxBits, bool _allowRG, bool _useFloat, bool _useCRC)
|
||||
{
|
||||
allowRG = _allowRG;
|
||||
useFloat = _useFloat;
|
||||
int downmix = 0;
|
||||
if (reverseStereo)
|
||||
downmix = 2;
|
||||
else
|
||||
downmix = forceMono ? 1 : 0;
|
||||
bitsPerSample = maxBits;
|
||||
|
||||
decoder = mpg123_new(NULL, NULL);
|
||||
long flags = MPG123_QUIET|MPG123_FORCE_FLOAT|MPG123_SKIP_ID3V2|MPG123_IGNORE_STREAMLENGTH|MPG123_IGNORE_INFOFRAME;
|
||||
if (forceMono) {
|
||||
flags |= MPG123_FORCE_MONO;
|
||||
}
|
||||
mpg123_param(decoder, MPG123_FLAGS, flags, 0);
|
||||
mpg123_param(decoder, MPG123_RVA, MPG123_RVA_OFF, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ADTS_MPG123::Open(ifc_mpeg_stream_reader *file)
|
||||
{
|
||||
mpg123_open_feed(decoder);
|
||||
if (allowRG) {
|
||||
gain = file->MPEGStream_Gain();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ADTS_MPG123::Close()
|
||||
{
|
||||
if (decoder) {
|
||||
mpg123_delete(decoder);
|
||||
decoder = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool ADTS_MPG123::_UpdateProperties()
|
||||
{
|
||||
if (decoder && (!channels || !sampleRate)) {
|
||||
long sample_rate = 44100;
|
||||
int channels = 2;
|
||||
int encoding = 0;
|
||||
if (mpg123_getformat(decoder, &sample_rate, &channels, &encoding) == MPG123_OK) {
|
||||
this->channels = channels;
|
||||
this->sampleRate = sample_rate;
|
||||
}
|
||||
}
|
||||
|
||||
return channels && sampleRate;
|
||||
}
|
||||
|
||||
void ADTS_MPG123::GetOutputParameters(size_t *numBits, int *numChannels, int *sampleRate)
|
||||
{
|
||||
_UpdateProperties();
|
||||
*sampleRate = this->sampleRate;
|
||||
*numChannels = this->channels;
|
||||
*numBits = bitsPerSample;
|
||||
}
|
||||
|
||||
void ADTS_MPG123::CalculateFrameSize(int *frameSize)
|
||||
{
|
||||
_UpdateProperties();
|
||||
*frameSize = (int)(bitsPerSample/8) * channels * mpg123_spf(decoder);
|
||||
#if 0 // TODO?
|
||||
if (decoder->GetStreamInfo()->GetLayer() == 1)
|
||||
*frameSize *= 3;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ADTS_MPG123::Flush(ifc_mpeg_stream_reader *file)
|
||||
{
|
||||
mpg123_open_feed(decoder);
|
||||
}
|
||||
|
||||
size_t ADTS_MPG123::GetCurrentBitrate()
|
||||
{
|
||||
mpg123_frameinfo frameInfo;
|
||||
if (mpg123_info(decoder, &frameInfo) == MPG123_OK) {
|
||||
return frameInfo.bitrate;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t ADTS_MPG123::GetDecoderDelay()
|
||||
{
|
||||
return decoderDelay;
|
||||
}
|
||||
|
||||
static void Decimate(const float *input, void *output, size_t numSamples, size_t *outputWritten, int bitsPerSample, bool useFloat, float gain)
|
||||
{
|
||||
if (!useFloat)
|
||||
{
|
||||
// TODO seen a few crashes reported where 'output' is 0
|
||||
nsutil_pcm_FloatToInt_Interleaved_Gain(output, input, bitsPerSample, numSamples, gain);
|
||||
}
|
||||
else if (gain != 1.f)
|
||||
{
|
||||
float *data = (float *)output;
|
||||
for (size_t i=0;i<numSamples;i++)
|
||||
data[i]*=gain;
|
||||
//data[i]=input[i]*gain;
|
||||
}
|
||||
|
||||
*outputWritten = numSamples * (bitsPerSample / 8);
|
||||
}
|
||||
|
||||
int ADTS_MPG123::_Read(ifc_mpeg_stream_reader *_file)
|
||||
{
|
||||
int err;
|
||||
do {
|
||||
unsigned char buffer[4096];
|
||||
size_t bytes = 0;
|
||||
_file->MPEGStream_Read(buffer, sizeof(buffer), &bytes);
|
||||
err = mpg123_feed(decoder, buffer, bytes);
|
||||
} while (err == MPG123_NEED_MORE);
|
||||
switch(err) {
|
||||
case MPG123_OK:
|
||||
return adts::SUCCESS;
|
||||
case MPG123_NEED_MORE:
|
||||
if (_file->MPEGStream_EOF()) {
|
||||
return adts::ENDOFFILE;
|
||||
} else {
|
||||
return adts::NEEDMOREDATA;
|
||||
}
|
||||
default:
|
||||
return adts::FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
notes for mp3 surround implementations
|
||||
need to check the first two frames for ancillary data
|
||||
store first valid in temp
|
||||
store second valid frame in delay line
|
||||
decimate first valid into output buffer
|
||||
ancillary data is stored one frame behind, so PCM data decoded from mp3 frame n combines with anc data from frame n+1
|
||||
*/
|
||||
int ADTS_MPG123::Sync(ifc_mpeg_stream_reader *_file, unsigned __int8 *output, size_t outputSize, size_t *outputWritten, size_t *bitrate)
|
||||
{
|
||||
if (outputWritten) {
|
||||
*outputWritten = 0;
|
||||
}
|
||||
|
||||
int err = _Read(_file);
|
||||
if (err == adts::SUCCESS) {
|
||||
err = mpg123_read(decoder, 0, 0, 0);
|
||||
if (err == MPG123_NEED_MORE) {
|
||||
return adts::NEEDMOREDATA;
|
||||
}
|
||||
if (err != MPG123_NEW_FORMAT
|
||||
&& err != MPG123_OK) {
|
||||
return adts::FAILURE;
|
||||
}
|
||||
_UpdateProperties();
|
||||
mpg123_frameinfo frameInfo;
|
||||
err = mpg123_info(decoder, &frameInfo);
|
||||
if (err == MPG123_OK) {
|
||||
*bitrate = frameInfo.bitrate;
|
||||
return adts::SUCCESS;
|
||||
} else {
|
||||
return adts::NEEDMOREDATA;
|
||||
}
|
||||
} else {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
int ADTS_MPG123::Decode(ifc_mpeg_stream_reader *_file, unsigned __int8 *output, size_t outputSize, size_t *outputWritten, size_t *bitrate, size_t *endCut)
|
||||
{
|
||||
bool retried=false;
|
||||
for (;;) {
|
||||
if (!decode_buffer) {
|
||||
int channels = 2;
|
||||
long sample_rate;
|
||||
int encoding;
|
||||
if (mpg123_getformat(decoder, &sample_rate, &channels, &encoding) == MPG123_OK) {
|
||||
this->channels = channels;
|
||||
decode_buffer_length = sizeof(float) * channels * mpg123_spf(decoder);
|
||||
decode_buffer = (float *)malloc(decode_buffer_length);
|
||||
if (!decode_buffer) {
|
||||
return adts::FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float *flData=useFloat?(float *)output:decode_buffer;
|
||||
size_t flDataSize=useFloat?outputSize:decode_buffer_length;
|
||||
size_t done=0;
|
||||
int err = mpg123_read(decoder, (unsigned char *)flData, flDataSize, &done);
|
||||
switch(err) {
|
||||
case MPG123_OK:
|
||||
{
|
||||
Decimate(flData, output, done / sizeof(float), outputWritten, (int)bitsPerSample, useFloat, (float)gain);
|
||||
mpg123_frameinfo frameInfo;
|
||||
if (mpg123_info(decoder, &frameInfo) == MPG123_OK) {
|
||||
*bitrate = frameInfo.bitrate;
|
||||
}
|
||||
}
|
||||
return adts::SUCCESS;
|
||||
case MPG123_NEW_FORMAT:
|
||||
assert(done == 0);
|
||||
return adts::SUCCESS;
|
||||
case MPG123_NEED_MORE:
|
||||
if (done) {
|
||||
Decimate(flData, output, done / sizeof(float), outputWritten, (int)bitsPerSample, useFloat, (float)gain);
|
||||
mpg123_frameinfo frameInfo;
|
||||
if (mpg123_info(decoder, &frameInfo) == MPG123_OK) {
|
||||
*bitrate = frameInfo.bitrate;
|
||||
}
|
||||
return adts::SUCCESS;
|
||||
} else if (_file->MPEGStream_EOF()) {
|
||||
return adts::ENDOFFILE;
|
||||
} else {
|
||||
if (retried) {
|
||||
return adts::NEEDMOREDATA;
|
||||
} else {
|
||||
retried=true;
|
||||
err = _Read(_file);
|
||||
if (err != adts::SUCCESS) {
|
||||
return err;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
assert(done == 0);
|
||||
return adts::FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ADTS_MPG123::GetLayer()
|
||||
{
|
||||
if (decoder) {
|
||||
mpg123_frameinfo frameInfo;
|
||||
mpg123_info(decoder, &frameInfo);
|
||||
return frameInfo.layer;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ADTS_MPG123::Release()
|
||||
{
|
||||
delete this;
|
||||
}
|
50
Src/mp3-mpg123/adts_mpg123.h
Normal file
50
Src/mp3-mpg123/adts_mpg123.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef NULLSOFT_IN_MP3_ADTS_MPG123_H
|
||||
#define NULLSOFT_IN_MP3_ADTS_MPG123_H
|
||||
|
||||
#include "../Plugins/Input/in_mp3/adts.h"
|
||||
#include "api__mp3-mpg123.h"
|
||||
#include <mpg123.h>
|
||||
|
||||
// {4192FE3F-E843-445c-8D62-51BE5EE5E68C}
|
||||
static const GUID adts_mpg123_guid =
|
||||
{ 0x4192fe3f, 0xe843, 0x445c, { 0x8d, 0x62, 0x51, 0xbe, 0x5e, 0xe5, 0xe6, 0x8c } };
|
||||
|
||||
class ADTS_MPG123 : public adts
|
||||
{
|
||||
public:
|
||||
static const char *getServiceName() { return "MPG123 stream Decoder"; }
|
||||
static GUID getServiceGuid() { return adts_mpg123_guid; }
|
||||
ADTS_MPG123();
|
||||
~ADTS_MPG123();
|
||||
int Initialize(bool forceMono, bool reverse_stereo, bool allowSurround, int maxBits, bool allowRG, bool _useFloat = false, bool _useCRC = false);
|
||||
bool Open(ifc_mpeg_stream_reader *file);
|
||||
void Close();
|
||||
void GetOutputParameters(size_t *numBits, int *numChannels, int *sampleRate);
|
||||
void CalculateFrameSize(int *frameSize);
|
||||
void Flush(ifc_mpeg_stream_reader *file);
|
||||
size_t GetCurrentBitrate();
|
||||
size_t GetDecoderDelay();
|
||||
int Sync(ifc_mpeg_stream_reader *file, unsigned __int8 *output, size_t outputSize, size_t *outputWritten, size_t *bitrate);
|
||||
int Decode(ifc_mpeg_stream_reader *file, unsigned __int8 *output, size_t outputSize, size_t *outputWritten, size_t *bitrate, size_t *endCut);
|
||||
int GetLayer();
|
||||
void Release();
|
||||
|
||||
private:
|
||||
mpg123_handle *decoder;
|
||||
size_t bitsPerSample;
|
||||
double gain;
|
||||
bool allowRG;
|
||||
bool useFloat;
|
||||
|
||||
int channels;
|
||||
int sampleRate;
|
||||
unsigned int decoderDelay;
|
||||
|
||||
int _Read(ifc_mpeg_stream_reader *file);
|
||||
bool _UpdateProperties();
|
||||
float *decode_buffer;
|
||||
size_t decode_buffer_length;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
14
Src/mp3-mpg123/api__mp3-mpg123.h
Normal file
14
Src/mp3-mpg123/api__mp3-mpg123.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <api/service/api_service.h>
|
||||
extern api_service *serviceManager;
|
||||
#define WASABI_API_SVC serviceManager
|
||||
|
||||
|
||||
#include "../Agave/Config/api_config.h"
|
||||
extern api_config *configApi;
|
||||
#define AGAVE_API_CONFIG configApi
|
||||
|
||||
#include <api/memmgr/api_memmgr.h>
|
||||
extern api_memmgr *memmgrApi;
|
||||
#define WASABI_API_MEMMGR memmgrApi
|
209
Src/mp3-mpg123/avi_mp3_decoder.cpp
Normal file
209
Src/mp3-mpg123/avi_mp3_decoder.cpp
Normal file
@ -0,0 +1,209 @@
|
||||
#include "avi_mp3_decoder.h"
|
||||
#include "../nsutil/pcm.h"
|
||||
#include <assert.h>
|
||||
|
||||
int AVIDecoder::CreateAudioDecoder(const nsavi::AVIH *avi_header,
|
||||
const nsavi::STRH *stream_header, const nsavi::STRF *stream_format, const nsavi::STRD *stream_data,
|
||||
unsigned int preferred_bits, unsigned int max_channels, bool floating_point,
|
||||
ifc_aviaudiodecoder **decoder)
|
||||
{
|
||||
nsavi::mp3_format *waveformat = (nsavi::mp3_format *)stream_format;
|
||||
|
||||
if (waveformat->format.format == nsavi::audio_format_mp3
|
||||
||waveformat->format.format == nsavi::audio_format_mp2)
|
||||
{
|
||||
mpg123_handle *ctx = mpg123_new(NULL, NULL);
|
||||
if (!ctx)
|
||||
return CREATEDECODER_FAILURE;
|
||||
|
||||
long flags = MPG123_QUIET|MPG123_FORCE_FLOAT|MPG123_SKIP_ID3V2|MPG123_IGNORE_STREAMLENGTH|MPG123_IGNORE_INFOFRAME;
|
||||
if (max_channels == 1) {
|
||||
flags |= MPG123_FORCE_MONO;
|
||||
}
|
||||
mpg123_param(ctx, MPG123_FLAGS, flags, 0);
|
||||
mpg123_param(ctx, MPG123_RVA, MPG123_RVA_OFF, 0);
|
||||
|
||||
*decoder = new AVIMP3Decoder(ctx, preferred_bits, max_channels, floating_point);
|
||||
return CREATEDECODER_SUCCESS;
|
||||
}
|
||||
|
||||
return CREATEDECODER_NOT_MINE;
|
||||
|
||||
}
|
||||
|
||||
#define CBCLASS AVIDecoder
|
||||
START_DISPATCH;
|
||||
CB(CREATE_AUDIO_DECODER, CreateAudioDecoder)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
||||
|
||||
#define FHG_DELAY 529
|
||||
AVIMP3Decoder::AVIMP3Decoder(mpg123_handle *mp3, unsigned int bps, unsigned max_channels, bool floating_point)
|
||||
: mp3(mp3), bits(bps?bps:16), max_channels(max_channels?max_channels:2), floating_point(floating_point), channels(0)
|
||||
{
|
||||
mpg123_open_feed(mp3);
|
||||
pregap = FHG_DELAY;
|
||||
channels = 0;
|
||||
decode_buffer=0;
|
||||
decode_buffer_length=0;
|
||||
}
|
||||
|
||||
AVIMP3Decoder::~AVIMP3Decoder()
|
||||
{
|
||||
if (mp3) {
|
||||
mpg123_delete(mp3);
|
||||
mp3 = 0;
|
||||
}
|
||||
free(decode_buffer);
|
||||
}
|
||||
|
||||
int AVIMP3Decoder::OutputFrameSize(size_t *frame_size)
|
||||
{
|
||||
long sample_rate = 44100;
|
||||
int channels = 2;
|
||||
int encoding = 0;
|
||||
if (mpg123_getformat(mp3, &sample_rate, &channels, &encoding) == MPG123_OK) {
|
||||
this->channels = channels;
|
||||
}
|
||||
|
||||
*frame_size = (bits/8) * channels * mpg123_spf(mp3);
|
||||
#if 0 // TODO?
|
||||
if (mp3->GetStreamInfo()->GetLayer() == 1)
|
||||
*frame_size *= 3;
|
||||
#endif
|
||||
return AVI_SUCCESS;
|
||||
}
|
||||
|
||||
int AVIMP3Decoder::GetOutputProperties(unsigned int *sampleRate, unsigned int *_channels, unsigned int *bitsPerSample, bool *isFloat)
|
||||
{
|
||||
long sample_rate = 44100;
|
||||
int channels = 2;
|
||||
int encoding = 0;
|
||||
if (mpg123_getformat(mp3, &sample_rate, &channels, &encoding) == MPG123_OK) {
|
||||
this->channels = channels;
|
||||
*sampleRate = sample_rate;
|
||||
*_channels = channels;
|
||||
*bitsPerSample = bits;
|
||||
*isFloat = floating_point;
|
||||
return AVI_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return AVI_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
int AVIMP3Decoder::DecodeChunk(uint16_t type, void **inputBuffer, size_t *inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes)
|
||||
{
|
||||
if (!mp3)
|
||||
return AVI_FAILURE;
|
||||
|
||||
if (inputBufferBytes) {
|
||||
const uint8_t *mp3_buffer = (const uint8_t *)*inputBuffer;
|
||||
int err = mpg123_feed(mp3, mp3_buffer, *inputBufferBytes);
|
||||
if (err == MPG123_OK) {
|
||||
mp3_buffer += *inputBufferBytes;
|
||||
*inputBuffer = (void *)mp3_buffer;
|
||||
*inputBufferBytes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t output_buffer_len = *outputBufferBytes;
|
||||
*outputBufferBytes = 0;
|
||||
for (;;) {
|
||||
if (!decode_buffer) {
|
||||
int channels = 2;
|
||||
long sample_rate;
|
||||
int encoding;
|
||||
if (mpg123_getformat(mp3, &sample_rate, &channels, &encoding) == MPG123_OK) {
|
||||
this->channels = channels;
|
||||
decode_buffer_length = sizeof(float) * channels * mpg123_spf(mp3);
|
||||
decode_buffer = (float *)malloc(decode_buffer_length);
|
||||
if (!decode_buffer) {
|
||||
return AVI_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get the decoded data out
|
||||
// TODO: if floating_point is true and pregap is 0, decode straight into outputBuffer
|
||||
size_t pcm_buf_used=0;
|
||||
int err = mpg123_read(mp3, (unsigned char *)decode_buffer, decode_buffer_length, &pcm_buf_used);
|
||||
|
||||
if (err == MPG123_NEED_MORE && pcm_buf_used == 0) {
|
||||
if (*outputBufferBytes == 0) {
|
||||
return AVI_NEED_MORE_INPUT;
|
||||
} else {
|
||||
return AVI_SUCCESS;
|
||||
}
|
||||
} else if (err == MPG123_NEW_FORMAT) {
|
||||
assert(pcm_buf_used == 0);
|
||||
continue;
|
||||
} else if (err == MPG123_OK || pcm_buf_used) {
|
||||
if (!channels) {
|
||||
long sample_rate = 44100;
|
||||
int channels = 2;
|
||||
int encoding = 0;
|
||||
if (mpg123_getformat(mp3, &sample_rate, &channels, &encoding) == MPG123_OK) {
|
||||
this->channels = channels;
|
||||
} else {
|
||||
return AVI_FAILURE;
|
||||
}
|
||||
}
|
||||
// deal with pregap
|
||||
size_t numSamples = pcm_buf_used / sizeof(float);
|
||||
size_t offset = min(numSamples, pregap * channels);
|
||||
numSamples -= offset;
|
||||
pregap -= (int)offset / channels;
|
||||
|
||||
float *pcm_buf = decode_buffer + offset;
|
||||
if (numSamples * bits / 8 > output_buffer_len) {
|
||||
return AVI_SUCCESS;
|
||||
}
|
||||
// convert to destination sample format
|
||||
if (floating_point)
|
||||
{
|
||||
memcpy(outputBuffer, pcm_buf, numSamples*bits/8);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsutil_pcm_FloatToInt_Interleaved_Gain(outputBuffer, pcm_buf, bits, numSamples, 1.0);
|
||||
}
|
||||
|
||||
*outputBufferBytes = *outputBufferBytes + numSamples * bits / 8;
|
||||
outputBuffer = (char *)outputBuffer + numSamples * bits / 8;
|
||||
output_buffer_len -= numSamples * bits / 8;
|
||||
//return AVI_SUCCESS;
|
||||
} else {
|
||||
assert(pcm_buf_used == 0);
|
||||
return AVI_FAILURE;
|
||||
}
|
||||
}
|
||||
return AVI_SUCCESS;
|
||||
}
|
||||
|
||||
void AVIMP3Decoder::Flush()
|
||||
{
|
||||
mpg123_open_feed(mp3);
|
||||
pregap = FHG_DELAY;
|
||||
}
|
||||
|
||||
void AVIMP3Decoder::Close()
|
||||
{
|
||||
if (mp3) {
|
||||
mpg123_delete(mp3);
|
||||
mp3 = 0;
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
#define CBCLASS AVIMP3Decoder
|
||||
START_DISPATCH;
|
||||
CB(OUTPUT_FRAME_SIZE, OutputFrameSize)
|
||||
CB(GET_OUTPUT_PROPERTIES, GetOutputProperties)
|
||||
CB(DECODE_CHUNK, DecodeChunk)
|
||||
VCB(FLUSH, Flush)
|
||||
VCB(CLOSE, Close)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
45
Src/mp3-mpg123/avi_mp3_decoder.h
Normal file
45
Src/mp3-mpg123/avi_mp3_decoder.h
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
#include "../Plugins/Input/in_avi/svc_avidecoder.h"
|
||||
#include "../Plugins/Input/in_avi/ifc_aviaudiodecoder.h"
|
||||
#include <mpg123.h>
|
||||
|
||||
// {11D89BF5-014E-463a-B284-385FF0662FCC}
|
||||
static const GUID avi_mp3_guid =
|
||||
{ 0x11d89bf5, 0x14e, 0x463a, { 0xb2, 0x84, 0x38, 0x5f, 0xf0, 0x66, 0x2f, 0xcc } };
|
||||
|
||||
class AVIDecoder : public svc_avidecoder
|
||||
{
|
||||
public:
|
||||
static const char *getServiceName() { return "MP3 AVI Decoder"; }
|
||||
static GUID getServiceGuid() { return avi_mp3_guid; }
|
||||
int CreateAudioDecoder(const nsavi::AVIH *avi_header, const nsavi::STRH *stream_header, const nsavi::STRF *stream_format, const nsavi::STRD *stream_data, unsigned int preferred_bits, unsigned int max_channels, bool floating_point, ifc_aviaudiodecoder **decoder);
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
class AVIMP3Decoder : public ifc_aviaudiodecoder
|
||||
{
|
||||
public:
|
||||
AVIMP3Decoder(mpg123_handle *mp3, unsigned int bps, unsigned max_channels, bool floating_point);
|
||||
~AVIMP3Decoder();
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
private:
|
||||
/* ifc_mkvaudiodecoder implementation */
|
||||
int OutputFrameSize(size_t *frame_size);
|
||||
int GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat);
|
||||
int DecodeChunk(uint16_t type, void **inputBuffer, size_t *inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes);
|
||||
void Flush();
|
||||
void Close();
|
||||
|
||||
private:
|
||||
mpg123_handle *mp3;
|
||||
unsigned int bits;
|
||||
int pregap;
|
||||
unsigned int max_channels;
|
||||
bool floating_point;
|
||||
unsigned int channels;
|
||||
float *decode_buffer;
|
||||
size_t decode_buffer_length;
|
||||
};
|
194
Src/mp3-mpg123/flv_mp3_decoder.cpp
Normal file
194
Src/mp3-mpg123/flv_mp3_decoder.cpp
Normal file
@ -0,0 +1,194 @@
|
||||
#include "flv_mp3_decoder.h"
|
||||
#include "../nsutil/pcm.h"
|
||||
|
||||
int FLVDecoderCreator::CreateAudioDecoder(int stereo, int bits, int sample_rate, int format_type, ifc_flvaudiodecoder **decoder)
|
||||
{
|
||||
if (format_type == FLV::AUDIO_FORMAT_MP3 || format_type == FLV::AUDIO_FORMAT_MP3_8KHZ)
|
||||
{
|
||||
mpg123_handle *ctx = mpg123_new(NULL, NULL);
|
||||
if (!ctx)
|
||||
return CREATEDECODER_FAILURE;
|
||||
|
||||
long flags = MPG123_QUIET|MPG123_FORCE_FLOAT|MPG123_SKIP_ID3V2|MPG123_IGNORE_STREAMLENGTH|MPG123_IGNORE_INFOFRAME;
|
||||
if (!stereo) {
|
||||
flags |= MPG123_FORCE_MONO;
|
||||
}
|
||||
mpg123_param(ctx, MPG123_FLAGS, flags, 0);
|
||||
mpg123_param(ctx, MPG123_RVA, MPG123_RVA_OFF, 0);
|
||||
|
||||
*decoder = new FLVMP3(ctx);
|
||||
return CREATEDECODER_SUCCESS;
|
||||
}
|
||||
return CREATEDECODER_NOT_MINE;
|
||||
}
|
||||
|
||||
int FLVDecoderCreator::HandlesAudio(int format_type)
|
||||
{
|
||||
if (format_type == FLV::AUDIO_FORMAT_MP3 || format_type == FLV::AUDIO_FORMAT_MP3_8KHZ)
|
||||
{
|
||||
return CREATEDECODER_SUCCESS;
|
||||
}
|
||||
return CREATEDECODER_NOT_MINE;
|
||||
}
|
||||
|
||||
#define CBCLASS FLVDecoderCreator
|
||||
START_DISPATCH;
|
||||
CB(CREATE_AUDIO_DECODER, CreateAudioDecoder)
|
||||
CB(HANDLES_AUDIO, HandlesAudio)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
||||
|
||||
/* --- */
|
||||
#define FHG_DELAY 529
|
||||
FLVMP3::FLVMP3(mpg123_handle *mp3) : mp3(mp3)
|
||||
{
|
||||
mpg123_open_feed(mp3);
|
||||
bits = 16;
|
||||
pregap = FHG_DELAY;
|
||||
max_channels = 2;
|
||||
channels = 0;
|
||||
decode_buffer = 0;
|
||||
decode_buffer_length = 0;
|
||||
}
|
||||
|
||||
FLVMP3::~FLVMP3()
|
||||
{
|
||||
if (mp3) {
|
||||
mpg123_delete(mp3);
|
||||
mp3 = 0;
|
||||
}
|
||||
free(decode_buffer);
|
||||
}
|
||||
|
||||
int FLVMP3::GetOutputFormat(unsigned int *sample_rate, unsigned int *_channels, unsigned int *_bits)
|
||||
{
|
||||
mpg123_frameinfo frameInfo;
|
||||
if (mpg123_info(mp3, &frameInfo) == MPG123_OK)
|
||||
{
|
||||
*sample_rate = frameInfo.rate;
|
||||
channels = (frameInfo.mode == MPG123_M_MONO)?1:2;
|
||||
*_channels = channels;
|
||||
*_bits = bits;
|
||||
return FLV_AUDIO_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FLV_AUDIO_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
int FLVMP3::DecodeSample(const void *input_buffer, size_t input_buffer_bytes, void *samples, size_t *samples_size_bytes, double *bitrate)
|
||||
{
|
||||
if (!mp3)
|
||||
return FLV_AUDIO_FAILURE;
|
||||
|
||||
mpg123_feed(mp3, (unsigned char *)input_buffer, input_buffer_bytes);
|
||||
|
||||
*samples_size_bytes = 0;
|
||||
*bitrate = 0;
|
||||
|
||||
for (;;) {
|
||||
if (!decode_buffer) {
|
||||
int channels = 2;
|
||||
long sample_rate;
|
||||
int encoding;
|
||||
if (mpg123_getformat(mp3, &sample_rate, &channels, &encoding) == MPG123_OK) {
|
||||
this->channels = channels;
|
||||
decode_buffer_length = sizeof(float) * channels * mpg123_spf(mp3);
|
||||
decode_buffer = (float *)malloc(decode_buffer_length);
|
||||
if (!decode_buffer) {
|
||||
return FLV_AUDIO_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get the decoded data out
|
||||
size_t pcm_buf_used=0;
|
||||
int err = mpg123_read(mp3, (unsigned char *)decode_buffer, decode_buffer_length, &pcm_buf_used);
|
||||
|
||||
if (pcm_buf_used) {
|
||||
if (!channels) {
|
||||
long sample_rate = 44100;
|
||||
int channels = 2;
|
||||
int encoding = 0;
|
||||
if (mpg123_getformat(mp3, &sample_rate, &channels, &encoding) == MPG123_OK) {
|
||||
this->channels = channels;
|
||||
} else {
|
||||
return FLV_AUDIO_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// deal with pregap
|
||||
size_t numSamples = pcm_buf_used / sizeof(float);
|
||||
size_t offset = min(numSamples, pregap * channels);
|
||||
numSamples -= offset;
|
||||
pregap -= (int)offset / channels;
|
||||
float *pcm_buf = decode_buffer + offset;
|
||||
|
||||
// convert to destination sample format
|
||||
|
||||
nsutil_pcm_FloatToInt_Interleaved(samples, pcm_buf, bits, numSamples);
|
||||
|
||||
*samples_size_bytes += numSamples * bits / 8;
|
||||
samples = (char *)samples + numSamples * bits / 8;
|
||||
|
||||
mpg123_frameinfo frameInfo;
|
||||
if (mpg123_info(mp3, &frameInfo) == MPG123_OK) {
|
||||
*bitrate = frameInfo.bitrate;
|
||||
}
|
||||
return FLV_AUDIO_SUCCESS;
|
||||
} else if (err == MPG123_NEED_MORE) {
|
||||
*samples_size_bytes = 0;
|
||||
return FLV_AUDIO_NEEDS_MORE_INPUT;
|
||||
} else if (err == MPG123_NEW_FORMAT) {
|
||||
continue;
|
||||
} else if (err == MPG123_OK) {
|
||||
continue;
|
||||
}
|
||||
else
|
||||
return FLV_AUDIO_FAILURE;
|
||||
}
|
||||
return FLV_AUDIO_SUCCESS;
|
||||
}
|
||||
|
||||
void FLVMP3::Flush()
|
||||
{
|
||||
mpg123_open_feed(mp3);
|
||||
pregap = FHG_DELAY;
|
||||
}
|
||||
|
||||
void FLVMP3::Close()
|
||||
{
|
||||
if (mp3) {
|
||||
mpg123_delete(mp3);
|
||||
mp3 = 0;
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
||||
void FLVMP3::SetPreferences(unsigned int _max_channels, unsigned int preferred_bits)
|
||||
{
|
||||
if (preferred_bits)
|
||||
bits = preferred_bits;
|
||||
|
||||
if (max_channels > _max_channels)
|
||||
max_channels = _max_channels;
|
||||
|
||||
long flags = MPG123_QUIET|MPG123_FORCE_FLOAT|MPG123_SKIP_ID3V2|MPG123_IGNORE_STREAMLENGTH|MPG123_IGNORE_INFOFRAME;
|
||||
if (max_channels == 1) {
|
||||
flags |= MPG123_FORCE_MONO;
|
||||
}
|
||||
mpg123_param(mp3, MPG123_FLAGS, flags, 0);
|
||||
mpg123_param(mp3, MPG123_RVA, MPG123_RVA_OFF, 0);
|
||||
|
||||
}
|
||||
|
||||
#define CBCLASS FLVMP3
|
||||
START_DISPATCH;
|
||||
CB(FLV_AUDIO_GETOUTPUTFORMAT, GetOutputFormat)
|
||||
CB(FLV_AUDIO_DECODE, DecodeSample)
|
||||
VCB(FLV_AUDIO_FLUSH, Flush)
|
||||
VCB(FLV_AUDIO_CLOSE, Close)
|
||||
VCB(FLV_AUDIO_SETPREFERENCES, SetPreferences)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
44
Src/mp3-mpg123/flv_mp3_decoder.h
Normal file
44
Src/mp3-mpg123/flv_mp3_decoder.h
Normal file
@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
#include "../Plugins/Input/in_flv/svc_flvdecoder.h"
|
||||
#include "../Plugins/Input/in_flv/FLVAudioHeader.h"
|
||||
#include "../Plugins/Input/in_flv/ifc_flvaudiodecoder.h"
|
||||
|
||||
#include <mpg123.h>
|
||||
|
||||
// {5CAED3F6-ED5F-4801-921E-9BF86A483016}
|
||||
static const GUID flv_mp3_guid =
|
||||
{ 0x5caed3f6, 0xed5f, 0x4801, { 0x92, 0x1e, 0x9b, 0xf8, 0x6a, 0x48, 0x30, 0x16 } };
|
||||
|
||||
|
||||
class FLVDecoderCreator : public svc_flvdecoder
|
||||
{
|
||||
public:
|
||||
static const char *getServiceName() { return "MP3 FLV Decoder"; }
|
||||
static GUID getServiceGuid() { return flv_mp3_guid; }
|
||||
int CreateAudioDecoder(int stereo, int bits, int sample_rate, int format, ifc_flvaudiodecoder **decoder);
|
||||
int HandlesAudio(int format_type);
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
class FLVMP3 : public ifc_flvaudiodecoder
|
||||
{
|
||||
public:
|
||||
FLVMP3(mpg123_handle *mp3);
|
||||
~FLVMP3();
|
||||
int GetOutputFormat(unsigned int *sample_rate, unsigned int *channels, unsigned int *bits);
|
||||
int DecodeSample(const void *input_buffer, size_t input_buffer_bytes, void *samples, size_t *samples_size_bytes, double *bitrate);
|
||||
void Flush();
|
||||
void Close();
|
||||
void SetPreferences(unsigned int max_channels, unsigned int preferred_bits);
|
||||
private:
|
||||
mpg123_handle *mp3;
|
||||
unsigned int bits;
|
||||
int pregap;
|
||||
unsigned int max_channels;
|
||||
unsigned int channels;
|
||||
float *decode_buffer;
|
||||
size_t decode_buffer_length;
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
89
Src/mp3-mpg123/main.cpp
Normal file
89
Src/mp3-mpg123/main.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
#include "api__mp3-mpg123.h"
|
||||
|
||||
#include "../nu/Singleton.h"
|
||||
#include "../nu/factoryt.h"
|
||||
#include "avi_mp3_decoder.h"
|
||||
#include "flv_mp3_decoder.h"
|
||||
#include "mkv_mp3_decoder.h"
|
||||
#include "mp3_in_mp4.h"
|
||||
#include "adts_mpg123.h"
|
||||
#include "MP4Factory.h"
|
||||
#include "NSVFactory.h"
|
||||
#include <bfc/platform/export.h>
|
||||
#include "../Agave/Component/ifc_wa5component.h"
|
||||
#include "../nu/ServiceBuilder.h"
|
||||
#include <mpg123.h>
|
||||
|
||||
api_service *WASABI_API_SVC = 0;
|
||||
api_config *AGAVE_API_CONFIG = 0;
|
||||
api_memmgr *WASABI_API_MEMMGR = 0;
|
||||
|
||||
class MP3DecoderComponent : public ifc_wa5component
|
||||
{
|
||||
public:
|
||||
void RegisterServices(api_service *service);
|
||||
int RegisterServicesSafeModeOk();
|
||||
void DeregisterServices(api_service *service);
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
static SingletonServiceFactory<svc_avidecoder, AVIDecoder> avi_factory;
|
||||
static AVIDecoder avi_decoder;
|
||||
static SingletonServiceFactory<svc_mkvdecoder, MKVDecoder> mkv_factory;
|
||||
static MKVDecoder mkv_decoder;
|
||||
static SingletonServiceFactory<svc_flvdecoder, FLVDecoderCreator> flv_factory;
|
||||
static FLVDecoderCreator flv_decoder;
|
||||
static MPEG4Factory mp4_factory;
|
||||
static ServiceFactoryT<adts, ADTS_MPG123> adts_factory;
|
||||
|
||||
static NSVFactory nsv_decoder;
|
||||
static SingletonServiceFactory<svc_nsvFactory, NSVFactory> nsv_factory;
|
||||
|
||||
void MP3DecoderComponent::RegisterServices(api_service *service)
|
||||
{
|
||||
WASABI_API_SVC = service;
|
||||
if (mpg123_init() == MPG123_OK) {
|
||||
WASABI_API_SVC->service_register(&mp4_factory);
|
||||
avi_factory.Register(WASABI_API_SVC, &avi_decoder);
|
||||
mkv_factory.Register(WASABI_API_SVC, &mkv_decoder);
|
||||
flv_factory.Register(WASABI_API_SVC, &flv_decoder);
|
||||
nsv_factory.Register(WASABI_API_SVC, &nsv_decoder);
|
||||
adts_factory.Register(WASABI_API_SVC);
|
||||
}
|
||||
ServiceBuild(WASABI_API_SVC, AGAVE_API_CONFIG, AgaveConfigGUID);
|
||||
ServiceBuild(WASABI_API_SVC, WASABI_API_MEMMGR, memMgrApiServiceGuid);
|
||||
}
|
||||
|
||||
void MP3DecoderComponent::DeregisterServices(api_service *service)
|
||||
{
|
||||
avi_factory.Deregister(WASABI_API_SVC);
|
||||
mkv_factory.Deregister(WASABI_API_SVC);
|
||||
WASABI_API_SVC->service_deregister(&mp4_factory);
|
||||
flv_factory.Deregister(WASABI_API_SVC);
|
||||
nsv_factory.Deregister(WASABI_API_SVC);
|
||||
adts_factory.Deregister(WASABI_API_SVC);
|
||||
ServiceRelease(WASABI_API_SVC, AGAVE_API_CONFIG, AgaveConfigGUID);
|
||||
ServiceRelease(WASABI_API_SVC, WASABI_API_MEMMGR, memMgrApiServiceGuid);
|
||||
mpg123_exit();
|
||||
}
|
||||
|
||||
int MP3DecoderComponent::RegisterServicesSafeModeOk()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
MP3DecoderComponent mp3_decoder_component;
|
||||
extern "C" DLLEXPORT ifc_wa5component *GetWinamp5SystemComponent()
|
||||
{
|
||||
return &mp3_decoder_component;
|
||||
}
|
||||
|
||||
#define CBCLASS MP3DecoderComponent
|
||||
START_DISPATCH;
|
||||
VCB(API_WA5COMPONENT_REGISTERSERVICES, RegisterServices)
|
||||
CB(15, RegisterServicesSafeModeOk)
|
||||
VCB(API_WA5COMPONENT_DEREEGISTERSERVICES, DeregisterServices)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
169
Src/mp3-mpg123/mkv_mp3_decoder.cpp
Normal file
169
Src/mp3-mpg123/mkv_mp3_decoder.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
#include "mkv_mp3_decoder.h"
|
||||
#include "../nsutil/pcm.h"
|
||||
|
||||
int MKVDecoder::CreateAudioDecoder(const char *codec_id, const nsmkv::TrackEntryData *track_entry_data, const nsmkv::AudioData *audio_data, unsigned int preferred_bits, unsigned int max_channels,bool floating_point, ifc_mkvaudiodecoder **decoder)
|
||||
{
|
||||
if (!strcmp(codec_id, "A_MPEG/L3")
|
||||
|| !strcmp(codec_id, "A_MPEG/L2")
|
||||
|| !strcmp(codec_id, "A_MPEG/L1"))
|
||||
{
|
||||
mpg123_handle *ctx = mpg123_new(NULL, NULL);
|
||||
if (!ctx)
|
||||
return CREATEDECODER_FAILURE;
|
||||
|
||||
long flags = MPG123_QUIET|MPG123_FORCE_FLOAT|MPG123_SKIP_ID3V2|MPG123_IGNORE_STREAMLENGTH|MPG123_IGNORE_INFOFRAME;
|
||||
if (max_channels == 1) {
|
||||
flags |= MPG123_FORCE_MONO;
|
||||
}
|
||||
mpg123_param(ctx, MPG123_FLAGS, flags, 0);
|
||||
mpg123_param(ctx, MPG123_RVA, MPG123_RVA_OFF, 0);
|
||||
|
||||
*decoder = new MKVMP3Decoder(ctx, preferred_bits, max_channels, floating_point);
|
||||
return CREATEDECODER_SUCCESS;
|
||||
}
|
||||
|
||||
return CREATEDECODER_NOT_MINE;
|
||||
}
|
||||
|
||||
#define CBCLASS MKVDecoder
|
||||
START_DISPATCH;
|
||||
CB(CREATE_AUDIO_DECODER, CreateAudioDecoder)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
||||
|
||||
#define FHG_DELAY 529
|
||||
MKVMP3Decoder::MKVMP3Decoder(mpg123_handle *mp3, unsigned int bps, unsigned max_channels, bool floating_point)
|
||||
: mp3(mp3), bits(bps?bps:16), max_channels(max_channels?max_channels:2), floating_point(floating_point)
|
||||
{
|
||||
decode_buffer=0;
|
||||
decode_buffer_length=0;
|
||||
sample_rate = 0;
|
||||
channels = 0;
|
||||
pregap = FHG_DELAY;
|
||||
mpg123_open_feed(mp3);
|
||||
}
|
||||
|
||||
MKVMP3Decoder::~MKVMP3Decoder()
|
||||
{
|
||||
if (mp3) {
|
||||
mpg123_delete(mp3);
|
||||
mp3 = 0;
|
||||
}
|
||||
free(decode_buffer);
|
||||
}
|
||||
|
||||
bool MKVMP3Decoder::_UpdateProperties()
|
||||
{
|
||||
if (mp3 && (!channels || !sample_rate)) {
|
||||
long sample_rate = 44100;
|
||||
int channels = 2;
|
||||
int encoding = 0;
|
||||
if (mpg123_getformat(mp3, &sample_rate, &channels, &encoding) == MPG123_OK) {
|
||||
this->channels = channels;
|
||||
this->sample_rate = sample_rate;
|
||||
}
|
||||
}
|
||||
|
||||
return channels && sample_rate;
|
||||
}
|
||||
|
||||
int MKVMP3Decoder::OutputFrameSize(size_t *frame_size)
|
||||
{
|
||||
if (_UpdateProperties()) {
|
||||
*frame_size = (bits/8) * channels * mpg123_spf(mp3);
|
||||
return MKV_SUCCESS;
|
||||
} else {
|
||||
return MKV_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
int MKVMP3Decoder::GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat)
|
||||
{
|
||||
if (_UpdateProperties()) {
|
||||
*sampleRate = this->sample_rate;
|
||||
*channels = this->channels;
|
||||
*bitsPerSample = bits;
|
||||
*isFloat = floating_point;
|
||||
return MKV_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MKV_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
int MKVMP3Decoder::DecodeBlock(void *inputBuffer, size_t inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes)
|
||||
{
|
||||
if (!mp3)
|
||||
return MKV_FAILURE;
|
||||
|
||||
*outputBufferBytes = 0;
|
||||
mpg123_feed(mp3, (unsigned char *)inputBuffer, inputBufferBytes);
|
||||
|
||||
for (;;) {
|
||||
if (!decode_buffer) {
|
||||
if (_UpdateProperties()) {
|
||||
decode_buffer_length = sizeof(float) * channels * mpg123_spf(mp3);
|
||||
decode_buffer = (float *)malloc(decode_buffer_length);
|
||||
if (!decode_buffer) {
|
||||
return MKV_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
// get the decoded data out
|
||||
size_t pcm_buf_used=0;
|
||||
int err = mpg123_read(mp3, (unsigned char *)decode_buffer, decode_buffer_length, &pcm_buf_used);
|
||||
|
||||
if (pcm_buf_used) {
|
||||
if (!_UpdateProperties()) {
|
||||
return MKV_FAILURE;
|
||||
}
|
||||
// deal with pregap
|
||||
size_t numSamples = pcm_buf_used / sizeof(float);
|
||||
size_t offset = min(numSamples, pregap * channels);
|
||||
numSamples -= offset;
|
||||
pregap -= (int)offset / channels;
|
||||
float *pcm_buf = decode_buffer + offset;
|
||||
|
||||
// convert to destination sample format
|
||||
|
||||
nsutil_pcm_FloatToInt_Interleaved(outputBuffer, pcm_buf, bits, numSamples);
|
||||
|
||||
*outputBufferBytes += numSamples * bits / 8;
|
||||
outputBuffer = (char *)outputBuffer + numSamples * bits / 8;
|
||||
|
||||
return MKV_SUCCESS;
|
||||
} else if (err == MPG123_NEED_MORE) {
|
||||
*outputBufferBytes = 0;
|
||||
return MKV_NEED_MORE_INPUT;
|
||||
} else if (err == MPG123_NEW_FORMAT) {
|
||||
continue;
|
||||
} else if (err == MPG123_OK) {
|
||||
continue;
|
||||
}
|
||||
else
|
||||
return MKV_FAILURE;
|
||||
}
|
||||
return MKV_SUCCESS;
|
||||
}
|
||||
|
||||
void MKVMP3Decoder::Flush()
|
||||
{
|
||||
mpg123_open_feed(mp3);
|
||||
pregap = FHG_DELAY;
|
||||
}
|
||||
|
||||
void MKVMP3Decoder::Close()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
#define CBCLASS MKVMP3Decoder
|
||||
START_DISPATCH;
|
||||
CB(OUTPUT_FRAME_SIZE, OutputFrameSize)
|
||||
CB(GET_OUTPUT_PROPERTIES, GetOutputProperties)
|
||||
CB(DECODE_BLOCK, DecodeBlock)
|
||||
VCB(FLUSH, Flush)
|
||||
VCB(CLOSE, Close)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
49
Src/mp3-mpg123/mkv_mp3_decoder.h
Normal file
49
Src/mp3-mpg123/mkv_mp3_decoder.h
Normal file
@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
#include "../Plugins/Input/in_mkv/svc_mkvdecoder.h"
|
||||
#include "../Plugins/Input/in_mkv/ifc_mkvaudiodecoder.h"
|
||||
#include <mpg123.h>
|
||||
|
||||
// {A08A5A0C-DEF7-4604-9F35-D5A5E9B1F4DF}
|
||||
static const GUID mkv_mp3_guid =
|
||||
{ 0xa08a5a0c, 0xdef7, 0x4604, { 0x9f, 0x35, 0xd5, 0xa5, 0xe9, 0xb1, 0xf4, 0xdf } };
|
||||
|
||||
|
||||
class MKVDecoder : public svc_mkvdecoder
|
||||
{
|
||||
public:
|
||||
static const char *getServiceName() { return "MP3 MKV Decoder"; }
|
||||
static GUID getServiceGuid() { return mkv_mp3_guid; }
|
||||
int CreateAudioDecoder(const char *codec_id, const nsmkv::TrackEntryData *track_entry_data, const nsmkv::AudioData *audio_data, unsigned int preferred_bits, unsigned int preferred_channels, bool floating_point, ifc_mkvaudiodecoder **decoder);
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
class MKVMP3Decoder : public ifc_mkvaudiodecoder
|
||||
{
|
||||
public:
|
||||
MKVMP3Decoder(mpg123_handle *mp3, unsigned int bps, unsigned max_channels, bool floating_point);
|
||||
~MKVMP3Decoder();
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
private:
|
||||
/* ifc_mkvaudiodecoder implementation */
|
||||
int OutputFrameSize(size_t *frame_size);
|
||||
int GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat);
|
||||
int DecodeBlock(void *inputBuffer, size_t inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes);
|
||||
void Flush();
|
||||
void Close();
|
||||
|
||||
private:
|
||||
mpg123_handle *mp3;
|
||||
unsigned int bits;
|
||||
int pregap;
|
||||
unsigned int max_channels;
|
||||
unsigned int channels;
|
||||
unsigned int sample_rate;
|
||||
bool floating_point;
|
||||
|
||||
bool _UpdateProperties();
|
||||
float *decode_buffer;
|
||||
size_t decode_buffer_length;
|
||||
};
|
76
Src/mp3-mpg123/mp3-mpg123.rc
Normal file
76
Src/mp3-mpg123/mp3-mpg123.rc
Normal file
@ -0,0 +1,76 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.K.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""version.rc2""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // English (U.K.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
#include "version.rc2"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
44
Src/mp3-mpg123/mp3-mpg123.sln
Normal file
44
Src/mp3-mpg123/mp3-mpg123.sln
Normal file
@ -0,0 +1,44 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29609.76
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp3-mpg123", "mp3-mpg123.vcxproj", "{5057C6D0-F787-43EB-BA3F-8D59AB3B09D1}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F} = {DABE6307-F8DD-416D-9DAC-673E2DECB73F}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nsutil", "..\nsutil\nsutil.vcxproj", "{DABE6307-F8DD-416D-9DAC-673E2DECB73F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{5057C6D0-F787-43EB-BA3F-8D59AB3B09D1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{5057C6D0-F787-43EB-BA3F-8D59AB3B09D1}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{5057C6D0-F787-43EB-BA3F-8D59AB3B09D1}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{5057C6D0-F787-43EB-BA3F-8D59AB3B09D1}.Debug|x64.Build.0 = Debug|Win32
|
||||
{5057C6D0-F787-43EB-BA3F-8D59AB3B09D1}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{5057C6D0-F787-43EB-BA3F-8D59AB3B09D1}.Release|Win32.Build.0 = Release|Win32
|
||||
{5057C6D0-F787-43EB-BA3F-8D59AB3B09D1}.Release|x64.ActiveCfg = Release|x64
|
||||
{5057C6D0-F787-43EB-BA3F-8D59AB3B09D1}.Release|x64.Build.0 = Release|x64
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|x64.Build.0 = Debug|x64
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|Win32.Build.0 = Release|Win32
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|x64.ActiveCfg = Release|x64
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {FC646532-2050-40A5-A2AB-F699F1C071C4}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
285
Src/mp3-mpg123/mp3-mpg123.vcxproj
Normal file
285
Src/mp3-mpg123/mp3-mpg123.vcxproj
Normal file
@ -0,0 +1,285 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.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="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{5057C6D0-F787-43EB-BA3F-8D59AB3B09D1}</ProjectGuid>
|
||||
<RootNamespace>mp3</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</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>
|
||||
<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|x64'" 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)'=='Release|x64'" 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 Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
<TargetName>mp3</TargetName>
|
||||
<TargetExt>.w5s</TargetExt>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
<TargetName>mp3</TargetName>
|
||||
<TargetExt>.w5s</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
<TargetName>mp3</TargetName>
|
||||
<TargetExt>.w5s</TargetExt>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
<TargetName>mp3</TargetName>
|
||||
<TargetExt>.w5s</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg">
|
||||
<VcpkgEnableManifest>false</VcpkgEnableManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<VcpkgUseStatic>false</VcpkgUseStatic>
|
||||
<VcpkgInstalledDir>
|
||||
</VcpkgInstalledDir>
|
||||
<VcpkgConfiguration>Debug</VcpkgConfiguration>
|
||||
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<VcpkgUseStatic>false</VcpkgUseStatic>
|
||||
<VcpkgInstalledDir>
|
||||
</VcpkgInstalledDir>
|
||||
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<VcpkgUseStatic>false</VcpkgUseStatic>
|
||||
<VcpkgInstalledDir>
|
||||
</VcpkgInstalledDir>
|
||||
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
|
||||
<VcpkgConfiguration>Debug</VcpkgConfiguration>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<VcpkgUseStatic>false</VcpkgUseStatic>
|
||||
<VcpkgInstalledDir>
|
||||
</VcpkgInstalledDir>
|
||||
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;UNICODE_INPUT_PLUGIN;DO_LAYER12;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\
|
||||
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\
|
||||
</Command>
|
||||
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_USRDLL;UNICODE_INPUT_PLUGIN;DO_LAYER12;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\
|
||||
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\
|
||||
</Command>
|
||||
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;_USRDLL;UNICODE_INPUT_PLUGIN;DO_LAYER12;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<ImportLibrary>$(ProjectDir)x86_Release\$(ProjectName).lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\
|
||||
</Command>
|
||||
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>NDEBUG;WIN64;_WINDOWS;_USRDLL;UNICODE_INPUT_PLUGIN;DO_LAYER12;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<ImportLibrary>$(ProjectDir)x64_Release\$(ProjectName).lib</ImportLibrary>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\
|
||||
</Command>
|
||||
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="adts_mpg123.cpp" />
|
||||
<ClCompile Include="avi_mp3_decoder.cpp" />
|
||||
<ClCompile Include="flv_mp3_decoder.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="mkv_mp3_decoder.cpp" />
|
||||
<ClCompile Include="mp3_in_mp4.cpp" />
|
||||
<ClCompile Include="MP4Factory.cpp" />
|
||||
<ClCompile Include="NSVFactory.cpp" />
|
||||
<ClCompile Include="nsvmain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="adts_mpg123.h" />
|
||||
<ClInclude Include="api__mp3-mpg123.h" />
|
||||
<ClInclude Include="avi_mp3_decoder.h" />
|
||||
<ClInclude Include="flv_mp3_decoder.h" />
|
||||
<ClInclude Include="mkv_mp3_decoder.h" />
|
||||
<ClInclude Include="mp3_in_mp4.h" />
|
||||
<ClInclude Include="MP4Factory.h" />
|
||||
<ClInclude Include="NSVFactory.h" />
|
||||
<ClInclude Include="nsvmain.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="mp3-mpg123.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\nsutil\nsutil.vcxproj">
|
||||
<Project>{dabe6307-f8dd-416d-9dac-673e2decb73f}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Wasabi\Wasabi.vcxproj">
|
||||
<Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
80
Src/mp3-mpg123/mp3-mpg123.vcxproj.filters
Normal file
80
Src/mp3-mpg123/mp3-mpg123.vcxproj.filters
Normal file
@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="adts_mpg123.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="avi_mp3_decoder.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="flv_mp3_decoder.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mkv_mp3_decoder.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mp3_in_mp4.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MP4Factory.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NSVFactory.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="nsvmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="adts_mpg123.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="api__mp3-mpg123.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="avi_mp3_decoder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="flv_mp3_decoder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mkv_mp3_decoder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mp3_in_mp4.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MP4Factory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NSVFactory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="nsvmain.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{79507766-5017-442a-906a-8d825464d222}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Ressource Files">
|
||||
<UniqueIdentifier>{4c991c0c-1c76-493f-99dc-ec1203032027}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{520e8828-1621-41d6-98df-ec2d1beec790}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="mp3-mpg123.rc">
|
||||
<Filter>Ressource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
228
Src/mp3-mpg123/mp3_in_mp4.cpp
Normal file
228
Src/mp3-mpg123/mp3_in_mp4.cpp
Normal file
@ -0,0 +1,228 @@
|
||||
// used to decode an MPEG-1 audio object in an MPEG-4 ISO Media file
|
||||
#include "mp3_in_mp4.h"
|
||||
#include "api__mp3-mpg123.h"
|
||||
#include "../nsutil/pcm.h"
|
||||
|
||||
// {B6CB4A7C-A8D0-4c55-8E60-9F7A7A23DA0F}
|
||||
static const GUID playbackConfigGroupGUID =
|
||||
{ 0xb6cb4a7c, 0xa8d0, 0x4c55, { 0x8e, 0x60, 0x9f, 0x7a, 0x7a, 0x23, 0xda, 0xf } };
|
||||
|
||||
#define FHG_DELAY 529
|
||||
MPEG4_MP3::MPEG4_MP3()
|
||||
{
|
||||
channels = 0;
|
||||
gain = 1;
|
||||
floatingPoint = false;
|
||||
decoder = 0;
|
||||
sample_rate = 0;
|
||||
bits = 16;
|
||||
pregap = FHG_DELAY;
|
||||
}
|
||||
|
||||
MPEG4_MP3::~MPEG4_MP3()
|
||||
{
|
||||
if (decoder) {
|
||||
mpg123_delete(decoder);
|
||||
decoder = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int MPEG4_MP3::OpenEx(size_t _bits, size_t _maxChannels, bool useFloat)
|
||||
{
|
||||
_bits = bits;
|
||||
floatingPoint = useFloat;
|
||||
if (floatingPoint)
|
||||
bits = 32;
|
||||
else
|
||||
bits = (int)_bits;
|
||||
|
||||
decoder = mpg123_new(NULL, NULL);
|
||||
long flags = MPG123_QUIET|MPG123_FORCE_FLOAT|MPG123_SKIP_ID3V2|MPG123_IGNORE_STREAMLENGTH|MPG123_IGNORE_INFOFRAME;
|
||||
if (_maxChannels == 1) {
|
||||
flags |= MPG123_FORCE_MONO;
|
||||
}
|
||||
mpg123_param(decoder, MPG123_FLAGS, flags, 0);
|
||||
mpg123_param(decoder, MPG123_RVA, MPG123_RVA_OFF, 0);
|
||||
mpg123_open_feed(decoder);
|
||||
return MP4_SUCCESS;
|
||||
}
|
||||
|
||||
const char *MPEG4_MP3::GetCodecInfoString()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MPEG4_MP3::CanHandleCodec(const char *codecName)
|
||||
{
|
||||
if (!lstrcmpA(codecName, "mp4a"))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MPEG4_MP3::CanHandleType(unsigned __int8 type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case MP4_MPEG4_LAYER3_AUDIO:
|
||||
case MP4_MPEG4_LAYER2_AUDIO:
|
||||
case MP4_MPEG4_LAYER1_AUDIO:
|
||||
case MP4_TYPE_MPEG1_AUDIO:
|
||||
case MP4_TYPE_MPEG2_AUDIO:
|
||||
//case MP4_TYPE_MPEG4_AUDIO:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int MPEG4_MP3::DecodeSample(void *inputBuffer, size_t inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes)
|
||||
{
|
||||
if (!decoder)
|
||||
return MP4_FAILURE;
|
||||
|
||||
*outputBufferBytes = 0;
|
||||
mpg123_feed(decoder, (unsigned char *)inputBuffer, inputBufferBytes);
|
||||
|
||||
for (;;) {
|
||||
// get the decoded data out
|
||||
size_t pcm_buf_used=0;
|
||||
float decodeBuf[1152*2];
|
||||
int err = mpg123_read(decoder, (unsigned char *)decodeBuf, sizeof(decodeBuf), &pcm_buf_used);
|
||||
|
||||
if (pcm_buf_used) {
|
||||
if (!_UpdateProperties()) {
|
||||
return MP4_FAILURE;
|
||||
}
|
||||
// deal with pregap
|
||||
int numSamples = (int)pcm_buf_used / sizeof(float);
|
||||
int offset = min(numSamples, pregap * channels);
|
||||
numSamples -= offset;
|
||||
pregap -= offset / channels;
|
||||
float *pcm_buf = decodeBuf + offset;
|
||||
|
||||
// convert to destination sample format
|
||||
|
||||
nsutil_pcm_FloatToInt_Interleaved(outputBuffer, pcm_buf, bits, numSamples);
|
||||
|
||||
*outputBufferBytes += numSamples * bits / 8;
|
||||
outputBuffer = (char *)outputBuffer + numSamples * bits / 8;
|
||||
|
||||
return MP4_SUCCESS;
|
||||
} else if (err == MPG123_NEED_MORE) {
|
||||
*outputBufferBytes = 0;
|
||||
return MP4_NEED_MORE_INPUT;
|
||||
} else if (err == MPG123_NEW_FORMAT) {
|
||||
continue;
|
||||
} else if (err == MPG123_OK) {
|
||||
continue;
|
||||
}
|
||||
else
|
||||
return MP4_FAILURE;
|
||||
}
|
||||
return MP4_SUCCESS;
|
||||
}
|
||||
|
||||
bool MPEG4_MP3::_UpdateProperties()
|
||||
{
|
||||
if (decoder && (!channels || !sample_rate)) {
|
||||
long sample_rate = 44100;
|
||||
int channels = 2;
|
||||
int encoding = 0;
|
||||
if (mpg123_getformat(decoder, &sample_rate, &channels, &encoding) == MPG123_OK) {
|
||||
this->channels = channels;
|
||||
this->sample_rate = sample_rate;
|
||||
}
|
||||
}
|
||||
|
||||
return channels && sample_rate;
|
||||
}
|
||||
int MPEG4_MP3::GetOutputPropertiesEx(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat)
|
||||
{
|
||||
if (_UpdateProperties()) {
|
||||
*sampleRate = this->sample_rate;
|
||||
*channels = this->channels;
|
||||
*bitsPerSample = bits;
|
||||
*isFloat = floatingPoint;
|
||||
return MP4_SUCCESS;
|
||||
} else {
|
||||
return MP4_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
int MPEG4_MP3::GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample)
|
||||
{
|
||||
bool dummy;
|
||||
return GetOutputPropertiesEx(sampleRate, channels, bitsPerSample, &dummy);
|
||||
}
|
||||
|
||||
void MPEG4_MP3::Close()
|
||||
{
|
||||
if (decoder) {
|
||||
mpg123_delete(decoder);
|
||||
decoder = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void MPEG4_MP3::Flush()
|
||||
{
|
||||
mpg123_open_feed(decoder);
|
||||
pregap = FHG_DELAY;
|
||||
}
|
||||
|
||||
int MPEG4_MP3::SetGain(float _gain)
|
||||
{
|
||||
gain = _gain;
|
||||
return MP4_SUCCESS;
|
||||
}
|
||||
|
||||
int MPEG4_MP3::GetCurrentBitrate(unsigned int *bitrate)
|
||||
{
|
||||
mpg123_frameinfo frameInfo;
|
||||
if (mpg123_info(decoder, &frameInfo) == MPG123_OK) {
|
||||
*bitrate = frameInfo.bitrate;
|
||||
return MP4_SUCCESS;
|
||||
} else {
|
||||
return MP4_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
int MPEG4_MP3::OutputFrameSize(size_t *frameSize)
|
||||
{
|
||||
if (_UpdateProperties()) {
|
||||
*frameSize = (bits/8) * channels * mpg123_spf(decoder);
|
||||
return MP4_SUCCESS;
|
||||
} else {
|
||||
return MP4_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
int MPEG4_MP3::CanHandleMPEG4Type(unsigned __int8 type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case MP4_MPEG4_LAYER1_AUDIO:
|
||||
case MP4_MPEG4_LAYER2_AUDIO:
|
||||
case MP4_MPEG4_LAYER3_AUDIO:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define CBCLASS MPEG4_MP3
|
||||
START_DISPATCH;
|
||||
CB(MPEG4_AUDIO_OPEN_EX, OpenEx)
|
||||
CB(MPEG4_AUDIO_CODEC_INFO_STRING, GetCodecInfoString)
|
||||
CB(MPEG4_AUDIO_BITRATE, GetCurrentBitrate)
|
||||
CB(MPEG4_AUDIO_FRAMESIZE, OutputFrameSize)
|
||||
CB(MPEG4_AUDIO_OUTPUTINFO, GetOutputProperties)
|
||||
CB(MPEG4_AUDIO_OUTPUTINFO_EX, GetOutputPropertiesEx)
|
||||
CB(MPEG4_AUDIO_DECODE, DecodeSample)
|
||||
VCB(MPEG4_AUDIO_FLUSH, Flush)
|
||||
VCB(MPEG4_AUDIO_CLOSE, Close)
|
||||
CB(MPEG4_AUDIO_HANDLES_CODEC, CanHandleCodec)
|
||||
CB(MPEG4_AUDIO_HANDLES_TYPE, CanHandleType)
|
||||
CB(MPEG4_AUDIO_HANDLES_MPEG4_TYPE, CanHandleMPEG4Type)
|
||||
CB(MPEG4_AUDIO_SET_GAIN, SetGain)
|
||||
END_DISPATCH;
|
43
Src/mp3-mpg123/mp3_in_mp4.h
Normal file
43
Src/mp3-mpg123/mp3_in_mp4.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef NULLSOFT_MP3_MPEG4_H
|
||||
#define NULLSOFT_MP3_MPEG4_H
|
||||
|
||||
// used to decode an MPEG-1 audio object in an MPEG-4 ISO Media file
|
||||
|
||||
#include "../Plugins/Input/in_mp4/mpeg4audio.h"
|
||||
#include <mpg123.h>
|
||||
|
||||
class MPEG4_MP3 : public MP4AudioDecoder
|
||||
{
|
||||
public:
|
||||
MPEG4_MP3();
|
||||
~MPEG4_MP3();
|
||||
int Open();
|
||||
int OpenEx(size_t bits, size_t maxChannels, bool useFloat);
|
||||
//int AudioSpecificConfiguration(void *buffer, size_t buffer_size); // reads ASC block from mp4 file
|
||||
int GetCurrentBitrate(unsigned int *bitrate);
|
||||
int OutputFrameSize(size_t *frameSize);
|
||||
int GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample);
|
||||
int GetOutputPropertiesEx(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat);
|
||||
int DecodeSample(void *inputBuffer, size_t inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes);
|
||||
void Flush();
|
||||
void Close();
|
||||
const char *GetCodecInfoString();
|
||||
int CanHandleCodec(const char *codecName);
|
||||
int CanHandleType(unsigned __int8 type);
|
||||
int CanHandleMPEG4Type(unsigned __int8 type);
|
||||
int SetGain(float gain);
|
||||
|
||||
private:
|
||||
bool _UpdateProperties();
|
||||
mpg123_handle *decoder;
|
||||
|
||||
int bits;
|
||||
int channels;
|
||||
bool floatingPoint;
|
||||
int sample_rate;
|
||||
RECVS_DISPATCH;
|
||||
float gain;
|
||||
int pregap;
|
||||
};
|
||||
|
||||
#endif
|
93
Src/mp3-mpg123/nsvmain.cpp
Normal file
93
Src/mp3-mpg123/nsvmain.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
#include "../nsv/nsvlib.h"
|
||||
#include "../nsv/dec_if.h"
|
||||
#include "nsvmain.h"
|
||||
#include "../nsutil/pcm.h"
|
||||
|
||||
MP3_Decoder::MP3_Decoder()
|
||||
{
|
||||
decoder = mpg123_new(NULL, NULL);
|
||||
long flags = MPG123_QUIET|MPG123_FORCE_FLOAT|MPG123_SKIP_ID3V2|MPG123_IGNORE_STREAMLENGTH|MPG123_IGNORE_INFOFRAME;
|
||||
mpg123_param(decoder, MPG123_FLAGS, flags, 0);
|
||||
mpg123_param(decoder, MPG123_RVA, MPG123_RVA_OFF, 0);
|
||||
memset(pcm_buf, 0, sizeof(pcm_buf));
|
||||
mpg123_open_feed(decoder);
|
||||
fused = 0; pcm_buf_used = 0; pcm_offs = 0;
|
||||
}
|
||||
|
||||
int MP3_Decoder::decode(void *in, int in_len,
|
||||
void *out, int *out_len,
|
||||
unsigned int out_fmt[8])
|
||||
{
|
||||
int rval = 1;
|
||||
if (fused < in_len)
|
||||
{
|
||||
int l = 4096;
|
||||
if (l > in_len - fused) l = in_len - fused;
|
||||
if (l) mpg123_feed(decoder, (unsigned char *)in + fused, l);
|
||||
fused += l;
|
||||
}
|
||||
|
||||
if (!pcm_buf_used)
|
||||
{
|
||||
mpg123_read(decoder, (unsigned char *)pcm_buf, sizeof(pcm_buf), &pcm_buf_used);
|
||||
|
||||
pcm_offs = 0;
|
||||
}
|
||||
|
||||
if (pcm_buf_used)
|
||||
{
|
||||
size_t numSamples = *out_len / 2;
|
||||
if (numSamples > (pcm_buf_used/sizeof(float)))
|
||||
numSamples = pcm_buf_used/sizeof(float);
|
||||
nsutil_pcm_FloatToInt_Interleaved(out, pcm_buf+pcm_offs, 16, numSamples);
|
||||
pcm_buf_used -= numSamples*sizeof(float);
|
||||
pcm_offs += (int)numSamples;
|
||||
*out_len = 2*(int)numSamples;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fused >= in_len) { fused = 0; rval = 0; }
|
||||
*out_len = 0;
|
||||
}
|
||||
mpg123_frameinfo frameInfo;
|
||||
if (mpg123_info(decoder, &frameInfo) == MPG123_OK) {
|
||||
int nch = (frameInfo.mode == MPG123_M_MONO)?1:2;
|
||||
int srate = frameInfo.rate;
|
||||
out_fmt[0] = (nch && srate) ? NSV_MAKETYPE('P', 'C', 'M', ' ') : 0;
|
||||
out_fmt[1] = srate;
|
||||
out_fmt[2] = nch;
|
||||
out_fmt[3] = (nch && srate) ? 16 : 0;
|
||||
out_fmt[4] = frameInfo.bitrate;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
void MP3_Decoder::flush()
|
||||
{
|
||||
fused = 0;
|
||||
pcm_buf_used = 0;
|
||||
pcm_offs = 0;
|
||||
mpg123_open_feed(decoder);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
__declspec(dllexport) IAudioDecoder *CreateAudioDecoder(unsigned int fmt, IAudioOutput **output)
|
||||
{
|
||||
switch (fmt)
|
||||
{
|
||||
case NSV_MAKETYPE('M', 'P', '3', ' '):
|
||||
return new MP3_Decoder;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(dllexport) void DeleteAudioDecoder(IAudioDecoder *decoder)
|
||||
{
|
||||
if (decoder)
|
||||
delete decoder;
|
||||
|
||||
}
|
||||
}
|
20
Src/mp3-mpg123/nsvmain.h
Normal file
20
Src/mp3-mpg123/nsvmain.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include <mpg123.h>
|
||||
#include "../nsv/dec_if.h"
|
||||
|
||||
class MP3_Decoder : public IAudioDecoder
|
||||
{
|
||||
public:
|
||||
MP3_Decoder();
|
||||
~MP3_Decoder() { };
|
||||
int decode(void *in, int in_len,
|
||||
void *out, int *out_len,
|
||||
unsigned int out_fmt[8]);
|
||||
void flush();
|
||||
private:
|
||||
mpg123_handle *decoder;
|
||||
float pcm_buf[1152*2*2];
|
||||
size_t pcm_buf_used;
|
||||
int pcm_offs;
|
||||
int fused;
|
||||
};
|
14
Src/mp3-mpg123/resource.h
Normal file
14
Src/mp3-mpg123/resource.h
Normal file
@ -0,0 +1,14 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by mp3-mpg123.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
|
9416
Src/mp3-mpg123/test/catch.hpp
Normal file
9416
Src/mp3-mpg123/test/catch.hpp
Normal file
File diff suppressed because it is too large
Load Diff
2
Src/mp3-mpg123/test/main.cpp
Normal file
2
Src/mp3-mpg123/test/main.cpp
Normal file
@ -0,0 +1,2 @@
|
||||
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
|
||||
#include "catch.hpp"
|
212
Src/mp3-mpg123/test/mp3-mpg123-test.vcproj
Normal file
212
Src/mp3-mpg123/test/mp3-mpg123-test.vcproj
Normal file
@ -0,0 +1,212 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="mp3-mpg123-test"
|
||||
ProjectGUID="{DDA33B81-0A85-4BAA-9DAC-12C0EBC80CEA}"
|
||||
RootNamespace="mp3mpg123test"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..;../../Wasabi;../../libmpg123/src/libmpg123"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="../../nsutil/nsutil.lib"
|
||||
OutputFile="$(ProgramFiles)\Winamp\$(ProjectName).exe"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
<ProjectReference
|
||||
ReferencedProjectIdentifier="{5057C6D0-F787-43EB-BA3F-8D59AB3B09D1}"
|
||||
RelativePathToProject=".\mp3-mpg123.vcproj"
|
||||
/>
|
||||
<ProjectReference
|
||||
ReferencedProjectIdentifier="{67CAA87B-7CF1-4F93-BB67-21C513F40803}"
|
||||
RelativePathToProject="..\libmpg123\ports\MSVC++\2008\libmpg123\libmpg123.vcproj"
|
||||
/>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\main.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\test_adts_mpg123.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\catch.hpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<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>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
88
Src/mp3-mpg123/test/test_adts_mpg123.cpp
Normal file
88
Src/mp3-mpg123/test/test_adts_mpg123.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
#include "catch.hpp"
|
||||
#include "adts_mpg123.h"
|
||||
|
||||
class MemoryStreamer : public ifc_mpeg_stream_reader
|
||||
{
|
||||
public:
|
||||
MemoryStreamer(){}
|
||||
int Peek(void *buffer, size_t to_read, size_t *bytes_read)
|
||||
{
|
||||
if (to_read > this->bufferBytes) {
|
||||
to_read = this->bufferBytes;
|
||||
}
|
||||
memcpy(buffer, this->buffer, to_read);
|
||||
*bytes_read = to_read;
|
||||
return adts::SUCCESS;
|
||||
}
|
||||
|
||||
int Read(void *buffer, size_t to_read, size_t *bytes_read)
|
||||
{
|
||||
if (to_read > this->bufferBytes) {
|
||||
to_read = this->bufferBytes;
|
||||
}
|
||||
memcpy(buffer, this->buffer, to_read);
|
||||
this->buffer = (unsigned char *)this->buffer + *bytes_read;
|
||||
*bytes_read = to_read;
|
||||
bufferBytes -= to_read;
|
||||
return adts::SUCCESS;
|
||||
}
|
||||
|
||||
int EndOf()
|
||||
{
|
||||
if (bufferBytes == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
float GetGain()
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
unsigned char *buffer;
|
||||
size_t bufferBytes;
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
#define CBCLASS MemoryStreamer
|
||||
START_DISPATCH;
|
||||
CB(MPEGSTREAM_PEEK, Peek)
|
||||
CB(MPEGSTREAM_READ, Read)
|
||||
CB(MPEGSTREAM_EOF, EndOf)
|
||||
CB(MPEGSTREAM_GAIN, GetGain)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
||||
|
||||
static const unsigned char mp3_frame1[] = {
|
||||
0xFF, 0xF3, 0x70, 0x54, 0x00, 0x10, 0x2D, 0xFA, 0x96, 0x0F, 0xA0, 0x20,
|
||||
0x00, 0x81, 0xE8, 0x05, 0x2C, 0x1F, 0x40, 0x00, 0x00, 0x03, 0x51, 0xB6,
|
||||
0x1B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3,
|
||||
0x0B, 0x05, 0x86, 0x07, 0x60, 0x2E, 0x11, 0x94, 0x0A, 0x01, 0x61, 0xA0,
|
||||
0xD0, 0xC2, 0xC5, 0xCF, 0x81, 0x41, 0x43, 0x2F, 0x44, 0x4E, 0x6E, 0x1F,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0x01, 0xA0, 0xA2, 0x8B, 0x87, 0xF6, 0x2E,
|
||||
0x7A, 0x0A, 0x19, 0x25, 0x9F, 0x02, 0xF6, 0x40, 0xA1, 0x92, 0x2E, 0x2E,
|
||||
0x7F, 0xEE, 0xFF, 0x96, 0x1E, 0x0E, 0x2C, 0x1B, 0x87, 0xEC, 0x1C, 0x07,
|
||||
0x8A, 0x1C, 0x18, 0x58, 0x76, 0x7C, 0x0A, 0x07, 0x86, 0x5E, 0x88, 0x94,
|
||||
0xEF, 0x02, 0xF6, 0x82, 0x86, 0x49, 0x67, 0xC0, 0xBD, 0x90, 0x28, 0x64,
|
||||
0x8B, 0x8B, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC,
|
||||
0x3D, 0xA0, 0xA2, 0x4B, 0x8B, 0x8B, 0x8A, 0x51, 0x60, 0xDC, 0x5D, 0x85,
|
||||
0x03, 0xC3, 0x2C, 0x00, 0x03, 0x31, 0xE0, 0x00, 0x7F};
|
||||
TEST_CASE("", "[adts_mpg123]") {
|
||||
|
||||
mpg123_init();
|
||||
ADTS_MPG123 mp3;
|
||||
MemoryStreamer memoryStreamer;
|
||||
REQUIRE(mp3.Initialize(false, false, false, 16, true, true, true) == adts::SUCCESS);
|
||||
REQUIRE(mp3.Open(&memoryStreamer) == true);
|
||||
size_t numBits;
|
||||
size_t numChannels;
|
||||
int sampleRate;
|
||||
memoryStreamer.buffer = (unsigned char *)mp3_frame1;
|
||||
memoryStreamer.bufferBytes = sizeof(mp3_frame1);
|
||||
size_t outputWritten=777;
|
||||
size_t bitrate=777;
|
||||
REQUIRE(mp3.Sync(&memoryStreamer, 0, 0, &outputWritten, &bitrate) == adts::SUCCESS);
|
||||
REQUIRE(bitrate == 64);
|
||||
REQUIRE(outputWritten == 0);
|
||||
|
||||
}
|
39
Src/mp3-mpg123/version.rc2
Normal file
39
Src/mp3-mpg123/version.rc2
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
#include "../Winamp/buildType.h"
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION WINAMP_PRODUCTVER
|
||||
PRODUCTVERSION WINAMP_PRODUCTVER
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Winamp SA"
|
||||
VALUE "FileDescription", "Winamp 5.x System Component"
|
||||
VALUE "FileVersion", STR_WINAMP_PRODUCTVER
|
||||
VALUE "InternalName", "mp3.w5s"
|
||||
VALUE "LegalCopyright", "Copyright <20> 2015-2023 Ben Allison"
|
||||
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
|
||||
VALUE "OriginalFilename", "mp3.w5s"
|
||||
VALUE "ProductName", "Winamp MPEG Audio Decoder Service"
|
||||
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
Reference in New Issue
Block a user