mpeg2audio.cc
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:13k
源码类别:

DVD

开发平台:

Unix_Linux

  1. /*
  2.    File: mpeg2audio.cc
  3.    By: Alex Theo de Jong
  4.    Created: Febraury 1996
  5.    Description:
  6.    MPEG 2 Audio class. The MPEG 2 Audio decoder reads from the
  7.    stream buffer, decodes and plays the audio on the SUN Solaris 
  8.    or SGI Irix audio device.
  9. */
  10. #define RELEASE "1.2, November 1996"
  11. #ifdef __GNUG__
  12. #pragma implementation
  13. #endif
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <iomanip.h>
  18. #include <fstream.h>
  19. #include <sys/errno.h>
  20. #include <unistd.h>
  21. #ifdef IRIX
  22. #include <dmedia/audio.h>
  23. #endif
  24. #ifdef SOLARIS
  25. #include <sys/audioio.h>
  26. #endif
  27. #ifdef LINUX
  28. #include <sys/soundcard.h>
  29. #endif
  30. #include "athread.hh"
  31. #include "error.hh"
  32. #include "debug.hh"
  33. #include "util.hh"
  34. #include "sync.hh"
  35. #include "mpeg2const.hh"
  36. #include "mpeg2buff.hh"
  37. #include "mpeg2audio.hh"
  38. extern int decode_ac3(AudioStream *,Synchronization *);
  39. /*
  40.  *
  41.  * Mpeg2Audio
  42.  *
  43.  */
  44. Mpeg2Audio::Mpeg2Audio(Mpeg2Buffer* input_buffer, Synchronization* s, int audio, int c, char** v) :
  45.   verbose_mode(True),
  46.   filter_check(False),
  47.   stdout_mode(False),
  48.   which_channels(both),
  49.   use_speaker(False),
  50.   use_headphone(False),
  51.   use_line_out(False),
  52.   use_own_scalefactor(False),
  53.   argc(c),
  54.   terminate(0), terminated(0)
  55. {
  56.   sync=s;
  57.   if (input_buffer) 
  58.     stream=new AudioStream(input_buffer, sync);
  59.   else stream=0;
  60.   if (argc) argv=v;
  61.   else argv=0;
  62.   header=new Header;
  63.   buffer=0;
  64.   filter1=0;
  65.   filter2=0;
  66.   if (audio == 1) {
  67. #ifdef DEBUG
  68.     Mpeg2Audio::player(this);
  69. #else
  70.     if (athr_create((void*(*)(void*))Mpeg2Audio::player, this, &thread_id)<0){
  71.       error("could not create audio player");
  72.       athr_exit(0);
  73.     }
  74. #endif
  75.   }
  76.   else {
  77. #ifdef DEBUG
  78.     Mpeg2Audio::ac3_player(this);
  79. #else
  80.     if (athr_create((void*(*)(void*))Mpeg2Audio::ac3_player, this, &thread_id)<0){
  81.       error("could not create audio player");
  82.       athr_exit(0);
  83.     }
  84. #endif
  85.   }
  86.   sched_param param;
  87.   int policy;
  88.   if (athr_getschedparam(thread_id, &policy, &param)<0){
  89.     error("could not get thread priority");
  90.   }
  91. #ifdef LINUX
  92.   param.sched_priority+=2;
  93. //  policy = SCHED_RR;
  94.   TRACER("AUDIOPRIORITY=" << param.sched_priority << "(" << param.sched_priority-2 << ")");
  95. #else
  96.   param.prio+=2;
  97.   TRACER("AUDIOPRIORITY=" << param.prio << "(" << param.prio-2 << ")");
  98. #endif
  99.   if (athr_setschedparam(thread_id, policy, &param)<0){
  100.     error("could not set thread priority");
  101.   }
  102. }
  103. Mpeg2Audio::~Mpeg2Audio(){
  104.   TRACER("Mpeg2Audio::~Mpeg2Audio()");
  105. //  terminate=1;
  106.   if (!terminated){
  107.     TRACER("waiting for audio thread ...");
  108.     athr_join(thread_id);
  109.     // In order to play TS stream without audio it shouln't wait here
  110.     // This is a bug that needs to be fixed somewhere else.
  111.     // Just a temporary fix.  Alex 05/27/96
  112.   }
  113.   TRACER("audio thread donenDeleting audio stuff ... ");
  114.   delete stream;
  115.   delete header;
  116.   delete buffer;
  117.   delete filter1;
  118.   delete filter2;
  119.   TRACER("audio thread done");
  120. }
  121. void* Mpeg2Audio::player(Mpeg2Audio* base){
  122.   base->terminated=0;
  123.   base->terminate=0;
  124.   if (base->options())
  125.     base->play();
  126.   base->terminated=1;
  127.   TRACER("audio thread terminated");
  128.   athr_exit(0);
  129.   return 0;
  130. }
  131. void* Mpeg2Audio::ac3_player(Mpeg2Audio* base){
  132.   base->terminated=0;
  133.   base->terminate=0;
  134.   decode_ac3(base->stream,base->sync);
  135.   base->terminated=1;
  136.   TRACER("audio thread terminated");
  137.   athr_exit(0);
  138.   return 0;
  139. }
  140. void Mpeg2Audio::usage(const char* name){
  141.   msg("usage: "); msg(name); message(" <filename> [options]");
  142.   message("options:");
  143.   message("t-qtquiet");
  144.   message("t-ltdecode only the left channel");
  145.   message("t-rtdecode only the right channel");
  146.   message("t-uxtsend audio signal to speaker(x:s), headphone (x:h), line out (x:l)");
  147.   message("t-ctcheck for filter range violations");
  148.   message("t-fntuse this (n) scalefactor instead of the default value 32768");
  149.   message("");
  150.   message("tMPEG 2 Audio Playern");
  151.   msg("tversion "); message(RELEASE);
  152.   message("tAlex Theo de Jong (e-mail: alex.dejong@nist.gov)n");
  153.   message("tMulti-Media and Digital Video Group");
  154.   message("tNational Institute of Standards and Technology");
  155.   message("tGaithersburg, Md, U.S.A.nn");
  156.   message("");
  157.   message("Original code by:");
  158.   message("tTobias Bading");
  159.   message("tBerlin University of Technology, Germany");
  160. }  
  161. int Mpeg2Audio::options(){
  162.   if (argc < 2 || argv[1][0]=='-'){
  163.     usage(argv[0]);
  164.     return 0;
  165.   }
  166.   filename=argv[1];
  167.   for (int i=2; i < argc; i++){
  168.     if (argv[i][0] == '-' && argv[i][1])
  169.       switch (argv[i][1]){
  170.       case 'q': verbose_mode = False; break;
  171.   case 's': stdout_mode = True;  break;
  172.      case 'l': which_channels = left; break;
  173.   case 'r': which_channels = right; break;
  174.   case 'u':
  175.     switch (argv[i][2]){
  176.     case 's': use_speaker = True; break;
  177.     case 'h': use_headphone = True; break;
  178.     case 'l': use_line_out = True; break;
  179.   }
  180.   break;
  181.      case 'c': filter_check = True; break;
  182.   case 'f':
  183.         use_own_scalefactor = True;
  184.         scalefactor=atoi(&argv[i][2]);
  185.         break;
  186.   default: msg("unknown option "); msg(argv[i]); message(" - ignored");
  187.     }
  188.   }
  189.   if (!(use_speaker || use_headphone || use_line_out)) use_speaker=True;
  190.   return 1;
  191. }
  192. int Mpeg2Audio::play(){
  193.   bool read_ready = False, write_ready = False;
  194.   if (!stream) stream=new AudioStream(filename); // read from file
  195.   if (!header->read_header(stream, &crc)) {
  196.     error("no header found!");
  197.     athr_exit(0);
  198.   }
  199.   // get info from header of first frame:
  200.   layer = header->layer ();
  201.   if ((mode = header->mode ()) == single_channel)
  202.     which_channels = left;
  203.   sample_frequency = header->sample_frequency ();
  204.   // create filter(s):
  205.   if (use_own_scalefactor) filter1 = new SynthesisFilter(0, scalefactor);
  206.   else                     filter1 = new SynthesisFilter(0);
  207.   if (mode != single_channel && which_channels == both)
  208.     if (use_own_scalefactor) filter2 = new SynthesisFilter(1, scalefactor);
  209.     else                     filter2 = new SynthesisFilter(1);
  210.   // create buffer:
  211.   if (stdout_mode)
  212. #ifdef IRIX
  213.     buffer=0;
  214. #else
  215.     if (mode == single_channel || which_channels != both)
  216.       buffer = new ShortObuffer(1);
  217.     else
  218.       buffer = new ShortObuffer (2);
  219. #endif
  220.   else
  221. #ifdef IRIX
  222.     if (mode == single_channel || which_channels != both)
  223.          buffer = new IrixObuffer (1, header);
  224.     else buffer = new IrixObuffer (2, header);
  225. #else
  226. #ifdef SOLARIS
  227.     if (SparcObuffer::class_suitable()){
  228.       if (mode == single_channel || which_channels != both)
  229.         buffer = new SparcObuffer (1, header, use_speaker, use_headphone, use_line_out);
  230.       else
  231.         buffer = new SparcObuffer (2, header, use_speaker, use_headphone, use_line_out);
  232.     }
  233.     else {
  234.       error("Sorry, no suitable audio device detected, please use stdout mode");
  235.       athr_exit(0);
  236.     }
  237. #else
  238. #ifdef LINUX
  239.     if (LinuxObuffer::class_suitable()){
  240.       if (mode == single_channel || which_channels != both)
  241.         buffer = new LinuxObuffer (1, header);
  242.       else
  243.         buffer = new LinuxObuffer (2, header);
  244.     }
  245.     else {
  246.       error("Sorry, no suitable audio device detected, please use stdout mode");
  247.       athr_exit(0);
  248.     }
  249. #endif  // !LINUX
  250. #endif // !SOLARIS
  251. #endif // !IRIX
  252.   if (!buffer){
  253.     error("no audio device available");
  254.     return 0;
  255.   }
  256.   if (verbose_mode){
  257.     // print informations about the stream
  258.     char *name = strrchr (filename, '/');
  259.     if (name) ++name;
  260.     else        name = filename;
  261.     cerr << name << " is a layer " << header->layer_string () << ' '
  262.  << header->mode_string () << " MPEG audio stream with";
  263.     if (!header->checksums ())
  264.       cerr << "out";
  265.     cerr << " checksums.nThe sample frequency is "
  266.  << header->sample_frequency_string () << " at a bitrate of "
  267.  << header->bitrate_string () << ".n"
  268.     "This stream is ";
  269.     if (header->original ()) cerr << "an original";
  270.     else                     cerr << "a copy";
  271.     cerr << " and is ";
  272.     if (!header->copyright ()) cerr << "not ";
  273.     cerr << "copyright protected.n";
  274.   }
  275.   do {
  276.     // is there a change in important parameters?
  277.     // (bitrate switching is allowed)
  278.     if (header->layer () != layer){
  279.       // layer switching is allowed
  280.       if (verbose_mode)
  281.         cerr << "switching to layer " << header->layer_string () << ".n";
  282.       layer = header->layer ();
  283.     }
  284.     if ((mode == single_channel && header->mode () != single_channel) ||
  285. (mode != single_channel && header->mode () == single_channel)){
  286.       // switching from single channel to stereo or vice versa is not allowed
  287.       error("illegal switch from single channel to stereo or vice versa!");
  288.       athr_exit(0);
  289.     }
  290.     if (header->sample_frequency () != sample_frequency){
  291.       // switching the sample frequency is not allowed
  292.       error("sorry, can't switch the sample frequency in the middle of the stream!");
  293.       athr_exit(0);
  294.     }
  295.     unsigned int i=0;
  296.     // create subband objects:
  297.     if (header->layer()==1){
  298.       if (header->mode()==single_channel)
  299.         for (i=0; i<header->number_of_subbands(); ++i)
  300.           subbands[i]=new SubbandLayer1(i);
  301.       else if (header->mode()==joint_stereo){
  302.         for (i=0; i<header->intensity_stereo_bound(); ++i)
  303.           subbands[i]=new SubbandLayer1Stereo(i);
  304.         for (; i<header->number_of_subbands(); ++i)
  305.           subbands[i]=new SubbandLayer1IntensityStereo(i);
  306.       }
  307.       else
  308.         for (i=0; i<header->number_of_subbands(); ++i)
  309.           subbands[i]=new SubbandLayer1Stereo(i);
  310.     }
  311.     else if (header->layer()==2){
  312.       if (header->mode()==single_channel)
  313.         for (i = 0; i<header->number_of_subbands (); ++i)
  314.           subbands[i] = new SubbandLayer2 (i);
  315.       else if (header->mode () == joint_stereo){
  316.         for (i = 0; i < header->intensity_stereo_bound (); ++i)
  317.           subbands[i] = new SubbandLayer2Stereo (i);
  318.         for (; i < header->number_of_subbands (); ++i)
  319.           subbands[i] = new SubbandLayer2IntensityStereo (i);
  320.       }
  321.       else
  322.         for (i = 0; i < header->number_of_subbands (); ++i)
  323.           subbands[i] = new SubbandLayer2Stereo (i);
  324.     }
  325.     else {
  326.       error("sorry, layer 3 not implemented!");
  327.       athr_exit(0);
  328.     }
  329.     
  330.     // start to read audio data:
  331.     for (i = 0; i < header->number_of_subbands(); ++i)
  332.       subbands[i]->read_allocation (stream, header, crc);
  333.     
  334.     if (header->layer()==2)
  335.       for (i = 0; i < header->number_of_subbands(); ++i)
  336.         ((SubbandLayer2 *)subbands[i])->read_scalefactor_selection (stream, crc);
  337.     
  338.     if (!crc || header->checksum_ok()){
  339.         // no checksums or checksum ok, continue reading from stream:
  340.         for (i = 0; i < header->number_of_subbands (); ++i)
  341.           subbands[i]->read_scalefactor (stream, header);
  342.         
  343.         do
  344.           {
  345.             for (i = 0; i < header->number_of_subbands (); ++i)
  346.               read_ready = subbands[i]->read_sampledata (stream);
  347.             
  348.             do
  349.               {
  350.               for (i = 0; i < header->number_of_subbands (); ++i)
  351.                 write_ready = subbands[i]->put_next_sample (which_channels, filter1, filter2);
  352.               
  353.               filter1->calculate_pcm_samples (buffer);
  354.               if (which_channels == both && header->mode () != single_channel)
  355.                 filter2->calculate_pcm_samples (buffer);
  356.             }
  357.             while (!write_ready);
  358.           }
  359.         while (!read_ready);
  360.         
  361.         if (sync) sync->wait(2); // wait for PTS, id=2, if <0, end of file
  362.         buffer->write_buffer(1); // write to stdout
  363.       }
  364.     else
  365.       // Sh*t! Wrong crc checksum in frame!
  366.       cerr << "WARNING: frame contains wrong crc checksum! (throwing frame away)n";
  367.     
  368.     for (i=0; i < header->number_of_subbands (); ++i) delete subbands[i];
  369.   }
  370.   while (!terminate && header->read_header(stream, &crc) && (!sync || !sync->done(2)));
  371.  
  372.   uint32 range_violations = filter1->violations ();
  373.   if (mode != single_channel && which_channels == both)
  374.    range_violations += filter2->violations ();
  375.   if (filter_check){
  376.     // check whether (one of) the filter(s) produced values not in [-1.0, 1.0]:
  377.     if (range_violations){
  378.       cerr << range_violations << " range violations have occured!n";
  379.       if (stdout_mode)
  380.         cerr << "If you notice these violations,n";
  381.       else
  382.         cerr << "If you have noticed these violations,n";
  383.       cerr << "please use the -f option with the value ";
  384.       if (mode != single_channel && which_channels == both &&
  385.           filter2->hardest_violation () > filter1->hardest_violation ())
  386.         cerr << filter2->recommended_scalefactor ();
  387.       else
  388.         cerr << filter1->recommended_scalefactor ();
  389.       cerr << "nor a greater value up to 32768 and try again.n";
  390.     }
  391.   }
  392.   if (verbose_mode){
  393.     // print playtime of stream:
  394.     real playtime = filter1->seconds_played (Header::frequency (sample_frequency));
  395.     uint32 minutes = (uint32)(playtime / 60.0);
  396.     uint32 seconds = (uint32)playtime - minutes * 60;
  397.     uint32 centiseconds = (uint32)((playtime - (real)(minutes * 60) - (real)seconds) * 100.0);
  398.     cerr << "end of stream, playtime: " << minutes << ':'
  399.       << setw (2) << setfill ('0')
  400.  << seconds << '.'
  401.  << setw (2) << setfill ('0')
  402.  << centiseconds << 'n';
  403.   }
  404.   return 0;
  405. }