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

📄 pcmdecode.c

📁 au1200 linux2.6.11 硬件解码mae驱动和maiplayer播放器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
          length =  (unsigned int)(*temp_str++) << 24;          length |= (unsigned int)(*temp_str++) << 16;          length |= (unsigned int)(*temp_str++) <<  8;          length |= (unsigned int)(*temp_str++);          check_length = 0;          number_of_markers =  (unsigned short)(*temp_str++) <<  8;          number_of_markers |= (unsigned short)(*temp_str++);          check_length += 2;          marker_counter = number_of_markers;          while (marker_counter--)          {            short marker_id, string_length;            marker_id =  (unsigned short)(*temp_str++) <<  8;            marker_id |= (unsigned short)(*temp_str++);            check_length += 2;            marker_positions[marker_id] =  (unsigned int)(*temp_str++) << 24;            marker_positions[marker_id] |= (unsigned int)(*temp_str++) << 16;            marker_positions[marker_id] |= (unsigned int)(*temp_str++) <<  8;            marker_positions[marker_id] |= (unsigned int)(*temp_str++);            check_length += 4;            string_length = (unsigned short)(*temp_str++);            check_length++;            // printf("string_length %x\n", string_length);            for (ii = 0; ii <= (unsigned int)string_length; ii++)   /* stupid Pascal string, get one more than the advertized length */            {              ntemp_str[ii] = (*temp_str++);              check_length++;            }            {              //DPRINTF((M_TEXT("MARK string read: now at file position %lx\n"), ftell(input_samples_fp)));              DPRINTF((M_TEXT("%s marker_positions[%d] = %lx\n"), ntemp_str, marker_id, marker_positions[marker_id]));            }            // printf("%s marker_positions[%d] = %lx\n", ntemp_str, marker_id, marker_positions[marker_id]);          }          if (check_length != length)          {            ERRORPRINTF((M_TEXT("AIFF MARK chunk parse error: %x != %x"), check_length, length));            return NULL;          }          if (number_of_markers > 1)          {            *loop_length = marker_positions[2] - marker_positions[1];            wave_sequence_length = marker_positions[2];          }          //DPRINTF((M_TEXT("MARK end now at file position %lx\n"), ftell(input_samples_fp));        }        else if (strncmp(temp_str, "NAME", 4) == 0)        {          unsigned int length;          temp_str += 4;          length =  (unsigned int)(*temp_str++) << 24;          length |= (unsigned int)(*temp_str++) << 16;          length |= (unsigned int)(*temp_str++) <<  8;          length |= (unsigned int)(*temp_str++);          for (ii = 0; ii < length; ii++)            ntemp_str[ii] = (*temp_str++);          ntemp_str[length] = 0;          DPRINTF((M_TEXT("NAME '%s'\n"), ntemp_str));        }        else if (strncmp(temp_str, "INST", 4) == 0)        {          temp_str += 4;          DPRINTF((M_TEXT("Gobbling INST\n")));          temp_str += mac_gobble(temp_str);        }        else if (strncmp(temp_str, "SSND", 4) == 0)        {          temp_str += 4;          number_of_bytes_of_sound_data =  (unsigned int)(*temp_str++) << 24;          number_of_bytes_of_sound_data |= (unsigned int)(*temp_str++) << 16;          number_of_bytes_of_sound_data |= (unsigned int)(*temp_str++) <<  8;          number_of_bytes_of_sound_data |= (unsigned int)(*temp_str++);          wave_offset =  (unsigned int)(*temp_str++) << 24;          wave_offset |= (unsigned int)(*temp_str++) << 16;          wave_offset |= (unsigned int)(*temp_str++) <<  8;          wave_offset |= (unsigned int)(*temp_str++);          block_alignment =  (unsigned int)(*temp_str++) << 24;          block_alignment |= (unsigned int)(*temp_str++) << 16;          block_alignment |= (unsigned int)(*temp_str++) <<  8;          block_alignment |= (unsigned int)(*temp_str++);          if (block_alignment != 0)          {            ERRORPRINTF((M_TEXT("AIFF header specifies nonzero blocksize?!?!")));            return NULL;          }          INFO_PRINTF((M_TEXT("AIFF format: \n  Length = %ld\n"), number_of_bytes_of_sound_data));          INFO_PRINTF((M_TEXT("  number_of_channels = %d\n"), *number_of_channels));          INFO_PRINTF((M_TEXT("  samples_per_second = %d\n"), *samples_per_second));          INFO_PRINTF((M_TEXT("  bits_in_a_sample   = %d\n"), bits_in_a_sample));          INFO_PRINTF((M_TEXT("  wave_offset        = %d\n"), wave_offset));          break;        }        else        {          int jj;          for (jj = 0; jj < 4; jj++)            DPRINTF((M_TEXT("%02x "), temp_str[jj]));          temp_str += 4;          DPRINTF((M_TEXT("Gobbling %s\n"), temp_str));          //DPRINTF((M_TEXT("Gobble now at file position %lx\n"), ftell(input_samples_fp)));          temp_str += mac_gobble(temp_str);        }        // DPRINTF((M_TEXT("AIFF end of loop: now at file position %lx\n"), ftell(input_samples_fp));      }    }    if (wave_sequence_length == 0)      wave_sequence_length = number_of_bytes_of_sound_data;    else      wave_sequence_length *= (bits_in_a_sample/8);    wavheader.iSamplesPerSec = *samples_per_second;    wavheader.iBitsPerSample = bits_in_a_sample;    wavheader.iChannels = *number_of_channels;    wavheader.iBitrate = (*samples_per_second) * (*number_of_channels) * bits_in_a_sample;    wavheader.iFramesize = block_alignment;    wavheader.iDuration = /* ms */ 80 * wave_sequence_length / (*number_of_channels) / (*samples_per_second / 100) / bits_in_a_sample;        wavheader.iLayer = WAVE_FORMAT_AIFF_PCM;    //wavheader.iEmphasis      }  else    DPRINTF((M_TEXT("NOT RIFF or AIFF file '%s'\n"), wav_header_to_scan));  if (*sample_size == 0)    *sample_size = bits_in_a_sample/8; /* number of bytes in sample */  DPRINTF((M_TEXT("ssize %d\n"), *sample_size));  return temp_str;}static int process_header;void init_wav_decode(audiodecChangeInfo *ci){  process_header = 1;  /* set defaults */  ci->sampling_rate = 44100;  ci->channels = 2;}void set_no_header_wav_decode(void){  process_header = 0;}int decode_wav_audio(audiodecChangeInfo *ci, short *p_outbuf, int *out_size, unsigned char *in_buf, int inbuf_size){  static int loop_length;  static int sample_size=0;  /* used only with WAVE_FORMAT_PCM!! */ int num_bytes_to_process = inbuf_size < MAX_PROCESS_PER_CALL_WAVE_FORMAT_PCM ? inbuf_size : MAX_PROCESS_PER_CALL_WAVE_FORMAT_PCM;  int ii, header_length = 0;  if (process_header)  {    unsigned char *out_buf = scan_wave_header(in_buf, &sample_size, &loop_length, &ci->channels, &ci->sampling_rate);    process_header = 0;     header_length = (out_buf - in_buf);    num_bytes_to_process -= header_length;    DPRINTF((M_TEXT("header_length %d\n"), header_length));    in_buf = out_buf;    *out_size = 0;    if (wavheader.iLayer != WAVE_FORMAT_PCM)      return header_length;  }  //else  /* do NOT do this since ci->bits_per_sample is changed later! */  //  sample_size = ci->bits_per_sample >> 3;    if ((wavheader.iLayer == WAVE_FORMAT_AIFF_PCM) || (wavheader.iLayer == WAVE_FORMAT_PCM) || (wavheader.iLayer == WAVE_FORMAT_PCM_EXTENDED))  {    int jj;    unsigned short *obuf = (unsigned short *)p_outbuf;    unsigned char *ibuf = (unsigned char *)in_buf;    unsigned int tester;	//MK051606	if(sample_size == 0)		sample_size = wavheader.iBitsPerSample >> 3;    switch (sample_size) // in bytes    {      case 3:         tester = num_bytes_to_process / 3;        num_bytes_to_process = tester * 3; // must be a multiple of 24 bits        if (big_endian)        {          for (jj = 0, ii = 0; ii < num_bytes_to_process; ii+=3, jj+=2)          {            unsigned short out, out2;            out2 = *ibuf++;             out = *ibuf++;            ibuf++; // discard low 8 bits, could round here            *obuf++ = out | (out2 << 8);          }        }        else        {          for (jj = 0, ii = 0; ii < num_bytes_to_process; ii+=3, jj+=2)          {            unsigned short out, out2;            ibuf++; // discard low 8 bits, could round here            out = *ibuf++;            out2 = *ibuf++;             *obuf++ = out | (out2 << 8);          }        }        num_bytes_to_process = ii;        *out_size = jj;        break;      case 2:          if (big_endian)          flip_byte_order16((unsigned short *)p_outbuf, (unsigned short *)in_buf, num_bytes_to_process);        else          memcpy(p_outbuf, in_buf, num_bytes_to_process);        *out_size = num_bytes_to_process;        break;      case 1:         for (ii = 0; ii < num_bytes_to_process; ii++)        {          unsigned short out;          out = *ibuf++;          out <<= 8;          *obuf++ = out + (unsigned int)0x8000;        }        num_bytes_to_process = ii;        *out_size = ii << 1;        break;      default:        DPRINTF((M_TEXT("sample size %d not supported\n"), sample_size));        *out_size = 0;        return -1;    }    do_pcm_conversions((char *)p_outbuf, out_size);    return num_bytes_to_process + header_length;  }  else if ((wavheader.iLayer == WAVE_FORMAT_ADPCM) || (wavheader.iLayer == WAVE_FORMAT_DVI_ADPCM))  {    if (wavheader.iFramesize <= (unsigned int)(inbuf_size - header_length))    {      if (wavheader.iLayer == WAVE_FORMAT_DVI_ADPCM)        *out_size = 2 * ms_ima_adpcm_decode_block(p_outbuf, in_buf, wavheader.iChannels, wavheader.iFramesize);      else        *out_size = 2 * ms_adpcm_decode_block(p_outbuf, in_buf, wavheader.iChannels, wavheader.iFramesize);      do_pcm_conversions((char *)p_outbuf, out_size);      return header_length + wavheader.iFramesize;    }    else /* should only happen on last frame */    {      *out_size = 0;      return inbuf_size;    }  }  else if ((wavheader.iLayer == WAVE_FORMAT_MULAW) || (wavheader.iLayer == WAVE_FORMAT_ALAW))  {    int len;    int ll = inbuf_size; // demux_read_data(sh_audio->ds,buf,minlen/2);    unsigned short *dd = (unsigned short *) p_outbuf;    unsigned char *ss = in_buf;    len = 2 * ll;    if (wavheader.iLayer == WAVE_FORMAT_ALAW) // also 0x77616C61    {      /* aLaw */      while (ll > 0)       {         --ll;         dd[ll] = alaw2short[ss[ll]];       }    }     else     {      /* uLaw */      while (ll > 0)      {         --ll;         dd[ll] = ulaw2short[ss[ll]];       }    }    *out_size = len;  }  else  {    ERRORPRINTF((M_TEXT("pcmdecode: unsupported format %x\n"), wavheader.iLayer));    *out_size = 0;    return inbuf_size;  }      do_pcm_conversions((char *)p_outbuf, out_size);  return inbuf_size;}/* * MPEG LPCM header : * - PES header 0 - private stream ID (8 bits) == 0xA0    (A1 == MLP) 1 - frame number (8 bits) 2/3 - unknown (16 bits) == 0x0003 ? 4 - unknown (4 bits) 4 - current frame (4 bits) 5 - unknown (2 bits) 5 - frequency (2 bits) 0 == 48 kHz, 1 == 32 kHz, 2 == ?, 3 == ? 5 - unknown (1 bit) 5 - number of channels - 1 (3 bits) 1 == 2 channels 6 - start code (8 bits) == 0x80 */ #if 0DVD LPCM HeaderThe audio frame size for LPCM packets in a VOB file is always 150 PTS ticks. For LPCM packets in an AOB file, the audio frame size for a stereo stream is as follows:  Size in Bytes Size inSamples 16-bit 20-bit 24-bit 44.1KHz or 48KHz 160 200 240 40 88.2KHz or 96KHz 320 400 480 80 176.4KHz or 192KHz 640 800 960 160 The LPCM header is as follows:Offset Size (bytes) Description 0 1 Sub-stream ID. Unconfirmed, but possibly 0xa0 for LPCM and 0xa1 for MLP 1 1 Continuity Counter - counts from 0x00 to 0x1f and then wraps to 0x00. 2 2 LPCM_header_length The following applies to LPCM packets (not MLP) 4 2 Byte pointer to start of first audio frame. 6 1 Unknown - e.g. 0x10 for stereo, 0x00 for surround 7 1 Sample size (high nibble - Channel Group 1, low nibble - Channel Group 2).0x0=16-bit, 0x1=20-bit, 0x2=24-bit, 0xf=Channel Group not used. 8 1 Samplerate (high nibble - Channel Group 1, low nibble - Channel Group 2).0x0=48KHz, 0x1=96KHz, 0x2=192KHz,0x8=44.1KHz, 0x9=88.2KHz, 0xa=176.4KHz, 0xf=Channel Group not used.e.g. 0x0f=48KHz Stereo, 0x88=44.1KHz Surround 9 1 Unknown - e.g. 0x00 10 1 Channel Group Assignment (see below). 11 1 Unknown - e.g. 0x80 12 var Padding - zero Channel Group AssignmentsThe DVD-Audio specification supports splitting a multi-channel track into two groups of channels, where the channels assigned to group 2 have a lower samplerate/bit-depth than the channels in group 1. The valid assignments are as follows:ID Chan. 0 Chan. 1 Chan. 2 Chan. 3 Chan. 4 Chan. 5 0  C   1  L R   2  L R S   3  L R Ls Rs   4  L R Lfe   5  L R Lfe S   6  L R Lfe Ls Rs   7  L R C   8  L R C S   9  L R C Ls Rs   10  L R C Lfe   11  L R C Lfe S   12  L R C Lfe Ls Rs 13  L R C S   14  L R C Ls Rs   15  L R C Lfe   16  L R C Lfe S   17  L R C Lfe Ls Rs 18  L R Ls Rs Lfe   19  L R Ls Rs C   20  L R Ls Rs C Lfe   Group 1 Group 2 where L=Front Left, R=Front Right, C=Centre, Ls=Left Surround, Rs=Right Surround, S=Surround and Lfe=Low frequency effects#endif     int decode_pcm_audio(audiodecChangeInfo *ci, short *p_outbuf, int *out_size, unsigned char *in_buf, int inbuf_size, int sample_size, int big_endian){  int ii;  int jj;  unsigned short *obuf = (unsigned short *)p_outbuf;  unsigned char *ibuf = (unsigned char *)in_buf;  unsigned int tester;  int num_bytes_to_process = inbuf_size < MAX_PROCESS_PER_CALL_WAVE_FORMAT_PCM ? inbuf_size : MAX_PROCESS_PER_CALL_WAVE_FORMAT_PCM;  DPRINTF((M_TEXT("PCMDEC raw %d\n"), inbuf_size));  switch (sample_size) // in bytes  {    case 3:       tester = num_bytes_to_process / 3;      num_bytes_to_process = tester * 3; // must be a multipl

⌨️ 快捷键说明

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