You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdemultimedia/mpeglib/lib/splay/mpegAudioHeader.cpp

269 lines
6.2 KiB

/*
stores information after we found a header.
Copyright (C) 2000 Martin Vogt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation.
For more information look at the file COPYRIGHT in this package
*/
#include "mpegAudioHeader.h"
#define DEBUG_HEADER(x)
//#define DEBUG_HEADER(x) x
#include <iostream>
using namespace std;
static const int frequencies[3][3]= {
{44100,48000,32000}, // MPEG 1
{22050,24000,16000}, // MPEG 2
{11025,12000,8000} // MPEG 2.5
};
static int translate[3][2][16] = { { { 2,0,0,2,2,2,3,3,3,3,3,3,3,3,3,2 } ,
{ 2,0,0,0,0,0,0,2,2,2,3,3,3,3,3,2 } } ,
{ { 2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2 } ,
{ 2,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2 } } ,
{ { 2,1,1,2,2,2,3,3,3,3,3,3,3,3,3,2 } ,
{ 2,1,1,1,1,1,1,2,2,2,3,3,3,3,3,2 } } };
static int sblims[5] = { 8 , 12 , 27, 30 , 30 };
static const int bitrate[2][3][15]= {
// MPEG 1
{{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}},
// MPEG 2
{{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}}
};
MpegAudioHeader::MpegAudioHeader() {
}
MpegAudioHeader::~MpegAudioHeader() {
}
int MpegAudioHeader::getChannelbitrate() {
cout << "getChannelbitrate not implemented"<<endl;
return 0;
}
int MpegAudioHeader::parseHeader(unsigned char* buf){
int c;
int mpeg25=false;
// Analyzing
header[0]=buf[0];
header[1]=buf[1];
header[2]=buf[2];
header[3]=buf[3];
c=buf[1];
lmpeg25=false;
if ( (c&0xf0) == 0xe0) {
lmpeg25=true;
}
c&=0xf;
protection=c&1;
layer=4-((c>>1)&3);
// we catch the layer==4 error later, for now go on with parsing
version=(int)(((c>>3)&1)^1);
if ((version==0) && lmpeg25) {
DEBUG_HEADER(cout << "wrong lsf/mpeg25 combination"<<endl;)
return false;
}
c=buf[2];
c=((c))>>1;
padding=(c&1);
c>>=1;
frequency=(int)(c&3);
c>>=2;
bitrateindex=(int)c;
if(bitrateindex>=15) {
DEBUG_HEADER(cout << "bitrateindex error"<<endl;)
return false;
}
c=buf[3];
c=((unsigned int)(c))>>4;
extendedmode=c&3;
mode=(int)(c>>2);
// Making information
inputstereo= (mode==_MODE_SINGLE)?0:1;
//
// frequency can be 0,1 or 2 but the mask above allows 3 as well
// check now.
if (frequency > 2) {
DEBUG_HEADER(cout << "frequency value out of range"<<endl;)
return false;
}
//
// does not belong here should be in the layer specific parts. [START]
//
switch(layer) {
case 3:
subbandnumber=0;
stereobound=0;
tableindex=0;
break;
case 2:
tableindex = translate[frequency][inputstereo][bitrateindex];
subbandnumber = sblims[tableindex];
stereobound = subbandnumber;
/*
Now merge the tableindex, for the bitalloclengthtable
*/
tableindex=tableindex>>1;
if(mode==_MODE_SINGLE)stereobound=0;
if(mode==_MODE_JOINT)stereobound=(extendedmode+1)<<2;
break;
case 1:
subbandnumber=MAXSUBBAND;
stereobound=subbandnumber;
tableindex=0;
if(mode==_MODE_SINGLE)stereobound=0;
if(mode==_MODE_JOINT)stereobound=(extendedmode+1)<<2;
break;
default:
DEBUG_HEADER(cout <<"unknown layer"<<endl;)
return false;
}
//
// does not belong here should be in the layer specific parts. [END]
//
frequencyHz=frequencies[version+lmpeg25][frequency];
// framesize & slots
if(layer==1) {
if (frequencyHz <= 0) {
return false;
}
framesize=(12000*bitrate[version][0][bitrateindex])/frequencyHz;
if(frequency==_FREQUENCY_44100 && padding)framesize++;
framesize<<=2;
} else {
int freq=frequencyHz<<version;
if (freq <= 0) {
return false;
}
framesize=(144000*bitrate[version][layer-1][bitrateindex])/freq;
if(padding)framesize++;
if(layer==3) {
if(version)
layer3slots=framesize-((mode==_MODE_SINGLE)?9:17)
-(protection?0:2)
-4;
else
layer3slots=framesize-((mode==_MODE_SINGLE)?17:32)
-(protection?0:2)
-4;
}
}
if (framesize <= 0) {
DEBUG_HEADER(cout << "framesize negative"<<endl;)
return false;
}
return true;
}
int MpegAudioHeader::getpcmperframe() {
int s;
s=32;
if(layer==3) {
s*=18;
if(version==0)s*=2;
}
else {
s*=SCALEBLOCK;
if(layer==2)s*=3;
}
return s;
}
void MpegAudioHeader::copyTo(MpegAudioHeader* dest) {
dest->protection=protection;
dest->layer=layer;
dest->version=version;
dest->padding=padding;
dest->frequency=frequency;
dest->frequencyHz=frequencyHz;
dest->bitrateindex=bitrateindex;
dest->extendedmode=extendedmode;
dest->mode=mode;
dest->inputstereo=inputstereo;
dest->channelbitrate=channelbitrate;
dest->tableindex=tableindex;
dest->subbandnumber=subbandnumber;
dest->stereobound=stereobound;
dest->framesize=framesize;
dest->layer3slots=layer3slots;
dest->lmpeg25=lmpeg25;
}
void MpegAudioHeader::print(const char* name) {
cout << "MpegAudioHeader [START]:"<<name<<endl;
printf("header:%1x%1x%1x%1x\n",header[0],header[1],header[2],header[3]);
cout << "getProtection:"<<getProtection()<<endl;
cout << "getLayer:"<<getLayer()<<endl;
cout << "getVersion:"<<getVersion()<<endl;
cout << "getPadding:"<<getPadding()<<endl;
cout << "getFrequency:"<<getFrequency()<<endl;
cout << "getFrequencyHz:"<<getFrequencyHz()<<endl;
cout << "getBitrateindex:"<<getBitrateindex()<<endl;
cout << "getExtendedmode:"<<getExtendedmode()<<endl;
cout << "getMode():"<<getMode()<<endl;
cout << "getInputstereo:"<<getInputstereo()<<endl;
cout << "getChannelbitrate:"<<getChannelbitrate()<<endl;
cout << "getTableindex:"<<getTableindex()<<endl;
cout << "getSubbandnumber:"<<getSubbandnumber()<<endl;
cout << "getStereobound:"<<getStereobound()<<endl;
cout << "getFramesize:"<<getFramesize()<<endl;
cout << "getLayer3slots:"<<getLayer3slots()<<endl;
cout << "getpcmperframe:"<<getpcmperframe()<<endl;
cout << "MpegAudioHeader [END]:"<<name<<endl;
}