* Enabled the mp2/mp3 decoder in the ffmpeg plug-in (CodecTable.h).
* Removed the mp3_reader and mp3_decoder from the image and from the source tree even. The mpeg123lib based decoder was crashy, since the lib didn't cope with bad input data too well, whatever the reason, but bad input can also be a specially crafted file. I didn't see the value in keeping two decoders around that use a third party library as backend. While reading in the mp3_decoder code, I even saw that it used global variables in the mpeg123 lib to figure out framerate and channel count, after decoding a bit of input. Obviously this has concurrency issues. * Removed the mp4_reader from the image. It is native code, and should perhaps be preferred over imported code, but I don't have the resources to look into it, and David doesn't seem to have the time either. There are basically three types of problems with the native mp4 reader: 1) It is way too CPU intensive. I have many HD files that don't play at all, since there is not enough time left for actual decoding. 2) Seeking leaves a lot of visual artifacts (with the very same decoder plug-in), since there seems something wrong either with finding true keyframes, or with flushing buffers correctly. And 3) very often audio stops working at all after seeking. Sometimes a keyframe is returned for audio which is very far away from the wanted frame, which currently triggers bad behavior in the audio producer node in MediaPlayer and can even crash the media_addon_server. With the ffmpeg based mp4 reader, none of these problems exist: Seeking is perfect, no artifacts, CPU load is low enough for pretty much all HD clips I tested with, and audio always works and is always in perfect sync with the video after seeking. If there are regressions after this commit at all (I tested a lot of files), then I anticipate only that the ffmpeg plugin does not advertise support for files it could actually handle (i.e. easily fixable). In those cases hopefully a test stream can be made available. If the native mp4 reader is improved to the point that it works as well as the ffmpeg mp4 demuxer, we can easily switch it back, but for now, users will prefer reliable playback. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38403 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
779ccf5c6d
commit
e9a09f6670
@ -141,9 +141,7 @@ SYSTEM_ADD_ONS_MEDIA = cortex_audioadapter.media_addon
|
||||
;
|
||||
SYSTEM_ADD_ONS_MEDIA_PLUGINS = $(GPL_ONLY)ac3_decoder
|
||||
aiff_reader asf_reader au_reader avi_reader $(X86_ONLY)ffmpeg
|
||||
matroska mov_reader
|
||||
mp3_decoder mp3_reader
|
||||
mp4_reader musepack
|
||||
matroska mov_reader musepack
|
||||
ogg raw_decoder speex
|
||||
$(X86_ONLY)ape_reader
|
||||
# theora
|
||||
|
@ -10,8 +10,6 @@ SubInclude HAIKU_TOP src add-ons media plugins avi_reader ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins matroska ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins mov_reader ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins mp3_decoder ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins mp3_reader ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins mp4_reader ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins musepack ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ogg ;
|
||||
|
@ -35,14 +35,23 @@ const struct codec_table gCodecTable[] = {
|
||||
{CODEC_ID_ADPCM_MS, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x0002, "MS ADPCM"},
|
||||
{CODEC_ID_ADPCM_IMA_WAV, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 0x6D730011, "IMA ADPCM"},
|
||||
{CODEC_ID_ADPCM_MS, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 0x6D730002, "MS ADPCM"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 0x6D730050, "MP Layer2"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 0x6D730055, "MP Layer3"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, 0x6D730050, "MP Layer2"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, 0x6D730055, "MP Layer3"},
|
||||
#if 0
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x0050, "MPEG Audio Layer 2"}, /* mpeg audio layer 2 */
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x0055, "MPEG Audio Layer 3"}, /* mpeg audio layer 3 */
|
||||
#endif
|
||||
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 0x6D730050, "MP Layer2"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 0x6D730055, "MP Layer3"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, '.mp3', "MPEG Audio Layer 3"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, '3pm.', "MPEG Audio Layer 3"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_AVI_FORMAT_FAMILY, '.mp3', "MPEG Audio Layer 3"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_AVI_FORMAT_FAMILY, '3pm.', "MPEG Audio Layer 3"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, 0x6D730050, "MP Layer2"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, 0x6D730055, "MP Layer3"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, B_MPEG_1_AUDIO_LAYER_2, "MP Layer2"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, B_MPEG_1_AUDIO_LAYER_3, "MP Layer3"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, B_MPEG_2_AUDIO_LAYER_2, "MP Layer2"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, B_MPEG_2_AUDIO_LAYER_3, "MP Layer3"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, B_MPEG_2_5_AUDIO_LAYER_2, "MP Layer2"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, B_MPEG_2_5_AUDIO_LAYER_3, "MP Layer3"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x0050, "MPEG Audio Layer 2"},
|
||||
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x0055, "MPEG Audio Layer 3"},
|
||||
|
||||
{CODEC_ID_ADPCM_IMA_QT, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 'ima4', "Quicktime IMA4"},
|
||||
{CODEC_ID_ADPCM_IMA_QT, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 'IMA4', "Quicktime IMA4"},
|
||||
|
@ -24,8 +24,9 @@ static const DemuxerFormat gDemuxerTable[] = {
|
||||
// B_WAV_FORMAT_FAMILY, B_AVI_FORMAT_FAMILY
|
||||
// },
|
||||
// {
|
||||
// // Tested with a limited amount of streams and works ok, keep using
|
||||
// // the avi_reader implementation by Marcus Overhagen.
|
||||
// // Tested with many streams and either works ok, or has inconsistent
|
||||
// // seeking results for audio, i.e. often audio is not in sync.
|
||||
// // Keep using the avi_reader implementation by Marcus Overhagen.
|
||||
// "avi", "AVI (Audio Video Interleaved)", "video/x-msvideo",
|
||||
// B_WAV_FORMAT_FAMILY, B_AVI_FORMAT_FAMILY
|
||||
// },
|
||||
@ -42,40 +43,41 @@ static const DemuxerFormat gDemuxerTable[] = {
|
||||
B_QUICKTIME_FORMAT_FAMILY, B_QUICKTIME_FORMAT_FAMILY
|
||||
},
|
||||
// {
|
||||
// // Tested and appears to work ok with the one clip I have...
|
||||
// // Tested and appears to work ok with regards to video,
|
||||
// // audio seems a problem.
|
||||
// "matroska", "Matroska Movie", "video/x-matroska",
|
||||
// B_WAV_FORMAT_FAMILY, B_AVI_FORMAT_FAMILY
|
||||
// B_MISC_FORMAT_FAMILY, B_QUICKTIME_FORMAT_FAMILY
|
||||
// },
|
||||
// {
|
||||
// // Plays the limited amount of files I could test with.
|
||||
// "mov", "Quicktime Movie", "video/x-mov",
|
||||
// B_QUICKTIME_FORMAT_FAMILY, B_QUICKTIME_FORMAT_FAMILY
|
||||
// },
|
||||
// {
|
||||
// // Plays the limited amount of files I could test with.
|
||||
// "mp4", "MPEG-4 Movie", "video/x-mp4",
|
||||
// B_QUICKTIME_FORMAT_FAMILY, B_QUICKTIME_FORMAT_FAMILY
|
||||
// },
|
||||
// {
|
||||
// // TODO: Broken because of buggy FindKeyFrame() or Seek() support.
|
||||
// "mp3", "MPEG (Motion Picture Experts Group)", "audio/mpg",
|
||||
// B_MPEG_FORMAT_FAMILY, B_MPEG_FORMAT_FAMILY
|
||||
// },
|
||||
{
|
||||
// Plays all files I could test with perfectly.
|
||||
"mp4", "MPEG-4 Movie", "video/x-mp4",
|
||||
B_QUICKTIME_FORMAT_FAMILY, B_QUICKTIME_FORMAT_FAMILY
|
||||
},
|
||||
{
|
||||
// Works very well with all files I tested.
|
||||
"mp3", "MPEG-3", "audio/mpg",
|
||||
B_MPEG_FORMAT_FAMILY, B_MPEG_FORMAT_FAMILY
|
||||
},
|
||||
{
|
||||
// NOTE: Tested with a couple of files and only audio works ok.
|
||||
// On some files, the duration and time_base is detected incorrectly
|
||||
// by libavformat and those streams don't play at all.
|
||||
"mpg", "MPEG (Motion Picture Experts Group)", "video/mpeg",
|
||||
"mpg", "MPEG", "video/mpeg",
|
||||
B_MPEG_FORMAT_FAMILY, B_MPEG_FORMAT_FAMILY
|
||||
},
|
||||
{
|
||||
// NOTE: keep this before "mpeg" so it detects "mpegts" first.
|
||||
"mpegts", "MPEG (Motion Picture Experts Group)", "video/mpeg",
|
||||
"mpegts", "MPEG TS", "video/mpeg",
|
||||
B_WAV_FORMAT_FAMILY, B_AVI_FORMAT_FAMILY
|
||||
},
|
||||
{
|
||||
// TODO: Also covers "mpegvideo", plus see mpegts.
|
||||
"mpeg", "MPEG (Motion Picture Experts Group)", "video/mpeg",
|
||||
"mpeg", "MPEG", "video/mpeg",
|
||||
B_MPEG_FORMAT_FAMILY, B_MPEG_FORMAT_FAMILY
|
||||
},
|
||||
{
|
||||
|
@ -1,18 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons media plugins mp3_decoder ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
UsePrivateHeaders media ;
|
||||
|
||||
SubDirHdrs [ FDirName $(SUBDIR) mpglib ] ;
|
||||
|
||||
Addon mp3_decoder :
|
||||
mp3DecoderPlugin.cpp
|
||||
:
|
||||
libmpglib.a
|
||||
be
|
||||
libmedia.so
|
||||
$(TARGET_LIBSUPC++)
|
||||
;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons media plugins mp3_decoder mpglib ;
|
@ -1,514 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2004, Marcus Overhagen
|
||||
* 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.
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <DataIO.h>
|
||||
#include <Locker.h>
|
||||
#include <MediaFormats.h>
|
||||
#include <MediaRoster.h>
|
||||
#include <ReaderPlugin.h>
|
||||
|
||||
#include "mp3DecoderPlugin.h"
|
||||
|
||||
//#define TRACE_MP3_DECODER
|
||||
#ifdef TRACE_MP3_DECODER
|
||||
#define TRACE printf
|
||||
#else
|
||||
#define TRACE(a...)
|
||||
#endif
|
||||
|
||||
#define DECODE_BUFFER_SIZE (32 * 1024)
|
||||
|
||||
// reference:
|
||||
// http://www.mp3-tech.org/programmer/frame_header.html
|
||||
|
||||
inline size_t
|
||||
AudioBufferSize(const media_raw_audio_format &raf, bigtime_t buffer_duration = 50000 /* 50 ms */)
|
||||
{
|
||||
return (raf.format & 0xf) * (raf.channel_count)
|
||||
* (size_t)((raf.frame_rate * buffer_duration) / 1000000.0);
|
||||
}
|
||||
|
||||
// bit_rate_table[mpeg_version_index][layer_index][bitrate_index]
|
||||
static const int bit_rate_table[4][4][16] =
|
||||
{
|
||||
{ // mpeg version 2.5
|
||||
{ }, // undefined layer
|
||||
{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, // layer 3
|
||||
{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, // layer 2
|
||||
{ 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 } // layer 1
|
||||
},
|
||||
{ // undefined version
|
||||
{ },
|
||||
{ },
|
||||
{ },
|
||||
{ }
|
||||
},
|
||||
{ // mpeg version 2
|
||||
{ },
|
||||
{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 },
|
||||
{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 },
|
||||
{ 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 }
|
||||
},
|
||||
{ // mpeg version 1
|
||||
{ },
|
||||
{ 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 },
|
||||
{ 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0 },
|
||||
{ 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0}
|
||||
}
|
||||
};
|
||||
|
||||
// frame_rate_table[mpeg_version_index][sampling_rate_index]
|
||||
static const int frame_rate_table[4][4] =
|
||||
{
|
||||
{ 11025, 12000, 8000, 0}, // mpeg version 2.5
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 22050, 24000, 16000, 0}, // mpeg version 2
|
||||
{ 44100, 48000, 32000, 0} // mpeg version 1
|
||||
};
|
||||
|
||||
|
||||
mp3Decoder::mp3Decoder()
|
||||
{
|
||||
InitMP3(&fMpgLibPrivate);
|
||||
fResidualBytes = 0;
|
||||
fResidualBuffer = 0;
|
||||
fDecodeBuffer = new uint8 [DECODE_BUFFER_SIZE];
|
||||
fStartTime = 0;
|
||||
fFrameSize = 0;
|
||||
fFrameRate = 0;
|
||||
fBitRate = 0;
|
||||
fChannelCount = 0;
|
||||
fOutputBufferSize = 0;
|
||||
fNeedSync = true; // some files start with garbage
|
||||
fDecodingError = false;
|
||||
fSampleNo = 0;
|
||||
}
|
||||
|
||||
|
||||
mp3Decoder::~mp3Decoder()
|
||||
{
|
||||
ExitMP3(&fMpgLibPrivate);
|
||||
delete [] fDecodeBuffer;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mp3Decoder::GetCodecInfo(media_codec_info *info)
|
||||
{
|
||||
strcpy(info->short_name, "mp3");
|
||||
strcpy(info->pretty_name, "MPEG audio decoder (mpeg123 mpglib)");
|
||||
// ToDo: could alter the above string depending on the real format
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
mp3Decoder::Setup(media_format *ioEncodedFormat,
|
||||
const void *infoBuffer, size_t infoSize)
|
||||
{
|
||||
// decode first chunk to initialize mpeg library
|
||||
status_t err = DecodeNextChunk();
|
||||
if (B_OK != err) {
|
||||
printf("mp3Decoder::Setup failed, can't decode first chunk %ld\n",err);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// initialize fBitRate, fFrameRate and fChannelCount from mpg decode library values of first header
|
||||
extern int tabsel_123[2][3][16];
|
||||
extern long freqs[9];
|
||||
fBitRate = tabsel_123[fMpgLibPrivate.fr.lsf][fMpgLibPrivate.fr.lay-1][fMpgLibPrivate.fr.bitrate_index] * 1000;
|
||||
fFrameRate = freqs[fMpgLibPrivate.fr.sampling_frequency];
|
||||
fChannelCount = fMpgLibPrivate.fr.stereo;
|
||||
|
||||
printf("mp3Decoder::Setup: channels %d, bitrate %d, framerate %d\n", fChannelCount, fBitRate, fFrameRate);
|
||||
|
||||
// put some more useful info into the media_format describing our input format
|
||||
ioEncodedFormat->u.encoded_audio.bit_rate = fBitRate;
|
||||
ioEncodedFormat->u.encoded_audio.output.frame_rate = fFrameRate;
|
||||
ioEncodedFormat->u.encoded_audio.output.channel_count = fChannelCount;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
mp3Decoder::NegotiateOutputFormat(media_format *ioDecodedFormat)
|
||||
{
|
||||
// fFrameRate and fChannelCount are already valid here
|
||||
|
||||
// BeBook says: The codec will find and return in ioFormat its best matching format
|
||||
// => This means, we never return an error, and always change the format values
|
||||
// that we don't support to something more applicable
|
||||
|
||||
ioDecodedFormat->type = B_MEDIA_RAW_AUDIO;
|
||||
ioDecodedFormat->u.raw_audio.frame_rate = fFrameRate;
|
||||
ioDecodedFormat->u.raw_audio.channel_count = fChannelCount;
|
||||
ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_SHORT;
|
||||
ioDecodedFormat->u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN;
|
||||
|
||||
fFrameSize = (ioDecodedFormat->u.raw_audio.format & 0xf) * ioDecodedFormat->u.raw_audio.channel_count;
|
||||
if (ioDecodedFormat->u.raw_audio.buffer_size == 0)
|
||||
ioDecodedFormat->u.raw_audio.buffer_size = AudioBufferSize(ioDecodedFormat->u.raw_audio);
|
||||
else
|
||||
ioDecodedFormat->u.raw_audio.buffer_size = (ioDecodedFormat->u.raw_audio.buffer_size / fFrameSize) * fFrameSize;
|
||||
|
||||
if (ioDecodedFormat->u.raw_audio.channel_mask == 0)
|
||||
ioDecodedFormat->u.raw_audio.channel_mask = (fChannelCount == 1) ? B_CHANNEL_LEFT : B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
|
||||
|
||||
// setup rest of the needed variables
|
||||
fOutputBufferSize = ioDecodedFormat->u.raw_audio.buffer_size;
|
||||
|
||||
TRACE("mp3Decoder::NegotiateOutputFormat: BufferSize %d, FrameSize %d\n", fOutputBufferSize, fFrameSize);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
mp3Decoder::Seek(uint32 seekTo,
|
||||
int64 seekFrame, int64 *frame,
|
||||
bigtime_t seekTime, bigtime_t *time)
|
||||
{
|
||||
fNeedSync = true;
|
||||
|
||||
if (seekTo == B_MEDIA_SEEK_TO_TIME) {
|
||||
TRACE("MP3Decoder::Seek by time ");
|
||||
TRACE("from frame %Ld and time %.6f TO Required Time %.6f. ", fSampleNo, fStartTime / 1000000.0, seekTime / 1000000.0);
|
||||
|
||||
*frame = (int64)(seekTime * fFrameRate / 1000000LL);
|
||||
*time = seekTime;
|
||||
} else if (seekTo == B_MEDIA_SEEK_TO_FRAME) {
|
||||
TRACE("MP3Decoder::Seek by Frame ");
|
||||
TRACE("from time %.6f and frame %Ld TO Required Frame %Ld. ", fStartTime / 1000000.0, fSampleNo, seekFrame);
|
||||
|
||||
*time = (bigtime_t)(seekFrame * 1000000LL / fFrameRate);
|
||||
*frame = seekFrame;
|
||||
} else
|
||||
return B_BAD_VALUE;
|
||||
|
||||
fSampleNo = *frame;
|
||||
fStartTime = *time;
|
||||
TRACE("so new frame is %Ld at time %.6f\n", *frame, *time / 1000000.0);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
mp3Decoder::Decode(void *buffer, int64 *frameCount,
|
||||
media_header *mediaHeader, media_decode_info *info /* = 0 */)
|
||||
{
|
||||
status_t last_err = B_LAST_BUFFER_ERROR;
|
||||
uint8 * out_buffer = static_cast<uint8 *>(buffer);
|
||||
int32 out_bytes_needed = fOutputBufferSize;
|
||||
int32 out_bytes = 0;
|
||||
|
||||
fStartTime = (bigtime_t)(fSampleNo *1000000LL / fFrameRate);
|
||||
mediaHeader->start_time = fStartTime;
|
||||
|
||||
while (out_bytes_needed > 0) {
|
||||
|
||||
if (fNeedSync) {
|
||||
TRACE("mp3Decoder::Decode: syncing...\n");
|
||||
ExitMP3(&fMpgLibPrivate);
|
||||
InitMP3(&fMpgLibPrivate);
|
||||
fDecodingError = false;
|
||||
fResidualBytes = 0;
|
||||
// fNeedSync is reset in DecodeNextChunk
|
||||
}
|
||||
|
||||
if (fDecodingError)
|
||||
return B_ERROR;
|
||||
|
||||
if (fResidualBytes) {
|
||||
int32 bytes = min_c(fResidualBytes, out_bytes_needed);
|
||||
memcpy(out_buffer, fResidualBuffer, bytes);
|
||||
fResidualBuffer += bytes;
|
||||
fResidualBytes -= bytes;
|
||||
out_buffer += bytes;
|
||||
out_bytes += bytes;
|
||||
out_bytes_needed -= bytes;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
last_err = DecodeNextChunk();
|
||||
if (last_err != B_OK) {
|
||||
fDecodingError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*frameCount = out_bytes / fFrameSize;
|
||||
fSampleNo += *frameCount;
|
||||
|
||||
TRACE("framecount %Ld, time %.6f\n", *frameCount, mediaHeader->start_time / 1000000.0);
|
||||
return (out_bytes > 0) ? B_OK : last_err;
|
||||
}
|
||||
|
||||
status_t
|
||||
mp3Decoder::DecodeNextChunk()
|
||||
{
|
||||
const void *chunkBuffer;
|
||||
size_t chunkSize;
|
||||
media_header mh;
|
||||
int outsize;
|
||||
int result;
|
||||
status_t err;
|
||||
|
||||
// decode residual data that is still in the decoder first
|
||||
result = decodeMP3(&fMpgLibPrivate, 0, 0, (char *)fDecodeBuffer, DECODE_BUFFER_SIZE, &outsize);
|
||||
if (result == MP3_OK) {
|
||||
fResidualBuffer = fDecodeBuffer;
|
||||
fResidualBytes = outsize;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// get another chunk and push it to the decoder
|
||||
err = GetNextChunk(&chunkBuffer, &chunkSize, &mh);
|
||||
if (err != B_OK)
|
||||
return err;
|
||||
|
||||
fStartTime = mh.start_time;
|
||||
// TRACE("mp3Decoder: fStartTime reset to %.6f\n", fStartTime / 1000000.0);
|
||||
|
||||
// resync after a seek
|
||||
if (fNeedSync) {
|
||||
TRACE("mp3Decoder::DecodeNextChunk: Syncing...\n");
|
||||
if (chunkSize < 4) {
|
||||
TRACE("mp3Decoder::DecodeNextChunk: Sync failed, frame too small\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
int len = GetFrameLength(chunkBuffer);
|
||||
TRACE("mp3Decoder::DecodeNextChunk: chunkSize %ld, first frame length %d\n", chunkSize, len);
|
||||
// len == -1 when not at frame start
|
||||
// len == chunkSize for mp3 reader (delivers single frames)
|
||||
if (len < (int)chunkSize) {
|
||||
// FIXME: join a few chunks to create a larger (2k) buffer, and use:
|
||||
// while (chunkSize > 100) {
|
||||
// if (IsValidStream((uint8 *)chunkBuffer, chunkSize))
|
||||
while (chunkSize >= 4) {
|
||||
if (GetFrameLength(chunkBuffer) > 0)
|
||||
break;
|
||||
chunkBuffer = (uint8 *)chunkBuffer + 1;
|
||||
chunkSize--;
|
||||
}
|
||||
// if (chunkSize <= 100) {
|
||||
if (chunkSize == 3) {
|
||||
TRACE("mp3Decoder::DecodeNextChunk: Sync failed\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
TRACE("mp3Decoder::DecodeNextChunk: new chunkSize %ld, first frame length %d\n", chunkSize, GetFrameLength(chunkBuffer));
|
||||
}
|
||||
fNeedSync = false;
|
||||
}
|
||||
|
||||
result = decodeMP3(&fMpgLibPrivate, (char *)chunkBuffer, chunkSize, (char *)fDecodeBuffer, DECODE_BUFFER_SIZE, &outsize);
|
||||
if (result == MP3_NEED_MORE) {
|
||||
TRACE("mp3Decoder::DecodeNextChunk: decodeMP3 returned MP3_NEED_MORE\n");
|
||||
fResidualBuffer = NULL;
|
||||
fResidualBytes = 0;
|
||||
return B_OK;
|
||||
} else if (result != MP3_OK) {
|
||||
TRACE("mp3Decoder::DecodeNextChunk: decodeMP3 returned error %d\n", result);
|
||||
return B_ERROR;
|
||||
// fNeedSync = true;
|
||||
// fResidualBuffer = NULL;
|
||||
// fResidualBytes = 0;
|
||||
// return B_OK;
|
||||
}
|
||||
|
||||
//printf("mp3Decoder::Decode: decoded %d bytes into %d bytes\n",chunkSize, outsize);
|
||||
|
||||
fResidualBuffer = fDecodeBuffer;
|
||||
fResidualBytes = outsize;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
mp3Decoder::IsValidStream(const uint8 *buffer, int size)
|
||||
{
|
||||
// check 3 consecutive frame headers to make sure
|
||||
// that the length encoded in the header is correct,
|
||||
// and also that mpeg version and layer do not change
|
||||
int length1 = GetFrameLength(buffer);
|
||||
if (length1 < 0 || (length1 + 4) > size)
|
||||
return false;
|
||||
int version_index1 = (buffer[1] >> 3) & 0x03;
|
||||
int layer_index1 = (buffer[1] >> 1) & 0x03;
|
||||
int length2 = GetFrameLength(buffer + length1);
|
||||
if (length2 < 0 || (length1 + length2 + 4) > size)
|
||||
return false;
|
||||
int version_index2 = (buffer[length1 + 1] >> 3) & 0x03;
|
||||
int layer_index2 = (buffer[length1 + 1] >> 1) & 0x03;
|
||||
if (version_index1 != version_index2 || layer_index1 != layer_index2)
|
||||
return false;
|
||||
int length3 = GetFrameLength(buffer + length1 + length2);
|
||||
if (length3 < 0)
|
||||
return false;
|
||||
int version_index3 = (buffer[length1 + length2 + 1] >> 3) & 0x03;
|
||||
int layer_index3 = (buffer[length1 + length2 + 1] >> 1) & 0x03;
|
||||
if (version_index2 != version_index3 || layer_index2 != layer_index3)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
mp3Decoder::GetFrameLength(const void *header)
|
||||
{
|
||||
const uint8 *h = static_cast<const uint8 *>(header);
|
||||
bool lsf = false;
|
||||
|
||||
if (h[0] != 0xff) {
|
||||
TRACE("No 0xff MP3 Header in chunk %x\n",h[0]);
|
||||
return -1;
|
||||
}
|
||||
if ((h[1] & 0xe0) != 0xe0) {
|
||||
TRACE("No 0xe0 MP3 Header in chunk %x\n",h[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int mpeg_version_index = (h[1] >> 3) & 0x03;
|
||||
int layer_index = (h[1] >> 1) & 0x03;
|
||||
int bitrate_index = (h[2] >> 4) & 0x0f;
|
||||
int sampling_rate_index = (h[2] >> 2) & 0x03;
|
||||
int padding = (h[2] >> 1) & 0x01;
|
||||
/* not interested in the other bits */
|
||||
|
||||
int bitrate = bit_rate_table[mpeg_version_index][layer_index][bitrate_index];
|
||||
int framerate = frame_rate_table[mpeg_version_index][sampling_rate_index];
|
||||
lsf = (mpeg_version_index == 0) || (mpeg_version_index == 2);
|
||||
|
||||
TRACE("%s %s, %s crc, bit rate %d, frame rate %d, padding %d\n",
|
||||
mpeg_version_index == 0 ? "mpeg 2.5" : (mpeg_version_index == 2 ? "mpeg 2" : "mpeg 1"),
|
||||
layer_index == 3 ? "layer 1" : (layer_index == 2 ? "layer 2" : "layer 3"),
|
||||
(h[1] & 0x01) ? "no" : "has",
|
||||
bitrate, framerate, padding);
|
||||
|
||||
if (!bitrate || !framerate) {
|
||||
TRACE("Invalid bitrate %d or framerate %d\n",bitrate,framerate);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int length;
|
||||
if (layer_index == 3) { // layer 1
|
||||
length = ((12 * 1000 * bitrate) / framerate + padding) * 4;
|
||||
} else if (layer_index == 2) { // layer 2
|
||||
length = ((144 * 1000 * bitrate) / framerate) + padding;
|
||||
} else if (lsf) { // layer 3 with lsf
|
||||
length = ((144 * 1000 * bitrate) / (framerate*2)) + padding;
|
||||
} else { // layer 3 without lsf
|
||||
length = ((144 * 1000 * bitrate) / framerate) + padding;
|
||||
}
|
||||
|
||||
#if 0
|
||||
TRACE("%s %s, %s crc, bit rate %d, frame rate %d, padding %d, frame length %d\n",
|
||||
mpeg_version_index == 0 ? "mpeg 2.5" : (mpeg_version_index == 2 ? "mpeg 2" : "mpeg 1"),
|
||||
layer_index == 3 ? "layer 1" : (layer_index == 2 ? "layer 2" : "layer 3"),
|
||||
(h[1] & 0x01) ? "no" : "has",
|
||||
bitrate, framerate, padding, length);
|
||||
#endif
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
Decoder *
|
||||
mp3DecoderPlugin::NewDecoder(uint index)
|
||||
{
|
||||
static BLocker locker;
|
||||
static bool initdone = false;
|
||||
locker.Lock();
|
||||
if (!initdone) {
|
||||
InitMpgLib();
|
||||
initdone = true;
|
||||
}
|
||||
locker.Unlock();
|
||||
return new mp3Decoder;
|
||||
}
|
||||
|
||||
|
||||
static media_format mp3_formats[1];
|
||||
|
||||
status_t
|
||||
mp3DecoderPlugin::GetSupportedFormats(media_format ** formats, size_t * count)
|
||||
{
|
||||
const mpeg_id ids[] = {
|
||||
B_MPEG_1_AUDIO_LAYER_1,
|
||||
B_MPEG_1_AUDIO_LAYER_2,
|
||||
B_MPEG_1_AUDIO_LAYER_3, // "MP3"
|
||||
B_MPEG_2_AUDIO_LAYER_1,
|
||||
B_MPEG_2_AUDIO_LAYER_2,
|
||||
B_MPEG_2_AUDIO_LAYER_3,
|
||||
B_MPEG_2_5_AUDIO_LAYER_1,
|
||||
B_MPEG_2_5_AUDIO_LAYER_2,
|
||||
B_MPEG_2_5_AUDIO_LAYER_3,
|
||||
};
|
||||
const size_t otherIDs = 6;
|
||||
const size_t numIDs = otherIDs + sizeof(ids) / sizeof(mpeg_id);
|
||||
media_format_description descriptions[numIDs];
|
||||
descriptions[0].family = B_WAV_FORMAT_FAMILY;
|
||||
descriptions[0].u.wav.codec = 0x0050;
|
||||
descriptions[1].family = B_WAV_FORMAT_FAMILY;
|
||||
descriptions[1].u.wav.codec = 0x0055;
|
||||
descriptions[2].family = B_QUICKTIME_FORMAT_FAMILY;
|
||||
descriptions[2].u.quicktime.codec = '.mp3';
|
||||
descriptions[3].family = B_QUICKTIME_FORMAT_FAMILY;
|
||||
descriptions[3].u.quicktime.codec = '3pm.';
|
||||
descriptions[4].family = B_AVI_FORMAT_FAMILY;
|
||||
descriptions[4].u.avi.codec = '.mp3';
|
||||
descriptions[5].family = B_AVI_FORMAT_FAMILY;
|
||||
descriptions[5].u.avi.codec = '3pm.';
|
||||
for (size_t i = otherIDs; i < numIDs; i++) {
|
||||
descriptions[i].family = B_MPEG_FORMAT_FAMILY;
|
||||
descriptions[i].u.mpeg.id = ids[i-otherIDs];
|
||||
}
|
||||
|
||||
media_format format;
|
||||
format.type = B_MEDIA_ENCODED_AUDIO;
|
||||
format.u.encoded_audio = media_encoded_audio_format::wildcard;
|
||||
format.u.encoded_audio.output.format = media_raw_audio_format::B_AUDIO_SHORT;
|
||||
format.u.encoded_audio.output.byte_order = B_MEDIA_HOST_ENDIAN;
|
||||
|
||||
BMediaFormats mediaFormats;
|
||||
status_t result = mediaFormats.InitCheck();
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
result = mediaFormats.MakeFormatFor(descriptions, numIDs, &format);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
mp3_formats[0] = format;
|
||||
|
||||
*formats = mp3_formats;
|
||||
*count = 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
MediaPlugin *instantiate_plugin()
|
||||
{
|
||||
return new mp3DecoderPlugin;
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2004, Marcus Overhagen
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef _MP3_DECODER_PLUGIN_H
|
||||
#define _MP3_DECODER_PLUGIN_H
|
||||
|
||||
#include "DecoderPlugin.h"
|
||||
#include "mpglib/mpglib.h"
|
||||
|
||||
class mp3Decoder : public Decoder
|
||||
{
|
||||
public:
|
||||
mp3Decoder();
|
||||
~mp3Decoder();
|
||||
|
||||
void GetCodecInfo(media_codec_info *codecInfo);
|
||||
|
||||
status_t Setup(media_format *ioEncodedFormat,
|
||||
const void *infoBuffer, size_t infoSize);
|
||||
|
||||
status_t NegotiateOutputFormat(media_format *ioDecodedFormat);
|
||||
|
||||
status_t Seek(uint32 seekTo,
|
||||
int64 seekFrame, int64 *frame,
|
||||
bigtime_t seekTime, bigtime_t *time);
|
||||
|
||||
|
||||
status_t Decode(void *buffer, int64 *frameCount,
|
||||
media_header *mediaHeader, media_decode_info *info);
|
||||
|
||||
private:
|
||||
status_t DecodeNextChunk();
|
||||
bool IsValidStream(const uint8 *buffer, int size);
|
||||
int GetFrameLength(const void *header);
|
||||
|
||||
private:
|
||||
struct mpstr fMpgLibPrivate;
|
||||
int32 fResidualBytes;
|
||||
uint8 * fResidualBuffer;
|
||||
uint8 * fDecodeBuffer;
|
||||
bigtime_t fStartTime;
|
||||
int fFrameSize;
|
||||
int fFrameRate;
|
||||
int fBitRate;
|
||||
int fChannelCount;
|
||||
int fOutputBufferSize;
|
||||
bool fNeedSync;
|
||||
bool fDecodingError;
|
||||
uint64 fSampleNo;
|
||||
};
|
||||
|
||||
|
||||
class mp3DecoderPlugin : public DecoderPlugin
|
||||
{
|
||||
public:
|
||||
Decoder * NewDecoder(uint index);
|
||||
status_t GetSupportedFormats(media_format ** formats, size_t * count);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,15 +0,0 @@
|
||||
14/Oct/1999:
|
||||
- VBR fix
|
||||
- Layer2 and Layer1 added
|
||||
|
||||
21/Nov/2003: (by Marcus Overhagen)
|
||||
- modified for usage with OpenBeOS
|
||||
- removed global variable struct mpstr *gmp
|
||||
- moved initialization into separate function
|
||||
|
||||
25/Nov/2003: (by Marcus Overhagen)
|
||||
- removed global variables bitindex and wordpointer
|
||||
- cleanup
|
||||
|
||||
29/Nov/2003: (by Marcus Overhagen)
|
||||
- cleanup
|
@ -1,14 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons media plugins mp3_decoder mpglib ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
StaticLibrary libmpglib.a :
|
||||
common.c
|
||||
dct64_i386.c
|
||||
decode_i386.c
|
||||
interface.c
|
||||
layer1.c
|
||||
layer2.c
|
||||
layer3.c
|
||||
tabinit.c
|
||||
;
|
@ -1,39 +0,0 @@
|
||||
MP3 library
|
||||
-----------
|
||||
Version 0.2a
|
||||
|
||||
This decoder is a 'light' version (thrown out all unnecessay parts)
|
||||
from the mpg123 package. I made this for a company.
|
||||
|
||||
Currently only Layer3 is enabled to save some space. Layer1,2 isn't
|
||||
tested at all. The interface will not change significantly.
|
||||
A backport to the mpg123 package is planed.
|
||||
|
||||
compiled and tested only on Solaris 2.6
|
||||
main.c contains a simple demo application for library.
|
||||
|
||||
COPYING: you may use this source under LGPL terms!
|
||||
(Yes, I switched to LGPL for the _mpglib_ part!)
|
||||
|
||||
PLEASE NOTE: This software may contain patented algorithms (at least
|
||||
patented in some countries). It may be not allowed to sell/use products
|
||||
based on this source code in these countries. Check this out first!
|
||||
|
||||
COPYRIGHT of MP3 music:
|
||||
Please note, that the duplicating of copyrighted music without explicit
|
||||
permission violates the rights of the owner.
|
||||
|
||||
SENDING PATCHES:
|
||||
The current version is under LGPL. Please consider this when sending patches or
|
||||
changes. I also want to have the freedom to sell the code to companies that
|
||||
cannot or do not want to use the code under LGPL. So, if you send me
|
||||
significant patches, I need your explicit permission to do this. Of course,
|
||||
there will always be the LGPLed open source version of the 100% same code.
|
||||
In the case you cannot accept this: the code is free, it's your freedom
|
||||
to distribute your changes again under LGPL.
|
||||
|
||||
FEEDBACK:
|
||||
I'm interessted to here from you, when you use this package as part
|
||||
of another project.
|
||||
|
||||
|
@ -1,226 +0,0 @@
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "mpg123.h"
|
||||
#include "mpglib.h"
|
||||
|
||||
int tabsel_123[2][3][16] = {
|
||||
{ {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,},
|
||||
{0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,},
|
||||
{0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} },
|
||||
|
||||
{ {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,},
|
||||
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,},
|
||||
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} }
|
||||
};
|
||||
|
||||
long freqs[9] = { 44100, 48000, 32000,
|
||||
22050, 24000, 16000 ,
|
||||
11025 , 12000 , 8000 };
|
||||
|
||||
#define HDRCMPMASK 0xfffffd00
|
||||
|
||||
#if 0
|
||||
int head_check(unsigned long head)
|
||||
{
|
||||
if( (head & 0xffe00000) != 0xffe00000)
|
||||
return FALSE;
|
||||
if(!((head>>17)&3))
|
||||
return FALSE;
|
||||
if( ((head>>12)&0xf) == 0xf)
|
||||
return FALSE;
|
||||
if( ((head>>10)&0x3) == 0x3 )
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* the code a header and write the information
|
||||
* into the frame structure
|
||||
*/
|
||||
int decode_header(struct frame *fr,unsigned long newhead)
|
||||
{
|
||||
if( newhead & (1<<20) ) {
|
||||
fr->lsf = (newhead & (1<<19)) ? 0x0 : 0x1;
|
||||
fr->mpeg25 = 0;
|
||||
}
|
||||
else {
|
||||
fr->lsf = 1;
|
||||
fr->mpeg25 = 1;
|
||||
}
|
||||
|
||||
fr->lay = 4-((newhead>>17)&3);
|
||||
if( ((newhead>>10)&0x3) == 0x3) {
|
||||
fprintf(stderr,"Stream error, reserved sampling rate\n");
|
||||
return 0;
|
||||
}
|
||||
if(fr->mpeg25) {
|
||||
fr->sampling_frequency = 6 + ((newhead>>10)&0x3);
|
||||
}
|
||||
else
|
||||
fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3);
|
||||
fr->error_protection = ((newhead>>16)&0x1)^0x1;
|
||||
|
||||
if(fr->mpeg25) /* allow Bitrate change for 2.5 ... */
|
||||
fr->bitrate_index = ((newhead>>12)&0xf);
|
||||
|
||||
fr->bitrate_index = ((newhead>>12)&0xf);
|
||||
fr->padding = ((newhead>>9)&0x1);
|
||||
fr->extension = ((newhead>>8)&0x1);
|
||||
fr->mode = ((newhead>>6)&0x3);
|
||||
fr->mode_ext = ((newhead>>4)&0x3);
|
||||
fr->copyright = ((newhead>>3)&0x1);
|
||||
fr->original = ((newhead>>2)&0x1);
|
||||
fr->emphasis = newhead & 0x3;
|
||||
|
||||
fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2;
|
||||
|
||||
if(!fr->bitrate_index)
|
||||
{
|
||||
fprintf(stderr, "Stream error, free format bitrate index not supported\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(fr->lay)
|
||||
{
|
||||
case 1:
|
||||
#if 0
|
||||
fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ?
|
||||
(fr->mode_ext<<2)+4 : 32;
|
||||
#endif
|
||||
fr->framesize = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000;
|
||||
fr->framesize /= freqs[fr->sampling_frequency];
|
||||
fr->framesize = ((fr->framesize+fr->padding)<<2)-4;
|
||||
break;
|
||||
case 2:
|
||||
#if 0
|
||||
fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ?
|
||||
(fr->mode_ext<<2)+4 : fr->II_sblimit;
|
||||
#endif
|
||||
fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000;
|
||||
fr->framesize /= freqs[fr->sampling_frequency];
|
||||
fr->framesize += fr->padding - 4;
|
||||
break;
|
||||
case 3:
|
||||
#if 0
|
||||
fr->do_layer = do_layer3;
|
||||
if(fr->lsf)
|
||||
ssize = (fr->stereo == 1) ? 9 : 17;
|
||||
else
|
||||
ssize = (fr->stereo == 1) ? 17 : 32;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if(fr->error_protection)
|
||||
ssize += 2;
|
||||
#endif
|
||||
fr->framesize = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000;
|
||||
fr->framesize /= freqs[fr->sampling_frequency]<<(fr->lsf);
|
||||
fr->framesize = fr->framesize + fr->padding - 4;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Stream error, unknown layer type.\n");
|
||||
return (0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void print_header(struct frame *fr)
|
||||
{
|
||||
static char *modes[4] = { "Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel" };
|
||||
static char *layers[4] = { "Unknown" , "I", "II", "III" };
|
||||
|
||||
fprintf(stderr,"MPEG %s, Layer: %s, Freq: %ld, mode: %s, modext: %d, BPF : %d\n",
|
||||
fr->mpeg25 ? "2.5" : (fr->lsf ? "2.0" : "1.0"),
|
||||
layers[fr->lay],freqs[fr->sampling_frequency],
|
||||
modes[fr->mode],fr->mode_ext,fr->framesize+4);
|
||||
fprintf(stderr,"Channels: %d, copyright: %s, original: %s, CRC: %s, emphasis: %d.\n",
|
||||
fr->stereo,fr->copyright?"Yes":"No",
|
||||
fr->original?"Yes":"No",fr->error_protection?"Yes":"No",
|
||||
fr->emphasis);
|
||||
fprintf(stderr,"Bitrate: %d Kbits/s, Extension value: %d\n",
|
||||
tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index],fr->extension);
|
||||
}
|
||||
|
||||
void print_header_compact(struct frame *fr)
|
||||
{
|
||||
static char *modes[4] = { "stereo", "joint-stereo", "dual-channel", "mono" };
|
||||
static char *layers[4] = { "Unknown" , "I", "II", "III" };
|
||||
|
||||
fprintf(stderr,"MPEG %s layer %s, %d kbit/s, %ld Hz %s\n",
|
||||
fr->mpeg25 ? "2.5" : (fr->lsf ? "2.0" : "1.0"),
|
||||
layers[fr->lay],
|
||||
tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index],
|
||||
freqs[fr->sampling_frequency], modes[fr->mode]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
unsigned int getbits(struct mpstr *mp, int number_of_bits)
|
||||
{
|
||||
unsigned long rval;
|
||||
|
||||
if(!number_of_bits)
|
||||
return 0;
|
||||
|
||||
{
|
||||
rval = mp->wordpointer[0];
|
||||
rval <<= 8;
|
||||
rval |= mp->wordpointer[1];
|
||||
rval <<= 8;
|
||||
rval |= mp->wordpointer[2];
|
||||
rval <<= mp->bitindex;
|
||||
rval &= 0xffffff;
|
||||
|
||||
mp->bitindex += number_of_bits;
|
||||
|
||||
rval >>= (24-number_of_bits);
|
||||
|
||||
mp->wordpointer += (mp->bitindex>>3);
|
||||
mp->bitindex &= 7;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
unsigned int getbits_fast(struct mpstr *mp, int number_of_bits)
|
||||
{
|
||||
unsigned long rval;
|
||||
|
||||
{
|
||||
rval = mp->wordpointer[0];
|
||||
rval <<= 8;
|
||||
rval |= mp->wordpointer[1];
|
||||
rval <<= mp->bitindex;
|
||||
rval &= 0xffff;
|
||||
mp->bitindex += number_of_bits;
|
||||
|
||||
rval >>= (16-number_of_bits);
|
||||
|
||||
mp->wordpointer += (mp->bitindex>>3);
|
||||
mp->bitindex &= 7;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
unsigned int get1bit(struct mpstr *mp)
|
||||
{
|
||||
unsigned char rval;
|
||||
rval = *mp->wordpointer << mp->bitindex;
|
||||
|
||||
mp->bitindex++;
|
||||
mp->wordpointer += (mp->bitindex>>3);
|
||||
mp->bitindex &= 7;
|
||||
|
||||
return rval>>7;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,315 +0,0 @@
|
||||
|
||||
/*
|
||||
* Discrete Cosine Tansform (DCT) for subband synthesis
|
||||
* optimized for machines with no auto-increment.
|
||||
* The performance is highly compiler dependend. Maybe
|
||||
* the dct64.c version for 'normal' processor may be faster
|
||||
* even for Intel processors.
|
||||
*/
|
||||
|
||||
#include "mpg123.h"
|
||||
|
||||
static void dct64_1(real *out0,real *out1,real *b1,real *b2,real *samples)
|
||||
{
|
||||
|
||||
{
|
||||
register real *costab = pnts[0];
|
||||
|
||||
b1[0x00] = samples[0x00] + samples[0x1F];
|
||||
b1[0x1F] = (samples[0x00] - samples[0x1F]) * costab[0x0];
|
||||
|
||||
b1[0x01] = samples[0x01] + samples[0x1E];
|
||||
b1[0x1E] = (samples[0x01] - samples[0x1E]) * costab[0x1];
|
||||
|
||||
b1[0x02] = samples[0x02] + samples[0x1D];
|
||||
b1[0x1D] = (samples[0x02] - samples[0x1D]) * costab[0x2];
|
||||
|
||||
b1[0x03] = samples[0x03] + samples[0x1C];
|
||||
b1[0x1C] = (samples[0x03] - samples[0x1C]) * costab[0x3];
|
||||
|
||||
b1[0x04] = samples[0x04] + samples[0x1B];
|
||||
b1[0x1B] = (samples[0x04] - samples[0x1B]) * costab[0x4];
|
||||
|
||||
b1[0x05] = samples[0x05] + samples[0x1A];
|
||||
b1[0x1A] = (samples[0x05] - samples[0x1A]) * costab[0x5];
|
||||
|
||||
b1[0x06] = samples[0x06] + samples[0x19];
|
||||
b1[0x19] = (samples[0x06] - samples[0x19]) * costab[0x6];
|
||||
|
||||
b1[0x07] = samples[0x07] + samples[0x18];
|
||||
b1[0x18] = (samples[0x07] - samples[0x18]) * costab[0x7];
|
||||
|
||||
b1[0x08] = samples[0x08] + samples[0x17];
|
||||
b1[0x17] = (samples[0x08] - samples[0x17]) * costab[0x8];
|
||||
|
||||
b1[0x09] = samples[0x09] + samples[0x16];
|
||||
b1[0x16] = (samples[0x09] - samples[0x16]) * costab[0x9];
|
||||
|
||||
b1[0x0A] = samples[0x0A] + samples[0x15];
|
||||
b1[0x15] = (samples[0x0A] - samples[0x15]) * costab[0xA];
|
||||
|
||||
b1[0x0B] = samples[0x0B] + samples[0x14];
|
||||
b1[0x14] = (samples[0x0B] - samples[0x14]) * costab[0xB];
|
||||
|
||||
b1[0x0C] = samples[0x0C] + samples[0x13];
|
||||
b1[0x13] = (samples[0x0C] - samples[0x13]) * costab[0xC];
|
||||
|
||||
b1[0x0D] = samples[0x0D] + samples[0x12];
|
||||
b1[0x12] = (samples[0x0D] - samples[0x12]) * costab[0xD];
|
||||
|
||||
b1[0x0E] = samples[0x0E] + samples[0x11];
|
||||
b1[0x11] = (samples[0x0E] - samples[0x11]) * costab[0xE];
|
||||
|
||||
b1[0x0F] = samples[0x0F] + samples[0x10];
|
||||
b1[0x10] = (samples[0x0F] - samples[0x10]) * costab[0xF];
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
register real *costab = pnts[1];
|
||||
|
||||
b2[0x00] = b1[0x00] + b1[0x0F];
|
||||
b2[0x0F] = (b1[0x00] - b1[0x0F]) * costab[0];
|
||||
b2[0x01] = b1[0x01] + b1[0x0E];
|
||||
b2[0x0E] = (b1[0x01] - b1[0x0E]) * costab[1];
|
||||
b2[0x02] = b1[0x02] + b1[0x0D];
|
||||
b2[0x0D] = (b1[0x02] - b1[0x0D]) * costab[2];
|
||||
b2[0x03] = b1[0x03] + b1[0x0C];
|
||||
b2[0x0C] = (b1[0x03] - b1[0x0C]) * costab[3];
|
||||
b2[0x04] = b1[0x04] + b1[0x0B];
|
||||
b2[0x0B] = (b1[0x04] - b1[0x0B]) * costab[4];
|
||||
b2[0x05] = b1[0x05] + b1[0x0A];
|
||||
b2[0x0A] = (b1[0x05] - b1[0x0A]) * costab[5];
|
||||
b2[0x06] = b1[0x06] + b1[0x09];
|
||||
b2[0x09] = (b1[0x06] - b1[0x09]) * costab[6];
|
||||
b2[0x07] = b1[0x07] + b1[0x08];
|
||||
b2[0x08] = (b1[0x07] - b1[0x08]) * costab[7];
|
||||
|
||||
b2[0x10] = b1[0x10] + b1[0x1F];
|
||||
b2[0x1F] = (b1[0x1F] - b1[0x10]) * costab[0];
|
||||
b2[0x11] = b1[0x11] + b1[0x1E];
|
||||
b2[0x1E] = (b1[0x1E] - b1[0x11]) * costab[1];
|
||||
b2[0x12] = b1[0x12] + b1[0x1D];
|
||||
b2[0x1D] = (b1[0x1D] - b1[0x12]) * costab[2];
|
||||
b2[0x13] = b1[0x13] + b1[0x1C];
|
||||
b2[0x1C] = (b1[0x1C] - b1[0x13]) * costab[3];
|
||||
b2[0x14] = b1[0x14] + b1[0x1B];
|
||||
b2[0x1B] = (b1[0x1B] - b1[0x14]) * costab[4];
|
||||
b2[0x15] = b1[0x15] + b1[0x1A];
|
||||
b2[0x1A] = (b1[0x1A] - b1[0x15]) * costab[5];
|
||||
b2[0x16] = b1[0x16] + b1[0x19];
|
||||
b2[0x19] = (b1[0x19] - b1[0x16]) * costab[6];
|
||||
b2[0x17] = b1[0x17] + b1[0x18];
|
||||
b2[0x18] = (b1[0x18] - b1[0x17]) * costab[7];
|
||||
}
|
||||
|
||||
{
|
||||
register real *costab = pnts[2];
|
||||
|
||||
b1[0x00] = b2[0x00] + b2[0x07];
|
||||
b1[0x07] = (b2[0x00] - b2[0x07]) * costab[0];
|
||||
b1[0x01] = b2[0x01] + b2[0x06];
|
||||
b1[0x06] = (b2[0x01] - b2[0x06]) * costab[1];
|
||||
b1[0x02] = b2[0x02] + b2[0x05];
|
||||
b1[0x05] = (b2[0x02] - b2[0x05]) * costab[2];
|
||||
b1[0x03] = b2[0x03] + b2[0x04];
|
||||
b1[0x04] = (b2[0x03] - b2[0x04]) * costab[3];
|
||||
|
||||
b1[0x08] = b2[0x08] + b2[0x0F];
|
||||
b1[0x0F] = (b2[0x0F] - b2[0x08]) * costab[0];
|
||||
b1[0x09] = b2[0x09] + b2[0x0E];
|
||||
b1[0x0E] = (b2[0x0E] - b2[0x09]) * costab[1];
|
||||
b1[0x0A] = b2[0x0A] + b2[0x0D];
|
||||
b1[0x0D] = (b2[0x0D] - b2[0x0A]) * costab[2];
|
||||
b1[0x0B] = b2[0x0B] + b2[0x0C];
|
||||
b1[0x0C] = (b2[0x0C] - b2[0x0B]) * costab[3];
|
||||
|
||||
b1[0x10] = b2[0x10] + b2[0x17];
|
||||
b1[0x17] = (b2[0x10] - b2[0x17]) * costab[0];
|
||||
b1[0x11] = b2[0x11] + b2[0x16];
|
||||
b1[0x16] = (b2[0x11] - b2[0x16]) * costab[1];
|
||||
b1[0x12] = b2[0x12] + b2[0x15];
|
||||
b1[0x15] = (b2[0x12] - b2[0x15]) * costab[2];
|
||||
b1[0x13] = b2[0x13] + b2[0x14];
|
||||
b1[0x14] = (b2[0x13] - b2[0x14]) * costab[3];
|
||||
|
||||
b1[0x18] = b2[0x18] + b2[0x1F];
|
||||
b1[0x1F] = (b2[0x1F] - b2[0x18]) * costab[0];
|
||||
b1[0x19] = b2[0x19] + b2[0x1E];
|
||||
b1[0x1E] = (b2[0x1E] - b2[0x19]) * costab[1];
|
||||
b1[0x1A] = b2[0x1A] + b2[0x1D];
|
||||
b1[0x1D] = (b2[0x1D] - b2[0x1A]) * costab[2];
|
||||
b1[0x1B] = b2[0x1B] + b2[0x1C];
|
||||
b1[0x1C] = (b2[0x1C] - b2[0x1B]) * costab[3];
|
||||
}
|
||||
|
||||
{
|
||||
register real const cos0 = pnts[3][0];
|
||||
register real const cos1 = pnts[3][1];
|
||||
|
||||
b2[0x00] = b1[0x00] + b1[0x03];
|
||||
b2[0x03] = (b1[0x00] - b1[0x03]) * cos0;
|
||||
b2[0x01] = b1[0x01] + b1[0x02];
|
||||
b2[0x02] = (b1[0x01] - b1[0x02]) * cos1;
|
||||
|
||||
b2[0x04] = b1[0x04] + b1[0x07];
|
||||
b2[0x07] = (b1[0x07] - b1[0x04]) * cos0;
|
||||
b2[0x05] = b1[0x05] + b1[0x06];
|
||||
b2[0x06] = (b1[0x06] - b1[0x05]) * cos1;
|
||||
|
||||
b2[0x08] = b1[0x08] + b1[0x0B];
|
||||
b2[0x0B] = (b1[0x08] - b1[0x0B]) * cos0;
|
||||
b2[0x09] = b1[0x09] + b1[0x0A];
|
||||
b2[0x0A] = (b1[0x09] - b1[0x0A]) * cos1;
|
||||
|
||||
b2[0x0C] = b1[0x0C] + b1[0x0F];
|
||||
b2[0x0F] = (b1[0x0F] - b1[0x0C]) * cos0;
|
||||
b2[0x0D] = b1[0x0D] + b1[0x0E];
|
||||
b2[0x0E] = (b1[0x0E] - b1[0x0D]) * cos1;
|
||||
|
||||
b2[0x10] = b1[0x10] + b1[0x13];
|
||||
b2[0x13] = (b1[0x10] - b1[0x13]) * cos0;
|
||||
b2[0x11] = b1[0x11] + b1[0x12];
|
||||
b2[0x12] = (b1[0x11] - b1[0x12]) * cos1;
|
||||
|
||||
b2[0x14] = b1[0x14] + b1[0x17];
|
||||
b2[0x17] = (b1[0x17] - b1[0x14]) * cos0;
|
||||
b2[0x15] = b1[0x15] + b1[0x16];
|
||||
b2[0x16] = (b1[0x16] - b1[0x15]) * cos1;
|
||||
|
||||
b2[0x18] = b1[0x18] + b1[0x1B];
|
||||
b2[0x1B] = (b1[0x18] - b1[0x1B]) * cos0;
|
||||
b2[0x19] = b1[0x19] + b1[0x1A];
|
||||
b2[0x1A] = (b1[0x19] - b1[0x1A]) * cos1;
|
||||
|
||||
b2[0x1C] = b1[0x1C] + b1[0x1F];
|
||||
b2[0x1F] = (b1[0x1F] - b1[0x1C]) * cos0;
|
||||
b2[0x1D] = b1[0x1D] + b1[0x1E];
|
||||
b2[0x1E] = (b1[0x1E] - b1[0x1D]) * cos1;
|
||||
}
|
||||
|
||||
{
|
||||
register real const cos0 = pnts[4][0];
|
||||
|
||||
b1[0x00] = b2[0x00] + b2[0x01];
|
||||
b1[0x01] = (b2[0x00] - b2[0x01]) * cos0;
|
||||
b1[0x02] = b2[0x02] + b2[0x03];
|
||||
b1[0x03] = (b2[0x03] - b2[0x02]) * cos0;
|
||||
b1[0x02] += b1[0x03];
|
||||
|
||||
b1[0x04] = b2[0x04] + b2[0x05];
|
||||
b1[0x05] = (b2[0x04] - b2[0x05]) * cos0;
|
||||
b1[0x06] = b2[0x06] + b2[0x07];
|
||||
b1[0x07] = (b2[0x07] - b2[0x06]) * cos0;
|
||||
b1[0x06] += b1[0x07];
|
||||
b1[0x04] += b1[0x06];
|
||||
b1[0x06] += b1[0x05];
|
||||
b1[0x05] += b1[0x07];
|
||||
|
||||
b1[0x08] = b2[0x08] + b2[0x09];
|
||||
b1[0x09] = (b2[0x08] - b2[0x09]) * cos0;
|
||||
b1[0x0A] = b2[0x0A] + b2[0x0B];
|
||||
b1[0x0B] = (b2[0x0B] - b2[0x0A]) * cos0;
|
||||
b1[0x0A] += b1[0x0B];
|
||||
|
||||
b1[0x0C] = b2[0x0C] + b2[0x0D];
|
||||
b1[0x0D] = (b2[0x0C] - b2[0x0D]) * cos0;
|
||||
b1[0x0E] = b2[0x0E] + b2[0x0F];
|
||||
b1[0x0F] = (b2[0x0F] - b2[0x0E]) * cos0;
|
||||
b1[0x0E] += b1[0x0F];
|
||||
b1[0x0C] += b1[0x0E];
|
||||
b1[0x0E] += b1[0x0D];
|
||||
b1[0x0D] += b1[0x0F];
|
||||
|
||||
b1[0x10] = b2[0x10] + b2[0x11];
|
||||
b1[0x11] = (b2[0x10] - b2[0x11]) * cos0;
|
||||
b1[0x12] = b2[0x12] + b2[0x13];
|
||||
b1[0x13] = (b2[0x13] - b2[0x12]) * cos0;
|
||||
b1[0x12] += b1[0x13];
|
||||
|
||||
b1[0x14] = b2[0x14] + b2[0x15];
|
||||
b1[0x15] = (b2[0x14] - b2[0x15]) * cos0;
|
||||
b1[0x16] = b2[0x16] + b2[0x17];
|
||||
b1[0x17] = (b2[0x17] - b2[0x16]) * cos0;
|
||||
b1[0x16] += b1[0x17];
|
||||
b1[0x14] += b1[0x16];
|
||||
b1[0x16] += b1[0x15];
|
||||
b1[0x15] += b1[0x17];
|
||||
|
||||
b1[0x18] = b2[0x18] + b2[0x19];
|
||||
b1[0x19] = (b2[0x18] - b2[0x19]) * cos0;
|
||||
b1[0x1A] = b2[0x1A] + b2[0x1B];
|
||||
b1[0x1B] = (b2[0x1B] - b2[0x1A]) * cos0;
|
||||
b1[0x1A] += b1[0x1B];
|
||||
|
||||
b1[0x1C] = b2[0x1C] + b2[0x1D];
|
||||
b1[0x1D] = (b2[0x1C] - b2[0x1D]) * cos0;
|
||||
b1[0x1E] = b2[0x1E] + b2[0x1F];
|
||||
b1[0x1F] = (b2[0x1F] - b2[0x1E]) * cos0;
|
||||
b1[0x1E] += b1[0x1F];
|
||||
b1[0x1C] += b1[0x1E];
|
||||
b1[0x1E] += b1[0x1D];
|
||||
b1[0x1D] += b1[0x1F];
|
||||
}
|
||||
|
||||
out0[0x10*16] = b1[0x00];
|
||||
out0[0x10*12] = b1[0x04];
|
||||
out0[0x10* 8] = b1[0x02];
|
||||
out0[0x10* 4] = b1[0x06];
|
||||
out0[0x10* 0] = b1[0x01];
|
||||
out1[0x10* 0] = b1[0x01];
|
||||
out1[0x10* 4] = b1[0x05];
|
||||
out1[0x10* 8] = b1[0x03];
|
||||
out1[0x10*12] = b1[0x07];
|
||||
|
||||
b1[0x08] += b1[0x0C];
|
||||
out0[0x10*14] = b1[0x08];
|
||||
b1[0x0C] += b1[0x0a];
|
||||
out0[0x10*10] = b1[0x0C];
|
||||
b1[0x0A] += b1[0x0E];
|
||||
out0[0x10* 6] = b1[0x0A];
|
||||
b1[0x0E] += b1[0x09];
|
||||
out0[0x10* 2] = b1[0x0E];
|
||||
b1[0x09] += b1[0x0D];
|
||||
out1[0x10* 2] = b1[0x09];
|
||||
b1[0x0D] += b1[0x0B];
|
||||
out1[0x10* 6] = b1[0x0D];
|
||||
b1[0x0B] += b1[0x0F];
|
||||
out1[0x10*10] = b1[0x0B];
|
||||
out1[0x10*14] = b1[0x0F];
|
||||
|
||||
b1[0x18] += b1[0x1C];
|
||||
out0[0x10*15] = b1[0x10] + b1[0x18];
|
||||
out0[0x10*13] = b1[0x18] + b1[0x14];
|
||||
b1[0x1C] += b1[0x1a];
|
||||
out0[0x10*11] = b1[0x14] + b1[0x1C];
|
||||
out0[0x10* 9] = b1[0x1C] + b1[0x12];
|
||||
b1[0x1A] += b1[0x1E];
|
||||
out0[0x10* 7] = b1[0x12] + b1[0x1A];
|
||||
out0[0x10* 5] = b1[0x1A] + b1[0x16];
|
||||
b1[0x1E] += b1[0x19];
|
||||
out0[0x10* 3] = b1[0x16] + b1[0x1E];
|
||||
out0[0x10* 1] = b1[0x1E] + b1[0x11];
|
||||
b1[0x19] += b1[0x1D];
|
||||
out1[0x10* 1] = b1[0x11] + b1[0x19];
|
||||
out1[0x10* 3] = b1[0x19] + b1[0x15];
|
||||
b1[0x1D] += b1[0x1B];
|
||||
out1[0x10* 5] = b1[0x15] + b1[0x1D];
|
||||
out1[0x10* 7] = b1[0x1D] + b1[0x13];
|
||||
b1[0x1B] += b1[0x1F];
|
||||
out1[0x10* 9] = b1[0x13] + b1[0x1B];
|
||||
out1[0x10*11] = b1[0x1B] + b1[0x17];
|
||||
out1[0x10*13] = b1[0x17] + b1[0x1F];
|
||||
out1[0x10*15] = b1[0x1F];
|
||||
}
|
||||
|
||||
/*
|
||||
* the call via dct64 is a trick to force GCC to use
|
||||
* (new) registers for the b1,b2 pointer to the bufs[xx] field
|
||||
*/
|
||||
void dct64(real *a,real *b,real *c)
|
||||
{
|
||||
real bufs[0x40];
|
||||
dct64_1(a,b,bufs,bufs+0x20,c);
|
||||
}
|
||||
|
@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Mpeg Layer-1,2,3 audio decoder
|
||||
* ------------------------------
|
||||
* copyright (c) 1995,1996,1997 by Michael Hipp, All rights reserved.
|
||||
* See also 'README'
|
||||
*
|
||||
* slighlty optimized for machines without autoincrement/decrement.
|
||||
* The performance is highly compiler dependend. Maybe
|
||||
* the decode.c version for 'normal' processor may be faster
|
||||
* even for Intel processors.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpg123.h"
|
||||
#include "mpglib.h"
|
||||
|
||||
/* old WRITE_SAMPLE */
|
||||
#define WRITE_SAMPLE(samples,sum,clip) \
|
||||
if( (sum) > 32767.0) { *(samples) = 0x7fff; (clip)++; } \
|
||||
else if( (sum) < -32768.0) { *(samples) = -0x8000; (clip)++; } \
|
||||
else { *(samples) = sum; }
|
||||
|
||||
int synth_1to1_mono(struct mpstr *mp, real *bandPtr,unsigned char *samples,int *pnt)
|
||||
{
|
||||
short samples_tmp[64];
|
||||
short *tmp1 = samples_tmp;
|
||||
int i,ret;
|
||||
int pnt1 = 0;
|
||||
|
||||
ret = synth_1to1(mp, bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
|
||||
samples += *pnt;
|
||||
|
||||
for(i=0;i<32;i++) {
|
||||
*( (short *) samples) = *tmp1;
|
||||
samples += 2;
|
||||
tmp1 += 2;
|
||||
}
|
||||
*pnt += 64;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int synth_1to1(struct mpstr *mp, real *bandPtr,int channel,unsigned char *out,int *pnt)
|
||||
{
|
||||
static const int step = 2;
|
||||
int bo;
|
||||
short *samples = (short *) (out + *pnt);
|
||||
|
||||
real *b0,(*buf)[0x110];
|
||||
int clip = 0;
|
||||
int bo1;
|
||||
|
||||
bo = mp->synth_bo;
|
||||
|
||||
if(!channel) {
|
||||
bo--;
|
||||
bo &= 0xf;
|
||||
buf = mp->synth_buffs[0];
|
||||
}
|
||||
else {
|
||||
samples++;
|
||||
buf = mp->synth_buffs[1];
|
||||
}
|
||||
|
||||
if(bo & 0x1) {
|
||||
b0 = buf[0];
|
||||
bo1 = bo;
|
||||
dct64(buf[1]+((bo+1)&0xf),buf[0]+bo,bandPtr);
|
||||
}
|
||||
else {
|
||||
b0 = buf[1];
|
||||
bo1 = bo+1;
|
||||
dct64(buf[0]+bo,buf[1]+bo+1,bandPtr);
|
||||
}
|
||||
|
||||
mp->synth_bo = bo;
|
||||
|
||||
{
|
||||
register int j;
|
||||
real *window = decwin + 16 - bo1;
|
||||
|
||||
for (j=16;j;j--,b0+=0x10,window+=0x20,samples+=step)
|
||||
{
|
||||
real sum;
|
||||
sum = window[0x0] * b0[0x0];
|
||||
sum -= window[0x1] * b0[0x1];
|
||||
sum += window[0x2] * b0[0x2];
|
||||
sum -= window[0x3] * b0[0x3];
|
||||
sum += window[0x4] * b0[0x4];
|
||||
sum -= window[0x5] * b0[0x5];
|
||||
sum += window[0x6] * b0[0x6];
|
||||
sum -= window[0x7] * b0[0x7];
|
||||
sum += window[0x8] * b0[0x8];
|
||||
sum -= window[0x9] * b0[0x9];
|
||||
sum += window[0xA] * b0[0xA];
|
||||
sum -= window[0xB] * b0[0xB];
|
||||
sum += window[0xC] * b0[0xC];
|
||||
sum -= window[0xD] * b0[0xD];
|
||||
sum += window[0xE] * b0[0xE];
|
||||
sum -= window[0xF] * b0[0xF];
|
||||
|
||||
WRITE_SAMPLE(samples,sum,clip);
|
||||
}
|
||||
|
||||
{
|
||||
real sum;
|
||||
sum = window[0x0] * b0[0x0];
|
||||
sum += window[0x2] * b0[0x2];
|
||||
sum += window[0x4] * b0[0x4];
|
||||
sum += window[0x6] * b0[0x6];
|
||||
sum += window[0x8] * b0[0x8];
|
||||
sum += window[0xA] * b0[0xA];
|
||||
sum += window[0xC] * b0[0xC];
|
||||
sum += window[0xE] * b0[0xE];
|
||||
WRITE_SAMPLE(samples,sum,clip);
|
||||
b0-=0x10,window-=0x20,samples+=step;
|
||||
}
|
||||
window += bo1<<1;
|
||||
|
||||
for (j=15;j;j--,b0-=0x10,window-=0x20,samples+=step)
|
||||
{
|
||||
real sum;
|
||||
sum = -window[-0x1] * b0[0x0];
|
||||
sum -= window[-0x2] * b0[0x1];
|
||||
sum -= window[-0x3] * b0[0x2];
|
||||
sum -= window[-0x4] * b0[0x3];
|
||||
sum -= window[-0x5] * b0[0x4];
|
||||
sum -= window[-0x6] * b0[0x5];
|
||||
sum -= window[-0x7] * b0[0x6];
|
||||
sum -= window[-0x8] * b0[0x7];
|
||||
sum -= window[-0x9] * b0[0x8];
|
||||
sum -= window[-0xA] * b0[0x9];
|
||||
sum -= window[-0xB] * b0[0xA];
|
||||
sum -= window[-0xC] * b0[0xB];
|
||||
sum -= window[-0xD] * b0[0xC];
|
||||
sum -= window[-0xE] * b0[0xD];
|
||||
sum -= window[-0xF] * b0[0xE];
|
||||
sum -= window[-0x0] * b0[0xF];
|
||||
|
||||
WRITE_SAMPLE(samples,sum,clip);
|
||||
}
|
||||
}
|
||||
*pnt += 128;
|
||||
|
||||
return clip;
|
||||
}
|
||||
|
@ -1,332 +0,0 @@
|
||||
/*
|
||||
* huffman tables ... recalcualted to work with my optimzed
|
||||
* decoder scheme (MH)
|
||||
*
|
||||
* probably we could save a few bytes of memory, because the
|
||||
* smaller tables are often the part of a bigger table
|
||||
*/
|
||||
|
||||
struct newhuff
|
||||
{
|
||||
unsigned int linbits;
|
||||
short *table;
|
||||
};
|
||||
|
||||
static short tab0[] =
|
||||
{
|
||||
0
|
||||
};
|
||||
|
||||
static short tab1[] =
|
||||
{
|
||||
-5, -3, -1, 17, 1, 16, 0
|
||||
};
|
||||
|
||||
static short tab2[] =
|
||||
{
|
||||
-15, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 17, -1, 1,
|
||||
16, 0
|
||||
};
|
||||
|
||||
static short tab3[] =
|
||||
{
|
||||
-13, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 16, 17, -1,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static short tab5[] =
|
||||
{
|
||||
-29, -25, -23, -15, -7, -5, -3, -1, 51, 35, 50, 49, -3, -1, 19,
|
||||
3, -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, 17, -1, 1, 16,
|
||||
0
|
||||
};
|
||||
|
||||
static short tab6[] =
|
||||
{
|
||||
-25, -19, -13, -9, -5, -3, -1, 51, 3, 35, -1, 50, 48, -1, 19,
|
||||
49, -3, -1, 34, 2, 18, -3, -1, 33, 32, 1, -1, 17, -1, 16,
|
||||
0
|
||||
};
|
||||
|
||||
static short tab7[] =
|
||||
{
|
||||
-69, -65, -57, -39, -29, -17, -11, -7, -3, -1, 85, 69, -1, 84, 83,
|
||||
-1, 53, 68, -3, -1, 37, 82, 21, -5, -1, 81, -1, 5, 52, -1,
|
||||
80, -1, 67, 51, -5, -3, -1, 36, 66, 20, -1, 65, 64, -11, -7,
|
||||
-3, -1, 4, 35, -1, 50, 3, -1, 19, 49, -3, -1, 48, 34, 18,
|
||||
-5, -1, 33, -1, 2, 32, 17, -1, 1, 16, 0
|
||||
};
|
||||
|
||||
static short tab8[] =
|
||||
{
|
||||
-65, -63, -59, -45, -31, -19, -13, -7, -5, -3, -1, 85, 84, 69, 83,
|
||||
-3, -1, 53, 68, 37, -3, -1, 82, 5, 21, -5, -1, 81, -1, 52,
|
||||
67, -3, -1, 80, 51, 36, -5, -3, -1, 66, 20, 65, -3, -1, 4,
|
||||
64, -1, 35, 50, -9, -7, -3, -1, 19, 49, -1, 3, 48, 34, -1,
|
||||
2, 32, -1, 18, 33, 17, -3, -1, 1, 16, 0
|
||||
};
|
||||
|
||||
static short tab9[] =
|
||||
{
|
||||
-63, -53, -41, -29, -19, -11, -5, -3, -1, 85, 69, 53, -1, 83, -1,
|
||||
84, 5, -3, -1, 68, 37, -1, 82, 21, -3, -1, 81, 52, -1, 67,
|
||||
-1, 80, 4, -7, -3, -1, 36, 66, -1, 51, 64, -1, 20, 65, -5,
|
||||
-3, -1, 35, 50, 19, -1, 49, -1, 3, 48, -5, -3, -1, 34, 2,
|
||||
18, -1, 33, 32, -3, -1, 17, 1, -1, 16, 0
|
||||
};
|
||||
|
||||
static short tab10[] =
|
||||
{
|
||||
-125,-121,-111, -83, -55, -35, -21, -13, -7, -3, -1, 119, 103, -1, 118,
|
||||
87, -3, -1, 117, 102, 71, -3, -1, 116, 86, -1, 101, 55, -9, -3,
|
||||
-1, 115, 70, -3, -1, 85, 84, 99, -1, 39, 114, -11, -5, -3, -1,
|
||||
100, 7, 112, -1, 98, -1, 69, 53, -5, -1, 6, -1, 83, 68, 23,
|
||||
-17, -5, -1, 113, -1, 54, 38, -5, -3, -1, 37, 82, 21, -1, 81,
|
||||
-1, 52, 67, -3, -1, 22, 97, -1, 96, -1, 5, 80, -19, -11, -7,
|
||||
-3, -1, 36, 66, -1, 51, 4, -1, 20, 65, -3, -1, 64, 35, -1,
|
||||
50, 3, -3, -1, 19, 49, -1, 48, 34, -7, -3, -1, 18, 33, -1,
|
||||
2, 32, 17, -1, 1, 16, 0
|
||||
};
|
||||
|
||||
static short tab11[] =
|
||||
{
|
||||
-121,-113, -89, -59, -43, -27, -17, -7, -3, -1, 119, 103, -1, 118, 117,
|
||||
-3, -1, 102, 71, -1, 116, -1, 87, 85, -5, -3, -1, 86, 101, 55,
|
||||
-1, 115, 70, -9, -7, -3, -1, 69, 84, -1, 53, 83, 39, -1, 114,
|
||||
-1, 100, 7, -5, -1, 113, -1, 23, 112, -3, -1, 54, 99, -1, 96,
|
||||
-1, 68, 37, -13, -7, -5, -3, -1, 82, 5, 21, 98, -3, -1, 38,
|
||||
6, 22, -5, -1, 97, -1, 81, 52, -5, -1, 80, -1, 67, 51, -1,
|
||||
36, 66, -15, -11, -7, -3, -1, 20, 65, -1, 4, 64, -1, 35, 50,
|
||||
-1, 19, 49, -5, -3, -1, 3, 48, 34, 33, -5, -1, 18, -1, 2,
|
||||
32, 17, -3, -1, 1, 16, 0
|
||||
};
|
||||
|
||||
static short tab12[] =
|
||||
{
|
||||
-115, -99, -73, -45, -27, -17, -9, -5, -3, -1, 119, 103, 118, -1, 87,
|
||||
117, -3, -1, 102, 71, -1, 116, 101, -3, -1, 86, 55, -3, -1, 115,
|
||||
85, 39, -7, -3, -1, 114, 70, -1, 100, 23, -5, -1, 113, -1, 7,
|
||||
112, -1, 54, 99, -13, -9, -3, -1, 69, 84, -1, 68, -1, 6, 5,
|
||||
-1, 38, 98, -5, -1, 97, -1, 22, 96, -3, -1, 53, 83, -1, 37,
|
||||
82, -17, -7, -3, -1, 21, 81, -1, 52, 67, -5, -3, -1, 80, 4,
|
||||
36, -1, 66, 20, -3, -1, 51, 65, -1, 35, 50, -11, -7, -5, -3,
|
||||
-1, 64, 3, 48, 19, -1, 49, 34, -1, 18, 33, -7, -5, -3, -1,
|
||||
2, 32, 0, 17, -1, 1, 16
|
||||
};
|
||||
|
||||
static short tab13[] =
|
||||
{
|
||||
-509,-503,-475,-405,-333,-265,-205,-153,-115, -83, -53, -35, -21, -13, -9,
|
||||
-7, -5, -3, -1, 254, 252, 253, 237, 255, -1, 239, 223, -3, -1, 238,
|
||||
207, -1, 222, 191, -9, -3, -1, 251, 206, -1, 220, -1, 175, 233, -1,
|
||||
236, 221, -9, -5, -3, -1, 250, 205, 190, -1, 235, 159, -3, -1, 249,
|
||||
234, -1, 189, 219, -17, -9, -3, -1, 143, 248, -1, 204, -1, 174, 158,
|
||||
-5, -1, 142, -1, 127, 126, 247, -5, -1, 218, -1, 173, 188, -3, -1,
|
||||
203, 246, 111, -15, -7, -3, -1, 232, 95, -1, 157, 217, -3, -1, 245,
|
||||
231, -1, 172, 187, -9, -3, -1, 79, 244, -3, -1, 202, 230, 243, -1,
|
||||
63, -1, 141, 216, -21, -9, -3, -1, 47, 242, -3, -1, 110, 156, 15,
|
||||
-5, -3, -1, 201, 94, 171, -3, -1, 125, 215, 78, -11, -5, -3, -1,
|
||||
200, 214, 62, -1, 185, -1, 155, 170, -1, 31, 241, -23, -13, -5, -1,
|
||||
240, -1, 186, 229, -3, -1, 228, 140, -1, 109, 227, -5, -1, 226, -1,
|
||||
46, 14, -1, 30, 225, -15, -7, -3, -1, 224, 93, -1, 213, 124, -3,
|
||||
-1, 199, 77, -1, 139, 184, -7, -3, -1, 212, 154, -1, 169, 108, -1,
|
||||
198, 61, -37, -21, -9, -5, -3, -1, 211, 123, 45, -1, 210, 29, -5,
|
||||
-1, 183, -1, 92, 197, -3, -1, 153, 122, 195, -7, -5, -3, -1, 167,
|
||||
151, 75, 209, -3, -1, 13, 208, -1, 138, 168, -11, -7, -3, -1, 76,
|
||||
196, -1, 107, 182, -1, 60, 44, -3, -1, 194, 91, -3, -1, 181, 137,
|
||||
28, -43, -23, -11, -5, -1, 193, -1, 152, 12, -1, 192, -1, 180, 106,
|
||||
-5, -3, -1, 166, 121, 59, -1, 179, -1, 136, 90, -11, -5, -1, 43,
|
||||
-1, 165, 105, -1, 164, -1, 120, 135, -5, -1, 148, -1, 119, 118, 178,
|
||||
-11, -3, -1, 27, 177, -3, -1, 11, 176, -1, 150, 74, -7, -3, -1,
|
||||
58, 163, -1, 89, 149, -1, 42, 162, -47, -23, -9, -3, -1, 26, 161,
|
||||
-3, -1, 10, 104, 160, -5, -3, -1, 134, 73, 147, -3, -1, 57, 88,
|
||||
-1, 133, 103, -9, -3, -1, 41, 146, -3, -1, 87, 117, 56, -5, -1,
|
||||
131, -1, 102, 71, -3, -1, 116, 86, -1, 101, 115, -11, -3, -1, 25,
|
||||
145, -3, -1, 9, 144, -1, 72, 132, -7, -5, -1, 114, -1, 70, 100,
|
||||
40, -1, 130, 24, -41, -27, -11, -5, -3, -1, 55, 39, 23, -1, 113,
|
||||
-1, 85, 7, -7, -3, -1, 112, 54, -1, 99, 69, -3, -1, 84, 38,
|
||||
-1, 98, 53, -5, -1, 129, -1, 8, 128, -3, -1, 22, 97, -1, 6,
|
||||
96, -13, -9, -5, -3, -1, 83, 68, 37, -1, 82, 5, -1, 21, 81,
|
||||
-7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20, -19, -11,
|
||||
-5, -1, 65, -1, 4, 64, -3, -1, 35, 50, 19, -3, -1, 49, 3,
|
||||
-1, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16,
|
||||
0
|
||||
};
|
||||
|
||||
static short tab15[] =
|
||||
{
|
||||
-495,-445,-355,-263,-183,-115, -77, -43, -27, -13, -7, -3, -1, 255, 239,
|
||||
-1, 254, 223, -1, 238, -1, 253, 207, -7, -3, -1, 252, 222, -1, 237,
|
||||
191, -1, 251, -1, 206, 236, -7, -3, -1, 221, 175, -1, 250, 190, -3,
|
||||
-1, 235, 205, -1, 220, 159, -15, -7, -3, -1, 249, 234, -1, 189, 219,
|
||||
-3, -1, 143, 248, -1, 204, 158, -7, -3, -1, 233, 127, -1, 247, 173,
|
||||
-3, -1, 218, 188, -1, 111, -1, 174, 15, -19, -11, -3, -1, 203, 246,
|
||||
-3, -1, 142, 232, -1, 95, 157, -3, -1, 245, 126, -1, 231, 172, -9,
|
||||
-3, -1, 202, 187, -3, -1, 217, 141, 79, -3, -1, 244, 63, -1, 243,
|
||||
216, -33, -17, -9, -3, -1, 230, 47, -1, 242, -1, 110, 240, -3, -1,
|
||||
31, 241, -1, 156, 201, -7, -3, -1, 94, 171, -1, 186, 229, -3, -1,
|
||||
125, 215, -1, 78, 228, -15, -7, -3, -1, 140, 200, -1, 62, 109, -3,
|
||||
-1, 214, 227, -1, 155, 185, -7, -3, -1, 46, 170, -1, 226, 30, -5,
|
||||
-1, 225, -1, 14, 224, -1, 93, 213, -45, -25, -13, -7, -3, -1, 124,
|
||||
199, -1, 77, 139, -1, 212, -1, 184, 154, -7, -3, -1, 169, 108, -1,
|
||||
198, 61, -1, 211, 210, -9, -5, -3, -1, 45, 13, 29, -1, 123, 183,
|
||||
-5, -1, 209, -1, 92, 208, -1, 197, 138, -17, -7, -3, -1, 168, 76,
|
||||
-1, 196, 107, -5, -1, 182, -1, 153, 12, -1, 60, 195, -9, -3, -1,
|
||||
122, 167, -1, 166, -1, 192, 11, -1, 194, -1, 44, 91, -55, -29, -15,
|
||||
-7, -3, -1, 181, 28, -1, 137, 152, -3, -1, 193, 75, -1, 180, 106,
|
||||
-5, -3, -1, 59, 121, 179, -3, -1, 151, 136, -1, 43, 90, -11, -5,
|
||||
-1, 178, -1, 165, 27, -1, 177, -1, 176, 105, -7, -3, -1, 150, 74,
|
||||
-1, 164, 120, -3, -1, 135, 58, 163, -17, -7, -3, -1, 89, 149, -1,
|
||||
42, 162, -3, -1, 26, 161, -3, -1, 10, 160, 104, -7, -3, -1, 134,
|
||||
73, -1, 148, 57, -5, -1, 147, -1, 119, 9, -1, 88, 133, -53, -29,
|
||||
-13, -7, -3, -1, 41, 103, -1, 118, 146, -1, 145, -1, 25, 144, -7,
|
||||
-3, -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 71, -7,
|
||||
-3, -1, 40, 130, -1, 24, 129, -7, -3, -1, 116, 8, -1, 128, 86,
|
||||
-3, -1, 101, 55, -1, 115, 70, -17, -7, -3, -1, 39, 114, -1, 100,
|
||||
23, -3, -1, 85, 113, -3, -1, 7, 112, 54, -7, -3, -1, 99, 69,
|
||||
-1, 84, 38, -3, -1, 98, 22, -3, -1, 6, 96, 53, -33, -19, -9,
|
||||
-5, -1, 97, -1, 83, 68, -1, 37, 82, -3, -1, 21, 81, -3, -1,
|
||||
5, 80, 52, -7, -3, -1, 67, 36, -1, 66, 51, -1, 65, -1, 20,
|
||||
4, -9, -3, -1, 35, 50, -3, -1, 64, 3, 19, -3, -1, 49, 48,
|
||||
34, -9, -7, -3, -1, 18, 33, -1, 2, 32, 17, -3, -1, 1, 16,
|
||||
0
|
||||
};
|
||||
|
||||
static short tab16[] =
|
||||
{
|
||||
-509,-503,-461,-323,-103, -37, -27, -15, -7, -3, -1, 239, 254, -1, 223,
|
||||
253, -3, -1, 207, 252, -1, 191, 251, -5, -1, 175, -1, 250, 159, -3,
|
||||
-1, 249, 248, 143, -7, -3, -1, 127, 247, -1, 111, 246, 255, -9, -5,
|
||||
-3, -1, 95, 245, 79, -1, 244, 243, -53, -1, 240, -1, 63, -29, -19,
|
||||
-13, -7, -5, -1, 206, -1, 236, 221, 222, -1, 233, -1, 234, 217, -1,
|
||||
238, -1, 237, 235, -3, -1, 190, 205, -3, -1, 220, 219, 174, -11, -5,
|
||||
-1, 204, -1, 173, 218, -3, -1, 126, 172, 202, -5, -3, -1, 201, 125,
|
||||
94, 189, 242, -93, -5, -3, -1, 47, 15, 31, -1, 241, -49, -25, -13,
|
||||
-5, -1, 158, -1, 188, 203, -3, -1, 142, 232, -1, 157, 231, -7, -3,
|
||||
-1, 187, 141, -1, 216, 110, -1, 230, 156, -13, -7, -3, -1, 171, 186,
|
||||
-1, 229, 215, -1, 78, -1, 228, 140, -3, -1, 200, 62, -1, 109, -1,
|
||||
214, 155, -19, -11, -5, -3, -1, 185, 170, 225, -1, 212, -1, 184, 169,
|
||||
-5, -1, 123, -1, 183, 208, 227, -7, -3, -1, 14, 224, -1, 93, 213,
|
||||
-3, -1, 124, 199, -1, 77, 139, -75, -45, -27, -13, -7, -3, -1, 154,
|
||||
108, -1, 198, 61, -3, -1, 92, 197, 13, -7, -3, -1, 138, 168, -1,
|
||||
153, 76, -3, -1, 182, 122, 60, -11, -5, -3, -1, 91, 137, 28, -1,
|
||||
192, -1, 152, 121, -1, 226, -1, 46, 30, -15, -7, -3, -1, 211, 45,
|
||||
-1, 210, 209, -5, -1, 59, -1, 151, 136, 29, -7, -3, -1, 196, 107,
|
||||
-1, 195, 167, -1, 44, -1, 194, 181, -23, -13, -7, -3, -1, 193, 12,
|
||||
-1, 75, 180, -3, -1, 106, 166, 179, -5, -3, -1, 90, 165, 43, -1,
|
||||
178, 27, -13, -5, -1, 177, -1, 11, 176, -3, -1, 105, 150, -1, 74,
|
||||
164, -5, -3, -1, 120, 135, 163, -3, -1, 58, 89, 42, -97, -57, -33,
|
||||
-19, -11, -5, -3, -1, 149, 104, 161, -3, -1, 134, 119, 148, -5, -3,
|
||||
-1, 73, 87, 103, 162, -5, -1, 26, -1, 10, 160, -3, -1, 57, 147,
|
||||
-1, 88, 133, -9, -3, -1, 41, 146, -3, -1, 118, 9, 25, -5, -1,
|
||||
145, -1, 144, 72, -3, -1, 132, 117, -1, 56, 131, -21, -11, -5, -3,
|
||||
-1, 102, 40, 130, -3, -1, 71, 116, 24, -3, -1, 129, 128, -3, -1,
|
||||
8, 86, 55, -9, -5, -1, 115, -1, 101, 70, -1, 39, 114, -5, -3,
|
||||
-1, 100, 85, 7, 23, -23, -13, -5, -1, 113, -1, 112, 54, -3, -1,
|
||||
99, 69, -1, 84, 38, -3, -1, 98, 22, -1, 97, -1, 6, 96, -9,
|
||||
-5, -1, 83, -1, 53, 68, -1, 37, 82, -1, 81, -1, 21, 5, -33,
|
||||
-23, -13, -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20,
|
||||
-5, -1, 65, -1, 4, 64, -1, 35, 50, -3, -1, 19, 49, -3, -1,
|
||||
3, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16,
|
||||
0
|
||||
};
|
||||
|
||||
static short tab24[] =
|
||||
{
|
||||
-451,-117, -43, -25, -15, -7, -3, -1, 239, 254, -1, 223, 253, -3, -1,
|
||||
207, 252, -1, 191, 251, -5, -1, 250, -1, 175, 159, -1, 249, 248, -9,
|
||||
-5, -3, -1, 143, 127, 247, -1, 111, 246, -3, -1, 95, 245, -1, 79,
|
||||
244, -71, -7, -3, -1, 63, 243, -1, 47, 242, -5, -1, 241, -1, 31,
|
||||
240, -25, -9, -1, 15, -3, -1, 238, 222, -1, 237, 206, -7, -3, -1,
|
||||
236, 221, -1, 190, 235, -3, -1, 205, 220, -1, 174, 234, -15, -7, -3,
|
||||
-1, 189, 219, -1, 204, 158, -3, -1, 233, 173, -1, 218, 188, -7, -3,
|
||||
-1, 203, 142, -1, 232, 157, -3, -1, 217, 126, -1, 231, 172, 255,-235,
|
||||
-143, -77, -45, -25, -15, -7, -3, -1, 202, 187, -1, 141, 216, -5, -3,
|
||||
-1, 14, 224, 13, 230, -5, -3, -1, 110, 156, 201, -1, 94, 186, -9,
|
||||
-5, -1, 229, -1, 171, 125, -1, 215, 228, -3, -1, 140, 200, -3, -1,
|
||||
78, 46, 62, -15, -7, -3, -1, 109, 214, -1, 227, 155, -3, -1, 185,
|
||||
170, -1, 226, 30, -7, -3, -1, 225, 93, -1, 213, 124, -3, -1, 199,
|
||||
77, -1, 139, 184, -31, -15, -7, -3, -1, 212, 154, -1, 169, 108, -3,
|
||||
-1, 198, 61, -1, 211, 45, -7, -3, -1, 210, 29, -1, 123, 183, -3,
|
||||
-1, 209, 92, -1, 197, 138, -17, -7, -3, -1, 168, 153, -1, 76, 196,
|
||||
-3, -1, 107, 182, -3, -1, 208, 12, 60, -7, -3, -1, 195, 122, -1,
|
||||
167, 44, -3, -1, 194, 91, -1, 181, 28, -57, -35, -19, -7, -3, -1,
|
||||
137, 152, -1, 193, 75, -5, -3, -1, 192, 11, 59, -3, -1, 176, 10,
|
||||
26, -5, -1, 180, -1, 106, 166, -3, -1, 121, 151, -3, -1, 160, 9,
|
||||
144, -9, -3, -1, 179, 136, -3, -1, 43, 90, 178, -7, -3, -1, 165,
|
||||
27, -1, 177, 105, -1, 150, 164, -17, -9, -5, -3, -1, 74, 120, 135,
|
||||
-1, 58, 163, -3, -1, 89, 149, -1, 42, 162, -7, -3, -1, 161, 104,
|
||||
-1, 134, 119, -3, -1, 73, 148, -1, 57, 147, -63, -31, -15, -7, -3,
|
||||
-1, 88, 133, -1, 41, 103, -3, -1, 118, 146, -1, 25, 145, -7, -3,
|
||||
-1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 40, -17, -7,
|
||||
-3, -1, 130, 24, -1, 71, 116, -5, -1, 129, -1, 8, 128, -1, 86,
|
||||
101, -7, -5, -1, 23, -1, 7, 112, 115, -3, -1, 55, 39, 114, -15,
|
||||
-7, -3, -1, 70, 100, -1, 85, 113, -3, -1, 54, 99, -1, 69, 84,
|
||||
-7, -3, -1, 38, 98, -1, 22, 97, -5, -3, -1, 6, 96, 53, -1,
|
||||
83, 68, -51, -37, -23, -15, -9, -3, -1, 37, 82, -1, 21, -1, 5,
|
||||
80, -1, 81, -1, 52, 67, -3, -1, 36, 66, -1, 51, 20, -9, -5,
|
||||
-1, 65, -1, 4, 64, -1, 35, 50, -1, 19, 49, -7, -5, -3, -1,
|
||||
3, 48, 34, 18, -1, 33, -1, 2, 32, -3, -1, 17, 1, -1, 16,
|
||||
0
|
||||
};
|
||||
|
||||
static short tab_c0[] =
|
||||
{
|
||||
-29, -21, -13, -7, -3, -1, 11, 15, -1, 13, 14, -3, -1, 7, 5,
|
||||
9, -3, -1, 6, 3, -1, 10, 12, -3, -1, 2, 1, -1, 4, 8,
|
||||
0
|
||||
};
|
||||
|
||||
static short tab_c1[] =
|
||||
{
|
||||
-15, -7, -3, -1, 15, 14, -1, 13, 12, -3, -1, 11, 10, -1, 9,
|
||||
8, -7, -3, -1, 7, 6, -1, 5, 4, -3, -1, 3, 2, -1, 1,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
|
||||
static struct newhuff ht[] =
|
||||
{
|
||||
{ /* 0 */ 0 , tab0 } ,
|
||||
{ /* 2 */ 0 , tab1 } ,
|
||||
{ /* 3 */ 0 , tab2 } ,
|
||||
{ /* 3 */ 0 , tab3 } ,
|
||||
{ /* 0 */ 0 , tab0 } ,
|
||||
{ /* 4 */ 0 , tab5 } ,
|
||||
{ /* 4 */ 0 , tab6 } ,
|
||||
{ /* 6 */ 0 , tab7 } ,
|
||||
{ /* 6 */ 0 , tab8 } ,
|
||||
{ /* 6 */ 0 , tab9 } ,
|
||||
{ /* 8 */ 0 , tab10 } ,
|
||||
{ /* 8 */ 0 , tab11 } ,
|
||||
{ /* 8 */ 0 , tab12 } ,
|
||||
{ /* 16 */ 0 , tab13 } ,
|
||||
{ /* 0 */ 0 , tab0 } ,
|
||||
{ /* 16 */ 0 , tab15 } ,
|
||||
|
||||
{ /* 16 */ 1 , tab16 } ,
|
||||
{ /* 16 */ 2 , tab16 } ,
|
||||
{ /* 16 */ 3 , tab16 } ,
|
||||
{ /* 16 */ 4 , tab16 } ,
|
||||
{ /* 16 */ 6 , tab16 } ,
|
||||
{ /* 16 */ 8 , tab16 } ,
|
||||
{ /* 16 */ 10, tab16 } ,
|
||||
{ /* 16 */ 13, tab16 } ,
|
||||
{ /* 16 */ 4 , tab24 } ,
|
||||
{ /* 16 */ 5 , tab24 } ,
|
||||
{ /* 16 */ 6 , tab24 } ,
|
||||
{ /* 16 */ 7 , tab24 } ,
|
||||
{ /* 16 */ 8 , tab24 } ,
|
||||
{ /* 16 */ 9 , tab24 } ,
|
||||
{ /* 16 */ 11, tab24 } ,
|
||||
{ /* 16 */ 13, tab24 }
|
||||
};
|
||||
|
||||
static struct newhuff htc[] =
|
||||
{
|
||||
{ /* 1 , 1 , */ 0 , tab_c0 } ,
|
||||
{ /* 1 , 1 , */ 0 , tab_c1 }
|
||||
};
|
||||
|
||||
|
@ -1,222 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mpg123.h"
|
||||
#include "mpglib.h"
|
||||
|
||||
void InitMpgLib(void)
|
||||
{
|
||||
make_decode_tables(32767);
|
||||
init_layer2();
|
||||
init_layer3(SBLIMIT);
|
||||
}
|
||||
|
||||
void InitMP3(struct mpstr *mp)
|
||||
{
|
||||
memset(mp,0,sizeof(struct mpstr));
|
||||
|
||||
mp->framesize = 0;
|
||||
mp->fsizeold = -1;
|
||||
mp->bsize = 0;
|
||||
mp->head = mp->tail = NULL;
|
||||
mp->fr.single = -1;
|
||||
mp->bsnum = 0;
|
||||
mp->synth_bo = 1;
|
||||
mp->bitindex = 0;
|
||||
mp->wordpointer = 0;
|
||||
}
|
||||
|
||||
void ExitMP3(struct mpstr *mp)
|
||||
{
|
||||
struct buf *b,*bn;
|
||||
|
||||
b = mp->tail;
|
||||
while(b) {
|
||||
free(b->pnt);
|
||||
bn = b->next;
|
||||
free(b);
|
||||
b = bn;
|
||||
}
|
||||
}
|
||||
|
||||
static struct buf *addbuf(struct mpstr *mp,char *buf,int size)
|
||||
{
|
||||
struct buf *nbuf;
|
||||
|
||||
nbuf = malloc( sizeof(struct buf) );
|
||||
if(!nbuf) {
|
||||
fprintf(stderr,"Out of memory!\n");
|
||||
return NULL;
|
||||
}
|
||||
nbuf->pnt = malloc(size);
|
||||
if(!nbuf->pnt) {
|
||||
free(nbuf);
|
||||
return NULL;
|
||||
}
|
||||
nbuf->size = size;
|
||||
memcpy(nbuf->pnt,buf,size);
|
||||
nbuf->next = NULL;
|
||||
nbuf->prev = mp->head;
|
||||
nbuf->pos = 0;
|
||||
|
||||
if(!mp->tail) {
|
||||
mp->tail = nbuf;
|
||||
}
|
||||
else {
|
||||
mp->head->next = nbuf;
|
||||
}
|
||||
|
||||
mp->head = nbuf;
|
||||
mp->bsize += size;
|
||||
|
||||
return nbuf;
|
||||
}
|
||||
|
||||
static void remove_buf(struct mpstr *mp)
|
||||
{
|
||||
struct buf *buf = mp->tail;
|
||||
|
||||
mp->tail = buf->next;
|
||||
if(mp->tail)
|
||||
mp->tail->prev = NULL;
|
||||
else {
|
||||
mp->tail = mp->head = NULL;
|
||||
}
|
||||
|
||||
free(buf->pnt);
|
||||
free(buf);
|
||||
|
||||
}
|
||||
|
||||
static int read_buf_byte(struct mpstr *mp)
|
||||
{
|
||||
unsigned int b;
|
||||
|
||||
int pos;
|
||||
|
||||
if(!mp->tail) {
|
||||
fprintf(stderr,"Fatal error!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pos = mp->tail->pos;
|
||||
while(pos >= mp->tail->size) {
|
||||
remove_buf(mp);
|
||||
if(!mp->tail) {
|
||||
fprintf(stderr,"Fatal error!\n");
|
||||
return 0;
|
||||
}
|
||||
pos = mp->tail->pos;
|
||||
}
|
||||
|
||||
b = mp->tail->pnt[pos];
|
||||
mp->bsize--;
|
||||
mp->tail->pos++;
|
||||
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static void read_head(struct mpstr *mp)
|
||||
{
|
||||
unsigned long head;
|
||||
|
||||
head = read_buf_byte(mp);
|
||||
head <<= 8;
|
||||
head |= read_buf_byte(mp);
|
||||
head <<= 8;
|
||||
head |= read_buf_byte(mp);
|
||||
head <<= 8;
|
||||
head |= read_buf_byte(mp);
|
||||
|
||||
mp->header = head;
|
||||
}
|
||||
|
||||
int decodeMP3(struct mpstr *mp,char *in,int isize,char *out,
|
||||
int osize,int *done)
|
||||
{
|
||||
int len;
|
||||
|
||||
if(osize < 4608) {
|
||||
fprintf(stderr,"To less out space\n");
|
||||
return MP3_ERR;
|
||||
}
|
||||
|
||||
if(in) {
|
||||
if(addbuf(mp,in,isize) == NULL) {
|
||||
return MP3_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
/* First decode header */
|
||||
if(mp->framesize == 0) {
|
||||
if(mp->bsize < 4) {
|
||||
return MP3_NEED_MORE;
|
||||
}
|
||||
read_head(mp);
|
||||
if (decode_header(&mp->fr,mp->header) == 0)
|
||||
return MP3_ERR;
|
||||
mp->framesize = mp->fr.framesize;
|
||||
}
|
||||
|
||||
if(mp->fr.framesize > mp->bsize)
|
||||
return MP3_NEED_MORE;
|
||||
|
||||
mp->wordpointer = mp->bsspace[mp->bsnum] + 512;
|
||||
mp->bsnum = (mp->bsnum + 1) & 0x1;
|
||||
mp->bitindex = 0;
|
||||
|
||||
len = 0;
|
||||
while(len < mp->framesize) {
|
||||
int nlen;
|
||||
int blen = mp->tail->size - mp->tail->pos;
|
||||
if( (mp->framesize - len) <= blen) {
|
||||
nlen = mp->framesize-len;
|
||||
}
|
||||
else {
|
||||
nlen = blen;
|
||||
}
|
||||
memcpy(mp->wordpointer+len,mp->tail->pnt+mp->tail->pos,nlen);
|
||||
len += nlen;
|
||||
mp->tail->pos += nlen;
|
||||
mp->bsize -= nlen;
|
||||
if(mp->tail->pos == mp->tail->size) {
|
||||
remove_buf(mp);
|
||||
}
|
||||
}
|
||||
|
||||
*done = 0;
|
||||
if(mp->fr.error_protection)
|
||||
getbits(mp, 16);
|
||||
switch(mp->fr.lay) {
|
||||
case 1:
|
||||
do_layer1(mp, &mp->fr,(unsigned char *) out,done);
|
||||
break;
|
||||
case 2:
|
||||
do_layer2(mp, &mp->fr,(unsigned char *) out,done);
|
||||
break;
|
||||
case 3:
|
||||
do_layer3(mp, &mp->fr,(unsigned char *) out,done);
|
||||
break;
|
||||
}
|
||||
|
||||
mp->fsizeold = mp->framesize;
|
||||
mp->framesize = 0;
|
||||
|
||||
return MP3_OK;
|
||||
}
|
||||
|
||||
int set_pointer(struct mpstr *mp, long backstep)
|
||||
{
|
||||
unsigned char *bsbufold;
|
||||
if(mp->fsizeold < 0 && backstep > 0) {
|
||||
fprintf(stderr,"Can't step back %ld!\n",backstep);
|
||||
return MP3_ERR;
|
||||
}
|
||||
bsbufold = mp->bsspace[mp->bsnum] + 512;
|
||||
mp->wordpointer -= backstep;
|
||||
if (backstep)
|
||||
memcpy(mp->wordpointer,bsbufold+mp->fsizeold-backstep,backstep);
|
||||
mp->bitindex = 0;
|
||||
return MP3_OK;
|
||||
}
|
@ -1,160 +0,0 @@
|
||||
/*
|
||||
* Layer 2 Alloc tables ..
|
||||
* most other tables are calculated on program start (which is (of course)
|
||||
* not ISO-conform) ..
|
||||
* Layer-3 huffman table is in huffman.h
|
||||
*/
|
||||
|
||||
struct al_table
|
||||
{
|
||||
short bits;
|
||||
short d;
|
||||
};
|
||||
|
||||
struct al_table alloc_0[] = {
|
||||
{4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
|
||||
{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
|
||||
{4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
|
||||
{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
|
||||
{4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
|
||||
{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{2,0},{5,3},{7,5},{16,-32767},
|
||||
{2,0},{5,3},{7,5},{16,-32767},
|
||||
{2,0},{5,3},{7,5},{16,-32767},
|
||||
{2,0},{5,3},{7,5},{16,-32767} };
|
||||
|
||||
struct al_table alloc_1[] = {
|
||||
{4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
|
||||
{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
|
||||
{4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
|
||||
{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
|
||||
{4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
|
||||
{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
|
||||
{2,0},{5,3},{7,5},{16,-32767},
|
||||
{2,0},{5,3},{7,5},{16,-32767},
|
||||
{2,0},{5,3},{7,5},{16,-32767},
|
||||
{2,0},{5,3},{7,5},{16,-32767},
|
||||
{2,0},{5,3},{7,5},{16,-32767},
|
||||
{2,0},{5,3},{7,5},{16,-32767},
|
||||
{2,0},{5,3},{7,5},{16,-32767} };
|
||||
|
||||
struct al_table alloc_2[] = {
|
||||
{4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
|
||||
{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
|
||||
{4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
|
||||
{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63} };
|
||||
|
||||
struct al_table alloc_3[] = {
|
||||
{4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
|
||||
{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
|
||||
{4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
|
||||
{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63} };
|
||||
|
||||
struct al_table alloc_4[] = {
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
|
||||
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
|
||||
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9},
|
||||
{2,0},{5,3},{7,5},{10,9} };
|
||||
|
@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Mpeg Layer-1 audio decoder
|
||||
* --------------------------
|
||||
* copyright (c) 1995 by Michael Hipp, All rights reserved. See also 'README'
|
||||
* near unoptimzed ...
|
||||
*
|
||||
* may have a few bugs after last optimization ...
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mpg123.h"
|
||||
|
||||
void I_step_one(struct mpstr *mp, unsigned int balloc[], unsigned int scale_index[2][SBLIMIT],struct frame *fr);
|
||||
void I_step_two(struct mpstr *mp, real fraction[2][SBLIMIT],unsigned int balloc[2*SBLIMIT],
|
||||
unsigned int scale_index[2][SBLIMIT],struct frame *fr);
|
||||
|
||||
void I_step_one(struct mpstr *mp, unsigned int balloc[], unsigned int scale_index[2][SBLIMIT],struct frame *fr)
|
||||
{
|
||||
unsigned int *ba=balloc;
|
||||
unsigned int *sca = (unsigned int *) scale_index;
|
||||
|
||||
if(fr->stereo == 2) {
|
||||
int i;
|
||||
int jsbound = fr->jsbound;
|
||||
for (i=0;i<jsbound;i++) {
|
||||
*ba++ = getbits(mp, 4);
|
||||
*ba++ = getbits(mp, 4);
|
||||
}
|
||||
for (i=jsbound;i<SBLIMIT;i++)
|
||||
*ba++ = getbits(mp, 4);
|
||||
|
||||
ba = balloc;
|
||||
|
||||
for (i=0;i<jsbound;i++) {
|
||||
if ((*ba++))
|
||||
*sca++ = getbits(mp, 6);
|
||||
if ((*ba++))
|
||||
*sca++ = getbits(mp, 6);
|
||||
}
|
||||
for (i=jsbound;i<SBLIMIT;i++)
|
||||
if ((*ba++)) {
|
||||
*sca++ = getbits(mp, 6);
|
||||
*sca++ = getbits(mp, 6);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
for (i=0;i<SBLIMIT;i++)
|
||||
*ba++ = getbits(mp, 4);
|
||||
ba = balloc;
|
||||
for (i=0;i<SBLIMIT;i++)
|
||||
if ((*ba++))
|
||||
*sca++ = getbits(mp, 6);
|
||||
}
|
||||
}
|
||||
|
||||
void I_step_two(struct mpstr *mp, real fraction[2][SBLIMIT],unsigned int balloc[2*SBLIMIT],
|
||||
unsigned int scale_index[2][SBLIMIT],struct frame *fr)
|
||||
{
|
||||
int i,n;
|
||||
int smpb[2*SBLIMIT]; /* values: 0-65535 */
|
||||
int *sample;
|
||||
register unsigned int *ba;
|
||||
register unsigned int *sca = (unsigned int *) scale_index;
|
||||
|
||||
if(fr->stereo) {
|
||||
int jsbound = fr->jsbound;
|
||||
register real *f0 = fraction[0];
|
||||
register real *f1 = fraction[1];
|
||||
ba = balloc;
|
||||
for (sample=smpb,i=0;i<jsbound;i++) {
|
||||
if ((n = *ba++))
|
||||
*sample++ = getbits(mp, n+1);
|
||||
if ((n = *ba++))
|
||||
*sample++ = getbits(mp, n+1);
|
||||
}
|
||||
for (i=jsbound;i<SBLIMIT;i++)
|
||||
if ((n = *ba++))
|
||||
*sample++ = getbits(mp, n+1);
|
||||
|
||||
ba = balloc;
|
||||
for (sample=smpb,i=0;i<jsbound;i++) {
|
||||
if((n=*ba++))
|
||||
*f0++ = (real) ( ((-1)<<n) + (*sample++) + 1) * muls[n+1][*sca++];
|
||||
else
|
||||
*f0++ = 0.0;
|
||||
if((n=*ba++))
|
||||
*f1++ = (real) ( ((-1)<<n) + (*sample++) + 1) * muls[n+1][*sca++];
|
||||
else
|
||||
*f1++ = 0.0;
|
||||
}
|
||||
for (i=jsbound;i<SBLIMIT;i++) {
|
||||
if ((n=*ba++)) {
|
||||
real samp = ( ((-1)<<n) + (*sample++) + 1);
|
||||
*f0++ = samp * muls[n+1][*sca++];
|
||||
*f1++ = samp * muls[n+1][*sca++];
|
||||
}
|
||||
else
|
||||
*f0++ = *f1++ = 0.0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
register real *f0 = fraction[0];
|
||||
ba = balloc;
|
||||
for (sample=smpb,i=0;i<SBLIMIT;i++)
|
||||
if ((n = *ba++))
|
||||
*sample++ = getbits(mp, n+1);
|
||||
ba = balloc;
|
||||
for (sample=smpb,i=0;i<SBLIMIT;i++) {
|
||||
if((n=*ba++))
|
||||
*f0++ = (real) ( ((-1)<<n) + (*sample++) + 1) * muls[n+1][*sca++];
|
||||
else
|
||||
*f0++ = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int do_layer1(struct mpstr *mp, struct frame *fr,unsigned char *pcm_sample,int *pcm_point)
|
||||
{
|
||||
int clip=0;
|
||||
int i,stereo = fr->stereo;
|
||||
unsigned int balloc[2*SBLIMIT];
|
||||
unsigned int scale_index[2][SBLIMIT];
|
||||
real fraction[2][SBLIMIT];
|
||||
int single = fr->single;
|
||||
|
||||
fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? (fr->mode_ext<<2)+4 : 32;
|
||||
|
||||
if(stereo == 1 || single == 3)
|
||||
single = 0;
|
||||
|
||||
I_step_one(mp, balloc,scale_index,fr);
|
||||
|
||||
for (i=0;i<SCALE_BLOCK;i++)
|
||||
{
|
||||
I_step_two(mp, fraction,balloc,scale_index,fr);
|
||||
|
||||
if(single >= 0) {
|
||||
clip += synth_1to1_mono(mp, (real*)fraction[single],pcm_sample,pcm_point);
|
||||
}
|
||||
else {
|
||||
int p1 = *pcm_point;
|
||||
clip += synth_1to1(mp, (real*)fraction[0],0,pcm_sample,&p1);
|
||||
clip += synth_1to1(mp, (real*)fraction[1],1,pcm_sample,pcm_point);
|
||||
}
|
||||
}
|
||||
|
||||
return clip;
|
||||
}
|
||||
|
||||
|
@ -1,296 +0,0 @@
|
||||
/*
|
||||
* Mpeg Layer-2 audio decoder
|
||||
* --------------------------
|
||||
* copyright (c) 1995 by Michael Hipp, All rights reserved. See also 'README'
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mpg123.h"
|
||||
#include "l2tables.h"
|
||||
|
||||
static int grp_3tab[32 * 3] = { 0, }; /* used: 27 */
|
||||
static int grp_5tab[128 * 3] = { 0, }; /* used: 125 */
|
||||
static int grp_9tab[1024 * 3] = { 0, }; /* used: 729 */
|
||||
|
||||
real muls[27][64]; /* also used by layer 1 */
|
||||
|
||||
void II_step_one(struct mpstr *mp, unsigned int *bit_alloc,int *scale,struct frame *fr);
|
||||
void II_step_two(struct mpstr *mp, unsigned int *bit_alloc,real fraction[2][4][SBLIMIT],int *scale,struct frame *fr,int x1);
|
||||
|
||||
void init_layer2(void)
|
||||
{
|
||||
static double mulmul[27] = {
|
||||
0.0 , -2.0/3.0 , 2.0/3.0 ,
|
||||
2.0/7.0 , 2.0/15.0 , 2.0/31.0, 2.0/63.0 , 2.0/127.0 , 2.0/255.0 ,
|
||||
2.0/511.0 , 2.0/1023.0 , 2.0/2047.0 , 2.0/4095.0 , 2.0/8191.0 ,
|
||||
2.0/16383.0 , 2.0/32767.0 , 2.0/65535.0 ,
|
||||
-4.0/5.0 , -2.0/5.0 , 2.0/5.0, 4.0/5.0 ,
|
||||
-8.0/9.0 , -4.0/9.0 , -2.0/9.0 , 2.0/9.0 , 4.0/9.0 , 8.0/9.0 };
|
||||
static int base[3][9] = {
|
||||
{ 1 , 0, 2 , } ,
|
||||
{ 17, 18, 0 , 19, 20 , } ,
|
||||
{ 21, 1, 22, 23, 0, 24, 25, 2, 26 } };
|
||||
int i,j,k,l,len;
|
||||
real *table;
|
||||
static int tablen[3] = { 3 , 5 , 9 };
|
||||
static int *itable,*tables[3] = { grp_3tab , grp_5tab , grp_9tab };
|
||||
|
||||
for(i=0;i<3;i++)
|
||||
{
|
||||
itable = tables[i];
|
||||
len = tablen[i];
|
||||
for(j=0;j<len;j++)
|
||||
for(k=0;k<len;k++)
|
||||
for(l=0;l<len;l++)
|
||||
{
|
||||
*itable++ = base[i][l];
|
||||
*itable++ = base[i][k];
|
||||
*itable++ = base[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for(k=0;k<27;k++)
|
||||
{
|
||||
double m=mulmul[k];
|
||||
table = muls[k];
|
||||
for(j=3,i=0;i<63;i++,j--)
|
||||
*table++ = m * pow(2.0,(double) j / 3.0);
|
||||
*table++ = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void II_step_one(struct mpstr *mp, unsigned int *bit_alloc,int *scale,struct frame *fr)
|
||||
{
|
||||
int stereo = fr->stereo-1;
|
||||
int sblimit = fr->II_sblimit;
|
||||
int jsbound = fr->jsbound;
|
||||
int sblimit2 = fr->II_sblimit<<stereo;
|
||||
struct al_table *alloc1 = fr->alloc;
|
||||
int i;
|
||||
unsigned int scfsi_buf[64];
|
||||
unsigned int *scfsi,*bita;
|
||||
int sc,step;
|
||||
|
||||
bita = bit_alloc;
|
||||
if(stereo)
|
||||
{
|
||||
for (i=jsbound;i;i--,alloc1+=(1<<step))
|
||||
{
|
||||
*bita++ = (char) getbits(mp, step=alloc1->bits);
|
||||
*bita++ = (char) getbits(mp, step);
|
||||
}
|
||||
for (i=sblimit-jsbound;i;i--,alloc1+=(1<<step))
|
||||
{
|
||||
bita[0] = (char) getbits(mp, step=alloc1->bits);
|
||||
bita[1] = bita[0];
|
||||
bita+=2;
|
||||
}
|
||||
bita = bit_alloc;
|
||||
scfsi=scfsi_buf;
|
||||
for (i=sblimit2;i;i--)
|
||||
if (*bita++)
|
||||
*scfsi++ = (char) getbits_fast(mp, 2);
|
||||
}
|
||||
else /* mono */
|
||||
{
|
||||
for (i=sblimit;i;i--,alloc1+=(1<<step))
|
||||
*bita++ = (char) getbits(mp, step=alloc1->bits);
|
||||
bita = bit_alloc;
|
||||
scfsi=scfsi_buf;
|
||||
for (i=sblimit;i;i--)
|
||||
if (*bita++)
|
||||
*scfsi++ = (char) getbits_fast(mp, 2);
|
||||
}
|
||||
|
||||
bita = bit_alloc;
|
||||
scfsi=scfsi_buf;
|
||||
for (i=sblimit2;i;i--)
|
||||
if (*bita++)
|
||||
switch (*scfsi++)
|
||||
{
|
||||
case 0:
|
||||
*scale++ = getbits_fast(mp, 6);
|
||||
*scale++ = getbits_fast(mp, 6);
|
||||
*scale++ = getbits_fast(mp, 6);
|
||||
break;
|
||||
case 1 :
|
||||
*scale++ = sc = getbits_fast(mp, 6);
|
||||
*scale++ = sc;
|
||||
*scale++ = getbits_fast(mp, 6);
|
||||
break;
|
||||
case 2:
|
||||
*scale++ = sc = getbits_fast(mp, 6);
|
||||
*scale++ = sc;
|
||||
*scale++ = sc;
|
||||
break;
|
||||
default: /* case 3 */
|
||||
*scale++ = getbits_fast(mp, 6);
|
||||
*scale++ = sc = getbits_fast(mp, 6);
|
||||
*scale++ = sc;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void II_step_two(struct mpstr *mp, unsigned int *bit_alloc,real fraction[2][4][SBLIMIT],int *scale,struct frame *fr,int x1)
|
||||
{
|
||||
int i,j,k,ba;
|
||||
int stereo = fr->stereo;
|
||||
int sblimit = fr->II_sblimit;
|
||||
int jsbound = fr->jsbound;
|
||||
struct al_table *alloc2,*alloc1 = fr->alloc;
|
||||
unsigned int *bita=bit_alloc;
|
||||
int d1,step;
|
||||
|
||||
for (i=0;i<jsbound;i++,alloc1+=(1<<step))
|
||||
{
|
||||
step = alloc1->bits;
|
||||
for (j=0;j<stereo;j++)
|
||||
{
|
||||
if ( (ba=*bita++) )
|
||||
{
|
||||
k=(alloc2 = alloc1+ba)->bits;
|
||||
if( (d1=alloc2->d) < 0)
|
||||
{
|
||||
real cm=muls[k][scale[x1]];
|
||||
fraction[j][0][i] = ((real) ((int)getbits(mp, k) + d1)) * cm;
|
||||
fraction[j][1][i] = ((real) ((int)getbits(mp, k) + d1)) * cm;
|
||||
fraction[j][2][i] = ((real) ((int)getbits(mp, k) + d1)) * cm;
|
||||
}
|
||||
else
|
||||
{
|
||||
static int *table[] = { 0,0,0,grp_3tab,0,grp_5tab,0,0,0,grp_9tab };
|
||||
unsigned int idx,*tab,m=scale[x1];
|
||||
idx = (unsigned int) getbits(mp, k);
|
||||
tab = (unsigned int *) (table[d1] + idx + idx + idx);
|
||||
fraction[j][0][i] = muls[*tab++][m];
|
||||
fraction[j][1][i] = muls[*tab++][m];
|
||||
fraction[j][2][i] = muls[*tab][m];
|
||||
}
|
||||
scale+=3;
|
||||
}
|
||||
else
|
||||
fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=jsbound;i<sblimit;i++,alloc1+=(1<<step))
|
||||
{
|
||||
step = alloc1->bits;
|
||||
bita++; /* channel 1 and channel 2 bitalloc are the same */
|
||||
if ( (ba=*bita++) )
|
||||
{
|
||||
k=(alloc2 = alloc1+ba)->bits;
|
||||
if( (d1=alloc2->d) < 0)
|
||||
{
|
||||
real cm;
|
||||
cm=muls[k][scale[x1+3]];
|
||||
fraction[1][0][i] = (fraction[0][0][i] = (real) ((int)getbits(mp, k) + d1) ) * cm;
|
||||
fraction[1][1][i] = (fraction[0][1][i] = (real) ((int)getbits(mp, k) + d1) ) * cm;
|
||||
fraction[1][2][i] = (fraction[0][2][i] = (real) ((int)getbits(mp, k) + d1) ) * cm;
|
||||
cm=muls[k][scale[x1]];
|
||||
fraction[0][0][i] *= cm; fraction[0][1][i] *= cm; fraction[0][2][i] *= cm;
|
||||
}
|
||||
else
|
||||
{
|
||||
static int *table[] = { 0,0,0,grp_3tab,0,grp_5tab,0,0,0,grp_9tab };
|
||||
unsigned int idx,*tab,m1,m2;
|
||||
m1 = scale[x1]; m2 = scale[x1+3];
|
||||
idx = (unsigned int) getbits(mp, k);
|
||||
tab = (unsigned int *) (table[d1] + idx + idx + idx);
|
||||
fraction[0][0][i] = muls[*tab][m1]; fraction[1][0][i] = muls[*tab++][m2];
|
||||
fraction[0][1][i] = muls[*tab][m1]; fraction[1][1][i] = muls[*tab++][m2];
|
||||
fraction[0][2][i] = muls[*tab][m1]; fraction[1][2][i] = muls[*tab][m2];
|
||||
}
|
||||
scale+=6;
|
||||
}
|
||||
else {
|
||||
fraction[0][0][i] = fraction[0][1][i] = fraction[0][2][i] =
|
||||
fraction[1][0][i] = fraction[1][1][i] = fraction[1][2][i] = 0.0;
|
||||
}
|
||||
/*
|
||||
should we use individual scalefac for channel 2 or
|
||||
is the current way the right one , where we just copy channel 1 to
|
||||
channel 2 ??
|
||||
The current 'strange' thing is, that we throw away the scalefac
|
||||
values for the second channel ...!!
|
||||
-> changed .. now we use the scalefac values of channel one !!
|
||||
*/
|
||||
}
|
||||
|
||||
for(i=sblimit;i<SBLIMIT;i++)
|
||||
for (j=0;j<stereo;j++)
|
||||
fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = 0.0;
|
||||
|
||||
}
|
||||
|
||||
static void II_select_table(struct frame *fr)
|
||||
{
|
||||
static int translate[3][2][16] =
|
||||
{ { { 0,2,2,2,2,2,2,0,0,0,1,1,1,1,1,0 } ,
|
||||
{ 0,2,2,0,0,0,1,1,1,1,1,1,1,1,1,0 } } ,
|
||||
{ { 0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0 } ,
|
||||
{ 0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0 } } ,
|
||||
{ { 0,3,3,3,3,3,3,0,0,0,1,1,1,1,1,0 } ,
|
||||
{ 0,3,3,0,0,0,1,1,1,1,1,1,1,1,1,0 } } };
|
||||
|
||||
int table,sblim;
|
||||
static struct al_table *tables[5] =
|
||||
{ alloc_0, alloc_1, alloc_2, alloc_3 , alloc_4 };
|
||||
static int sblims[5] = { 27 , 30 , 8, 12 , 30 };
|
||||
|
||||
if(fr->lsf)
|
||||
table = 4;
|
||||
else
|
||||
table = translate[fr->sampling_frequency][2-fr->stereo][fr->bitrate_index];
|
||||
sblim = sblims[table];
|
||||
|
||||
fr->alloc = tables[table];
|
||||
fr->II_sblimit = sblim;
|
||||
}
|
||||
|
||||
int do_layer2(struct mpstr *mp, struct frame *fr,unsigned char *pcm_sample,int *pcm_point)
|
||||
{
|
||||
int clip=0;
|
||||
int i,j;
|
||||
int stereo = fr->stereo;
|
||||
real fraction[2][4][SBLIMIT]; /* pick_table clears unused subbands */
|
||||
unsigned int bit_alloc[64];
|
||||
int scale[192];
|
||||
int single = fr->single;
|
||||
|
||||
II_select_table(fr);
|
||||
fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ?
|
||||
(fr->mode_ext<<2)+4 : fr->II_sblimit;
|
||||
|
||||
if (fr->jsbound > fr->II_sblimit) {
|
||||
fprintf(stderr, "libmpg123 layer2: Truncating stereo boundary to sideband limit.\n");
|
||||
fr->jsbound=fr->II_sblimit;
|
||||
}
|
||||
|
||||
if(stereo == 1 || single == 3)
|
||||
single = 0;
|
||||
|
||||
II_step_one(mp, bit_alloc, scale, fr);
|
||||
|
||||
for (i=0;i<SCALE_BLOCK;i++)
|
||||
{
|
||||
II_step_two(mp, bit_alloc, fraction, scale, fr, i>>2);
|
||||
for (j=0;j<3;j++) {
|
||||
if(single >= 0) {
|
||||
clip += synth_1to1_mono(mp, fraction[0][j],pcm_sample,pcm_point);
|
||||
}
|
||||
else {
|
||||
int p1 = *pcm_point;
|
||||
clip += synth_1to1(mp, fraction[0][j],0,pcm_sample,&p1);
|
||||
clip += synth_1to1(mp, fraction[1][j],1,pcm_sample,pcm_point);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return clip;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,120 +0,0 @@
|
||||
#ifndef _MPG123_H
|
||||
#define _MPG123_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef REAL_IS_FLOAT
|
||||
# define real float
|
||||
#elif defined(REAL_IS_LONG_DOUBLE)
|
||||
# define real long double
|
||||
#else
|
||||
# define real double
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define INLINE inline
|
||||
#else
|
||||
#define INLINE
|
||||
#endif
|
||||
|
||||
/* AUDIOBUFSIZE = n*64 with n=1,2,3 ... */
|
||||
#define AUDIOBUFSIZE 16384
|
||||
|
||||
#define SBLIMIT 32
|
||||
#define SSLIMIT 18
|
||||
|
||||
#define SCALE_BLOCK 12
|
||||
|
||||
#define MPG_MD_STEREO 0
|
||||
#define MPG_MD_JOINT_STEREO 1
|
||||
#define MPG_MD_DUAL_CHANNEL 2
|
||||
#define MPG_MD_MONO 3
|
||||
|
||||
#define MAXFRAMESIZE 1792
|
||||
|
||||
struct mpstr;
|
||||
|
||||
struct frame {
|
||||
int stereo;
|
||||
int jsbound;
|
||||
int single;
|
||||
int lsf;
|
||||
int mpeg25;
|
||||
int header_change;
|
||||
int lay;
|
||||
int error_protection;
|
||||
int bitrate_index;
|
||||
int sampling_frequency;
|
||||
int padding;
|
||||
int extension;
|
||||
int mode;
|
||||
int mode_ext;
|
||||
int copyright;
|
||||
int original;
|
||||
int emphasis;
|
||||
int framesize; /* computed framesize */
|
||||
|
||||
/* layer2 stuff */
|
||||
int II_sblimit;
|
||||
void *alloc;
|
||||
};
|
||||
|
||||
extern unsigned int get1bit(struct mpstr *mp);
|
||||
extern unsigned int getbits(struct mpstr *mp, int);
|
||||
extern unsigned int getbits_fast(struct mpstr *mp, int);
|
||||
extern int set_pointer(struct mpstr *mp, long backstep);
|
||||
|
||||
extern void make_decode_tables(long scaleval);
|
||||
extern int do_layer3(struct mpstr *mp, struct frame *fr,unsigned char *,int *);
|
||||
extern int do_layer2(struct mpstr *mp, struct frame *fr,unsigned char *,int *);
|
||||
extern int do_layer1(struct mpstr *mp, struct frame *fr,unsigned char *,int *);
|
||||
extern int decode_header(struct frame *fr,unsigned long newhead);
|
||||
|
||||
struct gr_info_s {
|
||||
int scfsi;
|
||||
unsigned part2_3_length;
|
||||
unsigned big_values;
|
||||
unsigned scalefac_compress;
|
||||
unsigned block_type;
|
||||
unsigned mixed_block_flag;
|
||||
unsigned table_select[3];
|
||||
unsigned subblock_gain[3];
|
||||
unsigned maxband[3];
|
||||
unsigned maxbandl;
|
||||
unsigned maxb;
|
||||
unsigned region1start;
|
||||
unsigned region2start;
|
||||
unsigned preflag;
|
||||
unsigned scalefac_scale;
|
||||
unsigned count1table_select;
|
||||
real *full_gain[3];
|
||||
real *pow2gain;
|
||||
};
|
||||
|
||||
struct III_sideinfo
|
||||
{
|
||||
unsigned main_data_begin;
|
||||
unsigned private_bits;
|
||||
struct {
|
||||
struct gr_info_s gr[2];
|
||||
} ch[2];
|
||||
};
|
||||
|
||||
extern int synth_1to1 (struct mpstr *mp, real *,int,unsigned char *,int *);
|
||||
extern int synth_1to1_mono (struct mpstr *mp, real *,unsigned char *,int *);
|
||||
|
||||
extern void init_layer3(int);
|
||||
extern void init_layer2(void);
|
||||
extern void make_decode_tables(long scale);
|
||||
extern void dct64(real *,real *,real *);
|
||||
|
||||
extern long freqs[9];
|
||||
extern real muls[27][64];
|
||||
extern real decwin[512+32];
|
||||
extern real *pnts[5];
|
||||
|
||||
#endif
|
@ -1,56 +0,0 @@
|
||||
#ifndef _MPGLIB_H
|
||||
#define _MPGLIB_H
|
||||
|
||||
#include "mpg123.h"
|
||||
|
||||
struct buf {
|
||||
unsigned char *pnt;
|
||||
long size;
|
||||
long pos;
|
||||
struct buf *next;
|
||||
struct buf *prev;
|
||||
};
|
||||
|
||||
struct framebuf {
|
||||
struct buf *buf;
|
||||
long pos;
|
||||
struct frame *next;
|
||||
struct frame *prev;
|
||||
};
|
||||
|
||||
struct mpstr {
|
||||
struct buf *head,*tail;
|
||||
int bsize;
|
||||
int framesize;
|
||||
int fsizeold;
|
||||
struct frame fr;
|
||||
unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */
|
||||
real hybrid_block[2][2][SBLIMIT*SSLIMIT];
|
||||
int hybrid_blc[2];
|
||||
unsigned long header;
|
||||
int bsnum;
|
||||
real synth_buffs[2][2][0x110];
|
||||
int synth_bo;
|
||||
int bitindex;
|
||||
unsigned char *wordpointer;
|
||||
};
|
||||
|
||||
#define MP3_ERR -1
|
||||
#define MP3_OK 0
|
||||
#define MP3_NEED_MORE 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void InitMpgLib(void);
|
||||
void InitMP3(struct mpstr *mp);
|
||||
int decodeMP3(struct mpstr *mp,char *inmemory,int inmemsize,
|
||||
char *outmemory,int outmemsize,int *done);
|
||||
void ExitMP3(struct mpstr *mp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,80 +0,0 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mpg123.h"
|
||||
|
||||
real decwin[512+32];
|
||||
static real cos64[16],cos32[8],cos16[4],cos8[2],cos4[1];
|
||||
real *pnts[] = { cos64,cos32,cos16,cos8,cos4 };
|
||||
|
||||
#if 0
|
||||
static unsigned char *conv16to8_buf = NULL;
|
||||
unsigned char *conv16to8;
|
||||
#endif
|
||||
|
||||
static long intwinbase[] = {
|
||||
0, -1, -1, -1, -1, -1, -1, -2, -2, -2,
|
||||
-2, -3, -3, -4, -4, -5, -5, -6, -7, -7,
|
||||
-8, -9, -10, -11, -13, -14, -16, -17, -19, -21,
|
||||
-24, -26, -29, -31, -35, -38, -41, -45, -49, -53,
|
||||
-58, -63, -68, -73, -79, -85, -91, -97, -104, -111,
|
||||
-117, -125, -132, -139, -147, -154, -161, -169, -176, -183,
|
||||
-190, -196, -202, -208, -213, -218, -222, -225, -227, -228,
|
||||
-228, -227, -224, -221, -215, -208, -200, -189, -177, -163,
|
||||
-146, -127, -106, -83, -57, -29, 2, 36, 72, 111,
|
||||
153, 197, 244, 294, 347, 401, 459, 519, 581, 645,
|
||||
711, 779, 848, 919, 991, 1064, 1137, 1210, 1283, 1356,
|
||||
1428, 1498, 1567, 1634, 1698, 1759, 1817, 1870, 1919, 1962,
|
||||
2001, 2032, 2057, 2075, 2085, 2087, 2080, 2063, 2037, 2000,
|
||||
1952, 1893, 1822, 1739, 1644, 1535, 1414, 1280, 1131, 970,
|
||||
794, 605, 402, 185, -45, -288, -545, -814, -1095, -1388,
|
||||
-1692, -2006, -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788,
|
||||
-5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597, -7910, -8209,
|
||||
-8491, -8755, -8998, -9219, -9416, -9585, -9727, -9838, -9916, -9959,
|
||||
-9966, -9935, -9863, -9750, -9592, -9389, -9139, -8840, -8492, -8092,
|
||||
-7640, -7134, -6574, -5959, -5288, -4561, -3776, -2935, -2037, -1082,
|
||||
-70, 998, 2122, 3300, 4533, 5818, 7154, 8540, 9975, 11455,
|
||||
12980, 14548, 16155, 17799, 19478, 21189, 22929, 24694, 26482, 28289,
|
||||
30112, 31947, 33791, 35640, 37489, 39336, 41176, 43006, 44821, 46617,
|
||||
48390, 50137, 51853, 53534, 55178, 56778, 58333, 59838, 61289, 62684,
|
||||
64019, 65290, 66494, 67629, 68692, 69679, 70590, 71420, 72169, 72835,
|
||||
73415, 73908, 74313, 74630, 74856, 74992, 75038 };
|
||||
|
||||
void make_decode_tables(long scaleval)
|
||||
{
|
||||
int i,j,k,kr,divv;
|
||||
real *table,*costab;
|
||||
|
||||
|
||||
for(i=0;i<5;i++)
|
||||
{
|
||||
kr=0x10>>i; divv=0x40>>i;
|
||||
costab = pnts[i];
|
||||
for(k=0;k<kr;k++)
|
||||
costab[k] = 1.0 / (2.0 * cos(M_PI * ((double) k * 2.0 + 1.0) / (double) divv));
|
||||
}
|
||||
|
||||
table = decwin;
|
||||
scaleval = -scaleval;
|
||||
for(i=0,j=0;i<256;i++,j++,table+=32)
|
||||
{
|
||||
if(table < decwin+512+16)
|
||||
table[16] = table[0] = (double) intwinbase[j] / 65536.0 * (double) scaleval;
|
||||
if(i % 32 == 31)
|
||||
table -= 1023;
|
||||
if(i % 64 == 63)
|
||||
scaleval = - scaleval;
|
||||
}
|
||||
|
||||
for( /* i=256 */ ;i<512;i++,j--,table+=32)
|
||||
{
|
||||
if(table < decwin+512+16)
|
||||
table[16] = table[0] = (double) intwinbase[j] / 65536.0 * (double) scaleval;
|
||||
if(i % 32 == 31)
|
||||
table -= 1023;
|
||||
if(i % 64 == 63)
|
||||
scaleval = - scaleval;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,10 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons media plugins mp3_reader ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
UsePrivateHeaders media ;
|
||||
|
||||
Addon mp3_reader :
|
||||
MP3ReaderPlugin.cpp
|
||||
: be libmedia.so $(TARGET_LIBSUPC++)
|
||||
;
|
File diff suppressed because it is too large
Load Diff
@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Marcus Overhagen
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef _MP3_READER_PLUGIN_H
|
||||
#define _MP3_READER_PLUGIN_H
|
||||
|
||||
#include "ReaderPlugin.h"
|
||||
|
||||
struct mp3data;
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
|
||||
class mp3Reader : public Reader
|
||||
{
|
||||
public:
|
||||
mp3Reader();
|
||||
~mp3Reader();
|
||||
|
||||
const char *Copyright();
|
||||
|
||||
status_t Sniff(int32 *streamCount);
|
||||
|
||||
void GetFileFormatInfo(media_file_format *mff);
|
||||
|
||||
status_t AllocateCookie(int32 streamNumber, void **cookie);
|
||||
status_t FreeCookie(void *cookie);
|
||||
|
||||
status_t GetStreamInfo(void *cookie, int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format, const void **infoBuffer, size_t *infoSize);
|
||||
|
||||
status_t Seek(void *cookie, uint32 flags,
|
||||
int64 *frame, bigtime_t *time);
|
||||
|
||||
status_t FindKeyFrame(void* cookie, uint32 flags,
|
||||
int64* frame, bigtime_t* time);
|
||||
|
||||
status_t GetNextChunk(void *cookie,
|
||||
const void **chunkBuffer, size_t *chunkSize,
|
||||
media_header *mediaHeader);
|
||||
|
||||
BPositionIO *Source() { return fSeekableSource; }
|
||||
|
||||
private:
|
||||
bool ParseFile();
|
||||
bool IsMp3File();
|
||||
|
||||
// checks if the buffer contains a valid mp3 stream, length should be
|
||||
bool IsValidStream(uint8 *buffer, int size);
|
||||
|
||||
int GetFrameLength(void *header);
|
||||
int GetXingVbrLength(uint8 *header);
|
||||
int GetFraunhoferVbrLength(uint8 *header);
|
||||
int GetLameVbrLength(uint8 *header);
|
||||
int GetId3v2Length(uint8 *header);
|
||||
int GetInfoCbrLength(uint8 *header);
|
||||
|
||||
bool FindData();
|
||||
|
||||
void ParseXingVbrHeader(int64 pos);
|
||||
void ParseFraunhoferVbrHeader(int64 pos);
|
||||
|
||||
int64 XingSeekPoint(float percent);
|
||||
|
||||
int64 VBRIseekPointByTime(float EntryTimeInMilliSeconds);
|
||||
int64 VBRISeekPoint(float percent);
|
||||
|
||||
bool ResynchronizeStream(mp3data *data);
|
||||
|
||||
private:
|
||||
|
||||
status_t CalculatePosition(void* cookie, uint32 flags,
|
||||
int64* frame, bigtime_t* time, off_t *position);
|
||||
bool isVBR() {return (fXingVbrInfo || fFhgVbrInfo);}
|
||||
|
||||
BPositionIO * fSeekableSource;
|
||||
int64 fFileSize;
|
||||
|
||||
int64 fDataStart;
|
||||
int64 fDataSize;
|
||||
|
||||
struct xing_vbr_info;
|
||||
struct fhg_vbr_info;
|
||||
|
||||
xing_vbr_info * fXingVbrInfo;
|
||||
fhg_vbr_info * fFhgVbrInfo;
|
||||
};
|
||||
|
||||
|
||||
class mp3ReaderPlugin : public ReaderPlugin
|
||||
{
|
||||
public:
|
||||
Reader *NewReader();
|
||||
};
|
||||
|
||||
} } // namespace BPrivate::media
|
||||
|
||||
using namespace BPrivate::media;
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user