⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 towave.c

📁 FreeAMP(MP3播放)程序源代码-用来研究MP3解码
💻 C
📖 第 1 页 / 共 2 页
字号:
   DEC_INFO  decinfo;
   int       bitrate;

/*------------------------------------------*/
/*   typedef struct
   {
      int (*decode_init) (MPEG_HEAD * h, int framebytes_arg,
                          int reduction_code, int transform_code,
                          int convert_code, int freq_limit);
      void (*decode_info) (DEC_INFO * info);
        IN_OUT(*decode) (unsigned char *bs, short *pcm);
   }
   AUDIO;
   static AUDIO audio;
   static AUDIO audio_table[2][2] =
   {
      {
         {audio_decode_init, audio_decode_info, audio_decode},
         {audio_decode8_init, audio_decode8_info, audio_decode8},
      },
      {
         {i_audio_decode_init, i_audio_decode_info, i_audio_decode},
         {audio_decode8_init, audio_decode8_info, audio_decode8},
      }
   };
*/
/*------------------------------------------*/

/*-----------------------*/
   printf("\nMPEG input file: %s", filename);
   printf("\n    output file: %s", fileout);
/*-----------------------*/
/*-----select decoder --------------*/
/*   if (decode8_flag && (convert_code >= 4))
      audio = audio_table[integer & 1][1];
   else
      audio = audio_table[integer & 1][0]; */
/*-----------------------*/

   mpeg_init(&m, 1);
   in_bytes = out_bytes = 0;
/*-----------------------*/
   handout = -1;
   pcm_buffer = NULL;
   pcm_bufbytes = 0;
/*-----------------------*/
   bs_buffer = NULL;
   handle = -1;
   bs_bufbytes = 0;
   bs_bufptr = bs_buffer;
   bs_trigger = 2500;
/*--- test for valid cvt_to_wave compile ---*/
   if (cvt_to_wave_test() != 0)
   {
      printf("\n INVALID CVT_TO_WAVE COMPILE");
      goto abort;
   }
/*------ open mpeg file --------*/
   handle = open(filename, O_RDONLY | O_BINARY);
   if (handle < 0)
   {
      printf("\n CANNOT_OPEN_INPUT_FILE\n");
      goto abort;
   }
/*--- allocate bs buffer ----*/
   bs_buffer = malloc(BS_BUFBYTES);
   if (bs_buffer == NULL)
   {
      printf("\n CANNOT_ALLOCATE_BUFFER\n");
      goto abort;
   }
/*--- fill bs buffer ----*/
   if (!bs_fill())
      goto abort;
/*---- parse mpeg header  -------*/
   framebytes = head_info2(bs_buffer, bs_bufbytes, &head, &bitrate);
   if (framebytes == 0)
   {
      printf("\n BAD OR UNSUPPORTED MPEG FILE\n");
      goto abort;
   }
/*--- display mpeg info --*/
   out_mpeg_info(&head, bitrate);

/*---- create pcm file ------*/
   handout =
      open(fileout, O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
   handout = open(fileout, O_WRONLY | O_BINARY);
/*
   {
       int fd;
       int channels = 2;
       int play_precision = 16;
       int play_stereo = channels-1;
       int play_sample_rate = 44100; //info->samples_per_second;
       int junkvar = 0;
       int flags;
       if ((fd = open("/dev/dsp", O_WRONLY | O_SYNC, 0)) < 0) {
           if (errno == EBUSY) {
               printf("Audio device busy!\n");
               exit(1);
           } else {
               printf("Can't open /dev/dsp for writing");
               exit(1);
           }
       }
       
       if ((flags = fcntl(fd,F_GETFL,0)) < 0) {
           printf("fcntl F_GETFL on /dev/audio failed");
           exit(1);
       }
       flags &= ~O_NDELAY;
       
       if (fcntl(fd, F_SETFL, flags) < 0) {
           printf("fcntl F_SETFL on /dev/audio failed");
           exit(1);
       }
       
       handout = fd;

       
       if (handout < 0) {
           printf ("Internal error, LinuxObuffer::handout has to be initialized\nby LinuxObuffer::class_suitable()!\n");
           exit (1);
       }
       
       // configure the device:
       //int play_precision = 16;
       //int play_stereo = channels-1;
       //int play_sample_rate = info->samples_per_second;
       //int junkvar = 0;
       if (ioctl(handout, SNDCTL_DSP_RESET, &junkvar) == -1) {
           printf("hosed during ioctl reset\n");
           exit(1);
       } 
       
       if(ioctl(handout, SNDCTL_DSP_SAMPLESIZE, &play_precision) == -1) {
           printf("config of samplesize failed");
           exit(1);
       }
       if(ioctl(handout, SNDCTL_DSP_STEREO, &play_stereo) == -1) {
           printf("config of stereo failed");
           exit(1);
       }
       if (ioctl(handout, SNDCTL_DSP_SPEED, &play_sample_rate) == -1) {
           printf("config of speed failed");
           exit(1);
       }
       
   }
*/
   if (handout < 0)
   {
      printf("\n CANNOT CREATE OUTPUT FILE\n");
      goto abort;
   }
/*---- allocate pcm buffer --------*/
   pcm_buffer = malloc(PCM_BUFBYTES);
   if (pcm_buffer == NULL)
   {
      printf("\n CANNOT ALLOCATE PCM BUFFER\n");
      goto abort;
   }

/*---- init decoder -------*/
   if (!audio_decode_init(&m, &head, framebytes,
                          reduction_code, 0, convert_code, freq_limit))
   {
      printf("\n DECODER INIT FAIL \n");
      goto abort;
   }
/*---- get info -------*/
   audio_decode_info(&m, &decinfo);
/*---- info display -------*/
   printf("\n output samprate = %6ld", decinfo.samprate);
   printf("\n output channels = %6d", decinfo.channels);
   printf("\n output bits     = %6d", decinfo.bits);
   printf("\n output type     = %6d", decinfo.type);

/*---- write pcm header -------*/
   if (!write_pcm_header_wave(handout,
                              decinfo.samprate, decinfo.channels, decinfo.bits,
                              decinfo.type))
   {
      printf("\n FILE WRITE ERROR\n");
      goto abort;
   }

/*--- init wave converter ---*/
   cvt_to_wave_init(decinfo.bits);

   printf("\n");
/*----- DECODE -----*/

   for (u = 0;;)
   {
      if (!bs_fill())
         break;
      if (bs_bufbytes < framebytes)
         break;                 /* end of file */
#ifdef TIME_TEST
      set_clock();
#endif
      x = audio_decode(&m, bs_bufptr, (short *) (pcm_buffer + pcm_bufbytes));
#ifdef TIME_TEST
      get_clock();
      tot_cycles += global_cycles;
      tot_cycles_n++;
#endif
      if (x.in_bytes <= 0)
      {
         printf("\n BAD SYNC IN MPEG FILE\n");
         break;
      }
      bs_bufptr += x.in_bytes;
      bs_bufbytes -= x.in_bytes;
      pcm_bufbytes += x.out_bytes;
      u++;
      if (pcm_bufbytes > pcm_trigger)
      {
         pcm_bufbytes = cvt_to_wave(pcm_buffer, pcm_bufbytes);
         do
         {
            nwrite = write(handout, pcm_buffer, pcm_bufbytes);
            usleep(10000);
         }
         while (errno == EAGAIN);
         if (nwrite != pcm_bufbytes)
         {
            printf("\n FILE WRITE ERROR\n");
            break;
         }
         out_bytes += pcm_bufbytes;
         pcm_bufbytes = 0;
      }
      if (kbhit())
         break;
      in_bytes += x.in_bytes;
      if ((u & 63) == 1)
         printf("\r frames %6ld   bytes in %6ld    bytes out %6ld",
                u, in_bytes, out_bytes);
   }
/*---------------*/

   if (pcm_bufbytes > 0)
   {
      pcm_bufbytes = cvt_to_wave(pcm_buffer, pcm_bufbytes);
      nwrite = write(handout, pcm_buffer, pcm_bufbytes);
      if (nwrite != pcm_bufbytes)
      {
         printf("\n FILE WRITE ERROR\n");
      }
      out_bytes += pcm_bufbytes;
      pcm_bufbytes = 0;
   }
   printf("\n frames %6ld   bytes in %6ld    bytes out %6ld",
          u, in_bytes, out_bytes);

/*---- write pcm tailer -------*/
   write_pcm_tailer_wave(handout, out_bytes);

   printf("\n    output file: %s", fileout);

 abort:
   mpeg_cleanup(&m);
   close(handle);
   close(handout);
   free(bs_buffer);
   free(pcm_buffer);
   while (kbhit())
      getch();                  /* purge key board */
   return 1;
}

/*-------------------------------------------------------------*/
static int
bs_fill()
{
   unsigned int nread;

   if (bs_bufbytes < 0)
      bs_bufbytes = 0;          // signed var could be negative

   if (bs_bufbytes < bs_trigger)
   {
      memmove(bs_buffer, bs_bufptr, bs_bufbytes);
      nread = read(handle, bs_buffer + bs_bufbytes, BS_BUFBYTES - bs_bufbytes);
      if ((nread + 1) == 0)
      {
/*-- test for -1 = error --*/
         bs_trigger = 0;
         printf("\n FILE_READ_ERROR\n");
         return 0;
      }
      bs_bufbytes += nread;
      bs_bufptr = bs_buffer;
   }

   return 1;
}

/*------------------------------------------------------------------*/
static int
out_mpeg_info(MPEG_HEAD * h, int bitrate_arg)   /* info only */
{
   int       bitrate;
   int       samprate;
   static char *Layer_msg[] = { "INVALID", "III", "II", "I" };
   static char *mode_msg[] = { "STEREO", "JOINT", "DUAL", "MONO" };
   static int sr_table[8] = { 22050L, 24000L, 16000L, 1L,
      44100L, 48000L, 32000L, 1L
   };

   bitrate = bitrate_arg / 1000;
   printf("\n Layer %s ", Layer_msg[h->option]);

   printf("  %s ", mode_msg[h->mode]);
   samprate = sr_table[4 * h->id + h->sr_index];
   if ((h->sync & 1) == 0)
      samprate = samprate / 2;  // mpeg25

   printf(" %d ", samprate);
   printf("  %dKb ", bitrate);
   if ((h->mode == 1) && (h->option != 1))
      printf("  %d stereo bands ", 4 + 4 * h->mode_ext);
   if (h->prot == 0)
      printf(" (CRC)");

   return 0;
}

/*------------------------------------------------------------------*/
int
dummy()
{
   return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -