📄 pcmdecode.c
字号:
{ // 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 + -