vdr-plugin-femon/ac3.c

94 lines
2.8 KiB
C
Raw Permalink Normal View History

/*
2015-03-07 21:32:58 +01:00
* ac3.c: Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
* AC3 Audio Header: http://www.atsc.org/standards/a_52a.pdf
*/
2015-03-07 21:32:58 +01:00
#include "tools.h"
#include "ac3.h"
2015-03-07 17:22:02 +01:00
int cFemonAC3::bitrateS[32] =
{
32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
2015-03-07 17:22:02 +01:00
int cFemonAC3::frequencieS[4] =
{
480, 441, 320, 0
};
2015-03-07 17:22:02 +01:00
int cFemonAC3::frameS[3][32] =
2009-08-25 19:22:06 +02:00
{
{64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 640, 768, 896, 1024, 1152, 1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{69, 87, 104, 121, 139, 174, 208, 243, 278, 348, 417, 487, 557, 696, 835, 975, 1114, 1253, 1393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{96, 120, 144, 168, 192, 240, 288, 336, 384, 480, 576, 672, 768, 960, 1152, 1344, 1536, 1728, 1920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
2015-03-07 17:22:02 +01:00
cFemonAC3::cFemonAC3(cFemonAC3If *audioHandlerP)
: audioHandlerM(audioHandlerP)
2009-08-25 19:22:06 +02:00
{
}
2009-08-25 19:22:06 +02:00
cFemonAC3::~cFemonAC3()
{
2009-08-25 19:22:06 +02:00
}
2015-03-07 17:22:02 +01:00
bool cFemonAC3::processAudio(const uint8_t *bufP, int lenP)
2009-08-25 19:22:06 +02:00
{
2009-08-26 21:44:49 +02:00
int fscod, frmsizcod, bsmod, acmod;
int centermixlevel = AUDIO_CENTER_MIX_LEVEL_INVALID;
int surroundmixlevel = AUDIO_SURROUND_MIX_LEVEL_INVALID;
int dolbysurroundmode = AUDIO_DOLBY_SURROUND_MODE_INVALID;
2015-03-07 17:22:02 +01:00
cFemonBitStream bs(bufP, lenP * 8);
2009-08-25 19:22:06 +02:00
2015-03-07 17:22:02 +01:00
if (!audioHandlerM)
return false;
2009-08-25 19:22:06 +02:00
// skip PES header
2015-03-07 17:22:02 +01:00
if (!PesLongEnough(lenP))
2009-08-25 19:22:06 +02:00
return false;
2015-03-07 17:22:02 +01:00
bs.SkipBits(8 * PesPayloadOffset(bufP));
2009-08-25 19:22:06 +02:00
// http://rmworkshop.com/dvd_info/related_info/ac3hdr.htm
// AC3 audio detection
2011-11-19 15:02:16 +01:00
if (bs.GetBits(16) != 0x0B77) // syncword
2009-08-25 19:22:06 +02:00
return false;
2011-11-19 15:02:16 +01:00
bs.SkipBits(16); // CRC1
2009-08-25 19:22:06 +02:00
2011-11-19 15:02:16 +01:00
fscod = bs.GetBits(2); // sampling rate values
frmsizcod = bs.GetBits(6); // frame size code
2009-08-25 19:22:06 +02:00
2011-11-19 15:02:16 +01:00
bs.SkipBits(5); // bitstream id
bsmod = bs.GetBits(3); // bitstream mode
acmod = bs.GetBits(3); // audio coding mode
2009-08-25 19:22:06 +02:00
// 3 front channels
2009-08-26 21:44:49 +02:00
if ((acmod & 0x01) && (acmod != 0x01))
2011-11-19 15:02:16 +01:00
centermixlevel = bs.GetBits(2);
2009-08-26 21:44:49 +02:00
2009-08-25 19:22:06 +02:00
// if a surround channel exists
2009-08-26 21:44:49 +02:00
if (acmod & 0x04)
2011-11-19 15:02:16 +01:00
surroundmixlevel = bs.GetBits(2);
2009-08-26 21:44:49 +02:00
2009-08-25 19:22:06 +02:00
// if in 2/0 mode
2009-08-26 21:44:49 +02:00
if (acmod == 0x02)
2011-11-19 15:02:16 +01:00
dolbysurroundmode = bs.GetBits(2);
2009-08-26 21:44:49 +02:00
2015-03-07 17:22:02 +01:00
audioHandlerM->SetAC3Bitrate(1000 * bitrateS[frmsizcod >> 1]);
audioHandlerM->SetAC3SamplingFrequency(100 * frequencieS[fscod]);
audioHandlerM->SetAC3Bitstream(bsmod);
audioHandlerM->SetAC3AudioCoding(acmod);
audioHandlerM->SetAC3CenterMix(centermixlevel);
audioHandlerM->SetAC3SurroundMix(surroundmixlevel);
audioHandlerM->SetAC3DolbySurround(dolbysurroundmode);
2009-08-25 19:22:06 +02:00
2015-03-07 17:22:02 +01:00
audioHandlerM->SetAC3LFE(bs.GetBit()); // low frequency effects on
audioHandlerM->SetAC3Dialog(bs.GetBits(5)); // dialog normalization
2009-08-25 19:22:06 +02:00
return true;
}