header.cc
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:6k
- /*
- File: header.cc
- */
- #ifdef __GNUG__
- #pragma implementation
- #endif
- #include <stdio.h>
- #include <stdlib.h>
- #include <fstream.h>
- #include <iomanip.h>
- #include "athread.hh"
- #include "error.hh"
- #include "debug.hh"
- #include "util.hh"
- #include "sync.hh"
- #include "mpeg2const.hh"
- #include "mpeg2buff.hh"
- #include "astream.hh"
- #include "crc.hh"
- #include "header.hh"
- const uint32 Header::frequencies[3] = { 44100, 48000, 32000 };
- int Header::read_header(AudioStream *stream, Crc16 **crcp){
- TRACER("bool Header::read_header(AudioStream *stream, Crc16 **crcp)");
- uint32 headerstring=0;
- if (stream->get_header(headerstring)==False){
- cerr << "invalid syncword 0x" << hex << setw (3) << setfill ('0')
- << ((headerstring & 0xfff00000) >> 20)
- << " found at fileoffset " << dec << 'n';
- TRACER("could not get_header");
- return 0;
- }
- if ((headerstring & 0xf0000000) == 0x80000000)
- return 2; /* Ac-3 audio */
- #ifdef NOT // moved to get_header to recover from errors
- if ((headerstring & 0xfff00000) != 0xfff00000){
- cerr << "invalid syncword 0x" << hex << setw (3) << setfill ('0')
- << ((headerstring & 0xfff00000) >> 20)
- << " found at fileoffset " << dec << 'n';
- // Try to recover from errors
- while ((headerstring & 0xFFF00000) != 0xFFF00000)
- if (!stream->get_header(headerstring)) return False;
- }
- #endif
- if ((h_layer = (headerstring >> 17) & 3) == 0){
- cerr << "unknown layer identifier found!n";
- exit (1);
- }
- h_layer = 4 - h_layer; // now 1 means Layer I and 3 means Layer III
- if (h_layer == 3){
- cerr << "Sorry, Layer III not implemented!n";
- exit (1);
- }
- h_protection_bit = (headerstring >> 16) & 1;
- if ((h_bitrate_index = (headerstring >> 12) & 0xF) == 15){
- cerr << "unknown bitrate index found!n";
- exit (1);
- }
- if (!h_bitrate_index){
- cerr << "free format not yet implemented!n";
- exit (1);
- }
- if ((h_sample_frequency = (e_sample_frequency)((headerstring >> 10) & 3)) == 3){
- cerr << "unknown sample frequency!n";
- exit (1);
- }
- h_padding_bit = (headerstring >> 9) & 1;
- h_mode = (e_mode)((headerstring >> 6) & 3);
- if (h_layer == 2)
- // testing validity of mode and bitrate:
- if ((((h_bitrate_index >= 1 && h_bitrate_index <= 3) || h_bitrate_index == 5) &&
- h_mode != single_channel) ||
- (h_bitrate_index >= 11 && h_mode == single_channel))
- {
- cerr << "illegal combination of mode and bitrate in a layer II stream:n"
- " mode: " << mode_string ()
- << "n bitrate: " << bitrate_string () << 'n';
- exit (1);
- }
- h_mode_extension = (headerstring >> 4) & 3;
- if (h_mode == joint_stereo)
- h_intensity_stereo_bound = (h_mode_extension << 2) + 4;
- else h_intensity_stereo_bound = 0; // should never be used
- h_copyright = ((headerstring >> 3) & 1) ? True : False;
- h_original = ((headerstring >> 2) & 1) ? True : False;
- // calculate number of subbands:
- if (h_layer == 1) h_number_of_subbands = 32;
- else {
- uint32 channel_bitrate = h_bitrate_index;
- // calculate bitrate per channel:
- if (h_mode != single_channel)
- if (channel_bitrate == 4)
- channel_bitrate = 1;
- else
- channel_bitrate -= 4;
- if (channel_bitrate == 1 || channel_bitrate == 2)
- if (h_sample_frequency == thirtytwo)
- h_number_of_subbands = 12;
- else
- h_number_of_subbands = 8;
- else
- if (h_sample_frequency == fourtyeight || (channel_bitrate >= 3 && channel_bitrate <= 5))
- h_number_of_subbands = 27;
- else
- h_number_of_subbands = 30;
- }
- if (h_intensity_stereo_bound > h_number_of_subbands)
- h_intensity_stereo_bound = h_number_of_subbands;
- // read framedata:
- if (!stream->read_frame (calculate_framesize ())) return False;
- if (!h_protection_bit){
- // frame contains a crc checksum
- checksum = (uint16)stream->get_bits (16);
- if (!crc) crc = new Crc16;
- crc->add_bits (headerstring, 16);
- *crcp = crc;
- }
- else *crcp = (Crc16 *)0;
- return 1;
- }
- uint32 Header::calculate_framesize(){
- /* calculates framesize in bytes excluding header size */
- static const uint32 bitrates_layer_1[15] = {
- 0 /*free format*/, 32000, 64000, 96000, 128000, 160000, 192000,
- 224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000 };
- static const uint32 bitrates_layer_2[15] = {
- 0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000,
- 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000 };
- static const uint32 samplefrequencies[3] = { 44100, 48000, 32000 };
- uint32 framesize;
- if (h_layer == 1)
- {
- framesize = (12 * bitrates_layer_1[h_bitrate_index]) / samplefrequencies[h_sample_frequency];
- if (h_sample_frequency == fourtyfour_point_one && h_padding_bit)
- ++framesize;
- framesize <<= 2; // one slot is 4 bytes long
- }
- else
- {
- framesize = (144 * bitrates_layer_2[h_bitrate_index]) / samplefrequencies[h_sample_frequency];
- if (h_sample_frequency == fourtyfour_point_one && h_padding_bit)
- ++framesize;
- }
- return framesize - 4; // subtract header size
- }
- const char *Header::layer_string (void){
- switch (h_layer){
- case 1: return "I";
- case 2: return "II";
- case 3: return "III (not implemented!)";
- }
- return NULL; // dummy
- }
- const char *Header::bitrate_string (void){
- static const char *layer1_bitrates[16] = {
- "free format", "32 kbis/s", "64 kbit/s", "96 kbit/s", "128 kbit/s", "160 kbit/s",
- "192 kbit/s", "224 kbit/s", "256 kbit/s", "288 kbit/s", "320 kbit/s", "352 kbit/s",
- "384 kbit/s", "416 kbit/s", "448 kbit/s", "forbidden"
- };
- static const char *layer2_bitrates[16] = {
- "free format", "32 kbis/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",
- "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s", "192 kbit/s", "224 kbit/s",
- "256 kbit/s", "320 kbit/s", "384 kbit/s", "forbidden"
- };
- if (h_layer == 1)
- return layer1_bitrates[h_bitrate_index];
- else
- return layer2_bitrates[h_bitrate_index];
- }
- const char *Header::sample_frequency_string (void)
- {
- switch (h_sample_frequency)
- {
- case thirtytwo:
- return "32 kHz";
- case fourtyfour_point_one:
- return "44.1 kHz";
- case fourtyeight:
- return "48 kHz";
- }
- return NULL; // dummy
- }
- const char *Header::mode_string (void)
- {
- switch (h_mode)
- {
- case stereo:
- return "stereo";
- case joint_stereo:
- return "joint stereo";
- case dual_channel:
- return "dual channel";
- case single_channel:
- return "single channel";
- }
- return NULL; // dummy
- }