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

📄 pcmdecode.c

📁 au1200 linux2.6.11 硬件解码mae驱动和maiplayer播放器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
  {    // encoded as 8 nibbles (4 bytes) per channel; switch channel every    // 4th byte    channel_counter = 0;    channel_index_l = 0;    channel_index_r = 1;    channel_index = channel_index_l;    for (i = 0; i < (block_size - MS_IMA_ADPCM_PREAMBLE_SIZE * channels); i++)    {      output[channel_index + 0] =        input[MS_IMA_ADPCM_PREAMBLE_SIZE * 2 + i] & 0x0F;      output[channel_index + 2] =        input[MS_IMA_ADPCM_PREAMBLE_SIZE * 2 + i] >> 4;      channel_index += 4;      channel_counter++;      if (channel_counter == 4)      {        channel_index_l = channel_index;        channel_index = channel_index_r;      }      else if (channel_counter == 8)      {        channel_index_r = channel_index;        channel_index = channel_index_l;        channel_counter = 0;      }    }  }    decode_nibbles(output,     (block_size - MS_IMA_ADPCM_PREAMBLE_SIZE * channels) * 2,    channels,    predictor_l, index_l,    predictor_r, index_r);  return (block_size - MS_IMA_ADPCM_PREAMBLE_SIZE * channels) * 2;}static int dk4_ima_adpcm_decode_block(unsigned short *output,  unsigned char *input, int channels, int block_size){  int i;  int output_ptr;  int predictor_l = 0;  int predictor_r = 0;  int index_l = 0;  int index_r = 0;  // the first predictor value goes straight to the output  predictor_l = output[0] = LE_16(&input[0]);  SIGN_EXTEND_16BIT(predictor_l);  index_l = input[2];  if (channels == 2)  {    predictor_r = output[1] = LE_16(&input[4]);    SIGN_EXTEND_16BIT(predictor_r);    index_r = input[6];  }  output_ptr = channels;  for (i = MS_IMA_ADPCM_PREAMBLE_SIZE * channels; i < block_size; i++)  {    output[output_ptr++] = input[i] >> 4;    output[output_ptr++] = input[i] & 0x0F;  }  decode_nibbles(&output[channels],    (block_size - MS_IMA_ADPCM_PREAMBLE_SIZE * channels) * 2 - channels,    channels,    predictor_l, index_l,    predictor_r, index_r);  return (block_size - MS_IMA_ADPCM_PREAMBLE_SIZE * channels) * 2 - channels;}static int ms_adpcm_adapt_table[] ={  230, 230, 230, 230, 307, 409, 512, 614, 768, 614, 512, 409, 307, 230, 230, 230};static int ms_adpcm_adapt_coef0[] ={  256, 512, 0, 192, 240, 460, 392};static int ms_adpcm_adapt_coef1[] ={  0, -256, 0, 64, 0, -208, -232};static int ms_adpcm_decode_block(unsigned short *output, unsigned char *input, int channels, int block_size){  int upper_nybble = 1;  int nybble;  int signed_nybble;  /* signed nybble */  int current_channel = 0;  int idelta[2];  int sample0[2];  int sample1[2];  int coef0[2];  int coef1[2];  int stream_index = 0;  int output_index = 0;  int predictor;  //{ int ii; for (ii = 0; ii < block_size; ii++) printf("%2x ", input[ii]); }  DPRINTF((M_TEXT("MS ADPCM: channels %d %d\n"), channels, block_size));  // process the short header, both channels  if (input[stream_index] > 6)  {    ERRORPRINTF((M_TEXT("MS ADPCM: %d out of range (must be 0 to 6)\n"), input[stream_index]));    return 0;  }  coef0[0] = ms_adpcm_adapt_coef0[input[stream_index]];  coef1[0] = ms_adpcm_adapt_coef1[input[stream_index]];  stream_index++;  if (channels == 2)  {    if (input[stream_index] > 6)      ERRORPRINTF((M_TEXT("MS ADPCM: %d out of range (must be 0 to 6)\n"), input[stream_index]));    coef0[1] = ms_adpcm_adapt_coef0[input[stream_index]];    coef1[1] = ms_adpcm_adapt_coef1[input[stream_index]];    stream_index++;  }  idelta[0] = LESS_OR_EQ_16(&input[stream_index]);  stream_index += 2;  SIGN_EXTEND_16BIT(idelta[0]);  if (channels == 2)  {    idelta[1] = LESS_OR_EQ_16(&input[stream_index]);    stream_index += 2;    SIGN_EXTEND_16BIT(idelta[1]);  }  sample0[0] = LESS_OR_EQ_16(&input[stream_index]);  stream_index += 2;  SIGN_EXTEND_16BIT(sample0[0]);  if (channels == 2)  {    sample0[1] = LESS_OR_EQ_16(&input[stream_index]);    stream_index += 2;    SIGN_EXTEND_16BIT(sample0[1]);  }  sample1[0] = LESS_OR_EQ_16(&input[stream_index]);  stream_index += 2;  SIGN_EXTEND_16BIT(sample1[0]);  if (channels == 2)  {    sample1[1] = LESS_OR_EQ_16(&input[stream_index]);    stream_index += 2;    SIGN_EXTEND_16BIT(sample1[1]);  }  if (channels == 1)  {    output[output_index++] = sample1[0];    output[output_index++] = sample0[0];  }   else   {    output[output_index++] = sample1[0];    output[output_index++] = sample1[1];    output[output_index++] = sample0[0];    output[output_index++] = sample0[1];  }  while (stream_index < block_size)  {    // get the next nybble    if (upper_nybble)      nybble = signed_nybble = input[stream_index] >> 4;    else      nybble = signed_nybble = input[stream_index++] & 0x0F;    upper_nybble ^= 1;    SIGN_EXTEND_4BIT(signed_nybble);    predictor = (      ((sample0[current_channel] * coef0[current_channel]) +       (sample1[current_channel] * coef1[current_channel])) / 256) +      (signed_nybble * idelta[current_channel]);    SATURATE_SHORT(predictor);    sample1[current_channel] = sample0[current_channel];    sample0[current_channel] = predictor;    output[output_index++] = predictor;    // find next delta    idelta[current_channel] = (ms_adpcm_adapt_table[nybble] * idelta[current_channel]) / 256;    CLAMP_ABOVE_16(idelta[current_channel]);    // next channel    current_channel ^= channels - 1;  }  return (block_size - (MS_ADPCM_PREAMBLE_SIZE * channels)) * 2;}static unsigned char *scan_wave_header(unsigned char *wav_header_to_scan, int *sample_size, unsigned int *loop_length, unsigned int *number_of_channels, unsigned int *samples_per_second){  unsigned char *temp_str;  unsigned char ntemp_str[32];  int riff_file_length;  int byte_order;  unsigned short wFormatTag;  unsigned int nAvgBytesPerSec, wave_offset = 0;  unsigned short block_alignment;  unsigned short bits_in_a_sample;  unsigned int wave_sequence_length;  big_endian = 0;  *samples_per_second = -1;  temp_str = wav_header_to_scan;  if (strncmp(temp_str, "RIFF", 4) == 0)  {    DPRINTF((M_TEXT("RIFF file %s\n"), wav_header_to_scan));    byte_order = 0;    temp_str += 4;    riff_file_length  = (unsigned int)(*temp_str++);    riff_file_length |= (unsigned int)(*temp_str++) <<  8;    riff_file_length |= (unsigned int)(*temp_str++) << 16;    riff_file_length |= (unsigned int)(*temp_str++) << 24;    DPRINTF((M_TEXT("RIFF Length = %lx, %ld\n"), riff_file_length, riff_file_length));    if (strncmp(temp_str, "WAVE", 4) == 0)    {      DPRINTF((M_TEXT("WAVE FILE SETUP.\n")));      temp_str += 4;      strncpy(wavheader.pcDecoderFullName, "WAV PCM decoder", 15);      if (!strncmp(temp_str, "fmt ", 4))      {        temp_str += 4;        wave_sequence_length  = (unsigned int)(*temp_str++);        wave_sequence_length |= (unsigned int)(*temp_str++) <<  8;        wave_sequence_length |= (unsigned int)(*temp_str++) << 16;        wave_sequence_length |= (unsigned int)(*temp_str++) << 24;        wFormatTag       =  (unsigned int)(*temp_str++);        wFormatTag      |=  (unsigned int)(*temp_str++) <<  8;        *number_of_channels        =  (unsigned int)(*temp_str++);        *number_of_channels       |=  (unsigned int)(*temp_str++) <<  8;        *samples_per_second   =  (unsigned int)(*temp_str++);        *samples_per_second  |=  (unsigned int)(*temp_str++) <<  8;        *samples_per_second  |=  (unsigned int)(*temp_str++) << 16;        *samples_per_second  |=  (unsigned int)(*temp_str++) << 24;        nAvgBytesPerSec  =  (unsigned int)(*temp_str++);        nAvgBytesPerSec |=  (unsigned int)(*temp_str++) <<  8;        nAvgBytesPerSec |=  (unsigned int)(*temp_str++) << 16;        nAvgBytesPerSec |=  (unsigned int)(*temp_str++) << 24;        block_alignment      =  (unsigned int)(*temp_str++);        block_alignment     |=  (unsigned int)(*temp_str++) <<  8;        bits_in_a_sample   =  (unsigned int)(*temp_str++);        bits_in_a_sample  |=  (unsigned int)(*temp_str++) <<  8;        {          INFO_PRINTF((M_TEXT("Wave format: \n  Length = %ld\n"), wave_sequence_length));          INFO_PRINTF((M_TEXT("  number_of_channels = %d\n"), *number_of_channels));          INFO_PRINTF((M_TEXT("  samples_per_second = %ld\n"), *samples_per_second));          INFO_PRINTF((M_TEXT("  nAvgBytesPerSec    = %ld\n"), nAvgBytesPerSec));          INFO_PRINTF((M_TEXT("  block_alignment    = %d\n"), block_alignment));          INFO_PRINTF((M_TEXT("  bits_in_a_sample   = %d\n"), bits_in_a_sample));          INFO_PRINTF((M_TEXT("  wFormatTag         = %x\n"), wFormatTag));        }      }      switch (wFormatTag)      {        case WAVE_FORMAT_ALAW: INFO_PRINTF((M_TEXT("WAVE_FORMAT_ALAW\n"))); break;        case WAVE_FORMAT_MULAW: INFO_PRINTF((M_TEXT("WAVE_FORMAT_MULAW\n"))); break;        case WAVE_FORMAT_ADPCM: INFO_PRINTF((M_TEXT("WAVE_FORMAT_ADPCM\n"))); break;        case WAVE_FORMAT_OKI_ADPCM: INFO_PRINTF((M_TEXT("WAVE_FORMAT_OKI_ADPCM\n"))); break;        case WAVE_FORMAT_IMA_ADPCM: INFO_PRINTF((M_TEXT("WAVE_FORMAT_IMA_ADPCM\n"))); break;        case WAVE_FORMAT_PCM_EXTENDED:         case WAVE_FORMAT_PCM: INFO_PRINTF((M_TEXT("WAVE_FORMAT_PCM\n"))); break;        default: ERRORPRINTF((M_TEXT("unknown format %x\n"), wFormatTag));      }            if (!strncmp(temp_str, "data", 4))      {        temp_str += 4;        wave_sequence_length  = (unsigned int)(*temp_str++);        wave_sequence_length |= (unsigned int)(*temp_str++) <<  8;        wave_sequence_length |= (unsigned int)(*temp_str++) << 16;        wave_sequence_length |= (unsigned int)(*temp_str++) << 24;        DPRINTF((M_TEXT("  Wave data length = %ld\n"), wave_sequence_length));      }      else      {        // There has to be a "data" chunk. Skip ahead to it.        int ii, found = 0;        for (ii = 0; ii < 1046 /* a guess */; ii++)        {          temp_str++;          if (!strncmp(temp_str, "data", 4))          {            found = 1;            temp_str += 4;            wave_sequence_length  = (unsigned int)(*temp_str++);            wave_sequence_length |= (unsigned int)(*temp_str++) <<  8;            wave_sequence_length |= (unsigned int)(*temp_str++) << 16;            wave_sequence_length |= (unsigned int)(*temp_str++) << 24;            DPRINTF((M_TEXT("  Wave data length = %ld\n"), wave_sequence_length));            break;          }        }                if (!found)        {          wave_sequence_length = riff_file_length - wave_sequence_length;          DPRINTF((M_TEXT("  Wave data length (using riff file length) = %ld\n"), wave_sequence_length));        }      }      wavheader.iSamplesPerSec = *samples_per_second;      wavheader.iBitsPerSample = bits_in_a_sample;      wavheader.iChannels = *number_of_channels;      wavheader.iBitrate = nAvgBytesPerSec * 8;      wavheader.iFramesize = block_alignment;      wavheader.iDuration = /* ms */ 80 * wave_sequence_length / (*number_of_channels) / (*samples_per_second / 100) / bits_in_a_sample;          //wavheader.iEmphasis          wavheader.iLayer = wFormatTag;    }  }  else if (strncmp(temp_str, "FORM", 4) == 0)  {    unsigned int number_of_bytes_of_sound_data;    unsigned int ii;    big_endian = 1;    DPRINTF((M_TEXT("found FORM AIFF file %s\n"), wav_header_to_scan));    temp_str += 4;    wave_sequence_length = 0;    byte_order = 1;    riff_file_length = (unsigned int)(*temp_str++) << 24;    riff_file_length |= (unsigned int)(*temp_str++) << 16;    riff_file_length |= (unsigned int)(*temp_str++) <<  8;    riff_file_length |= (unsigned int)(*temp_str++);    DPRINTF((M_TEXT("AIFF FILE. Length = %lx, %ld, %ld\n"), riff_file_length, riff_file_length, riff_file_length/2));    if (strncmp(temp_str, "AIFF", 4) == 0) /* This should be AIFF, else I don't know what to do with it */    {      int chunk_length, number_of_sample_frames;      temp_str += 4;      strncpy(wavheader.pcDecoderFullName, "AIFF PCM decoder", 16);      while (1) /* check for end of buffer FIXIT */      {        if (strncmp(temp_str, "COMM", 4) == 0)        {          temp_str += 4;          DPRINTF((M_TEXT("COMM found\n")));          chunk_length =  (unsigned int)(*temp_str++) << 24;          chunk_length |= (unsigned int)(*temp_str++) << 16;          chunk_length |= (unsigned int)(*temp_str++) <<  8;          chunk_length |= (unsigned int)(*temp_str++);          if (chunk_length != 18)          {            ERRORPRINTF((M_TEXT("AIFF COMM chunk has bad size %d != 18"), chunk_length));            return NULL;          }          *number_of_channels    =    (unsigned int)(*temp_str++) <<  8;          *number_of_channels    |=   (unsigned int)(*temp_str++);          number_of_sample_frames =  (unsigned int)(*temp_str++) << 24;          number_of_sample_frames |= (unsigned int)(*temp_str++) << 16;          number_of_sample_frames |= (unsigned int)(*temp_str++) <<  8;          number_of_sample_frames |= (unsigned int)(*temp_str++);          bits_in_a_sample  =        (unsigned int)(*temp_str++) <<  8;          bits_in_a_sample  |=       (unsigned int)(*temp_str++);          /* These next 10 bytes are the sampling rate. */          *samples_per_second = (int)ConvertFromIeeeExtended(temp_str);          temp_str += 10;        }        else if (strncmp(temp_str, "MARK", 4) == 0)        {          short number_of_markers, marker_counter;          unsigned int marker_positions[16];          unsigned int length, check_length;          temp_str += 4;          DPRINTF((M_TEXT("Processing MARK\n")));

⌨️ 快捷键说明

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