static void pcm_play_demo(void) { struct deca_feature_config deca_config; struct snd_feature_config snd_config; UINT32 i, j; struct pcm_output pcm; INT32 *p_pcm_sp; g_decv_dev = dev_get_by_id(HLD_DEV_TYPE_DECV, 0); g_deca_dev = dev_get_by_id(HLD_DEV_TYPE_DECA, 0); if (RET_SUCCESS != deca_open(g_deca_dev, 0, 0, 0, 0, 0)) { PRINTF("deca_open failed!!\n"); ASSERT(0); } if (RET_SUCCESS != snd_open(g_snd_dev)) { PRINTF("snd_open failed!!\n"); ASSERT(0); } MEMSET(&pcm, 0, sizeof(struct pcm_output)); pcm.ch_num = 2; pcm.ch_mod = DUAL_CHANNEL; pcm.ch_left = pcm_left_ch; pcm.ch_right = pcm_right_ch; pcm.samp_num = 1152; snd_set_spdif_type(g_snd_dev, SND_OUT_SPDIF_PCM); snd_set_volume(g_snd_dev, SND_SUB_OUT, 100); snd_set_duplicate(g_snd_dev, SND_DUP_NONE); /*assumes PCM data is in address __MM_AUDIO_PATTERN_ADDR, 400*4608 samples, Preset PCM sample rate is 48000, each sample occupy 1 double word (32 bits)*/ while (1) { p_pcm_sp = (INT32 *)__MM_AUDIO_PATTERN_ADDR; for (i = 0;i < PCM_FRM_NUM;i++) { for (j = 0;j < pcm.samp_num;j++) { /*for dual channel mode, 2 channels should have different samples, herel fills the same samples to 2 channels for demo. If only have 1 channel PCM, you can only fill 1 channel (left or right), but you should call snd_set_duplicate(g_snd_dev, SND_DUP_L); or snd_set_duplicate(g_snd_dev, SND_DUP_R); before play.*/ pcm_left_ch[j] = (*p_pcm_sp) << 5; pcm_right_ch[j] = (*p_pcm_sp) << 5; p_pcm_sp++; } libc_demo_pcm_output(&pcm); } } }
void process_ogg_pcm(struct snd_device * sound_dev, int bytes_readed, int *processed_pcm) { INT16 *out_buf_temp; UINT32 out_samp_num; UINT32 i; struct pcm_output pcm; int bytes_left = 0; //we process sample rate for martching our sound device. //note : the pcm code may not integrity, I don't know it works or not, under testing out_buf_temp = (INT16*)ogg_file->pcm_out_buff; out_samp_num = (bytes_readed /2) / ogg_file->channel; if(out_samp_num > ON_PCM_BUFF_LEN) return; if(g_pcm_sample_num + out_samp_num < ON_PCM_BUFF_LEN) { MEMCPY((char*)(g_temp_pcm_buff+g_pcm_current_using),out_buf_temp,bytes_readed); g_pcm_current_using += bytes_readed; g_pcm_sample_num += out_samp_num; return; } else { MEMCPY((char*)(g_temp_pcm_buff+g_pcm_current_using),out_buf_temp,(ON_PCM_BUFF_LEN-g_pcm_sample_num)*ogg_file->channel*2); bytes_left = bytes_readed - (ON_PCM_BUFF_LEN-g_pcm_sample_num)*ogg_file->channel*2; } g_pcm_current_using = 0; g_pcm_sample_num = 0; out_samp_num = ON_PCM_BUFF_LEN; pcm.samp_num = ON_PCM_BUFF_LEN; out_buf_temp = (INT16 *)g_temp_pcm_buff; //pcm.samp_num = out_samp_num; pcm.ch_num = (ogg_file->channel > 2) ? 2: ogg_file->channel; pcm.ch_left = (UINT32 *)processed_pcm; pcm.ch_right = (UINT32 *)(processed_pcm + 1152); pcm.raw_data_start = NULL; pcm.raw_data_len = 0; if(24000==ogg_file->samplerate||16000==ogg_file->samplerate||22050==ogg_file->samplerate) { ogg_dup_samplerate = ogg_file->samplerate<<1; if(out_samp_num <= 576) { if(pcm.ch_num == 1) //(SINGLE_CHANNEL) { snd_set_duplicate(sound_dev, SND_DUP_L); for(i=0; i<out_samp_num; i++) { *(processed_pcm+(i*2)) = (INT32)out_buf_temp[i] << 8; *(processed_pcm+(i*2 + 1)) = (INT32)out_buf_temp[i] << 8; } } else { snd_set_duplicate(sound_dev, SND_DUP_NONE); for(i=0; i<out_samp_num; i++) { *(processed_pcm+(i*2)) = (INT32)out_buf_temp[i*ogg_file->channel] << 8; *(processed_pcm+(i*2 + 1)) = (INT32)out_buf_temp[i*ogg_file->channel] << 8; *(processed_pcm + 1152 + (i*2)) = (INT32)out_buf_temp[i*ogg_file->channel+1] << 8; *(processed_pcm + 1152 + (i*2 + 1))= (INT32)out_buf_temp[i*ogg_file->channel+1] << 8; } } pcm.samp_num = out_samp_num<<1; low_sprt_ogg_output(sound_dev, &pcm); } else { UINT32 start_point; UINT32 full_count, count; full_count = out_samp_num / 576; count = out_samp_num % 576; if(pcm.ch_num == 1) //(SINGLE_CHANNEL) { snd_set_duplicate(sound_dev, SND_DUP_L); for (start_point = 0; start_point < full_count; start_point++) { for(i=0; i<576; i++) { *(processed_pcm+(i*2)) = (INT32)out_buf_temp[start_point * 576 + i] << 8; *(processed_pcm+(i*2 + 1)) = (INT32)out_buf_temp[start_point * 576 + i] << 8; } pcm.samp_num = 1152; low_sprt_ogg_output(sound_dev, &pcm); } for (i=0; i<count; ++i) { *(processed_pcm+(i*2)) = (INT32)out_buf_temp[start_point*576 + i] << 8; *(processed_pcm+(i*2 + 1)) = (INT32)out_buf_temp[start_point*576 + i] << 8; } if (count) { pcm.samp_num = count * 2; low_sprt_ogg_output(sound_dev, &pcm); } } else { snd_set_duplicate(sound_dev, SND_DUP_NONE); for (start_point = 0; start_point < full_count; start_point++) { for(i=0; i<576; i++) { *(processed_pcm+(i*2)) = (INT32)out_buf_temp[start_point*576*ogg_file->channel + i*ogg_file->channel] << 8; *(processed_pcm+(i*2 + 1)) = (INT32)out_buf_temp[start_point*576*ogg_file->channel + i*ogg_file->channel] << 8; *(processed_pcm + 1152 + (i*2)) = (INT32)out_buf_temp[start_point*576*ogg_file->channel + i*ogg_file->channel + 1] << 8; *(processed_pcm + 1152 + (i*2 + 1))= (INT32)out_buf_temp[start_point*576*ogg_file->channel + i*ogg_file->channel + 1] << 8; } pcm.samp_num = 1152; low_sprt_ogg_output(sound_dev, &pcm); } for (i=0; i<count; ++i) { *(processed_pcm+(i*2)) = (INT32)out_buf_temp[start_point*576*ogg_file->channel + i*ogg_file->channel] << 8; *(processed_pcm+(i*2 + 1)) = (INT32)out_buf_temp[start_point*576*ogg_file->channel + i*ogg_file->channel] << 8; *(processed_pcm + 1152 + (i*2)) = (INT32)out_buf_temp[start_point*576*ogg_file->channel + i*ogg_file->channel + 1] << 8; *(processed_pcm + 1152 + (i*2 + 1))= (INT32)out_buf_temp[start_point*576*ogg_file->channel + i*ogg_file->channel + 1] << 8; } if (count) { pcm.samp_num = count * 2; low_sprt_ogg_output(sound_dev, &pcm); } } } if(bytes_left > 0) { MEMCPY((char*)(g_temp_pcm_buff),(char*)(ogg_file->pcm_out_buff+(bytes_readed-bytes_left)),bytes_left); g_pcm_current_using = bytes_left; g_pcm_sample_num = bytes_left/ogg_file->channel/2; } return; } if(12000==ogg_file->samplerate||11025==ogg_file->samplerate||8000==ogg_file->samplerate) { INT32 cur_sp = 0; // static UINT32 prev_sp_l = 0,prev_sp_r = 0; ogg_dup_samplerate = ogg_file->samplerate<<2; if(out_samp_num<=288) { if(pcm.ch_num == 1) //(SINGLE_CHANNEL==ogg_file->aud_mode) { snd_set_duplicate(sound_dev, SND_DUP_L); for (i=0; i<out_samp_num; ++i) { cur_sp = (INT32)out_buf_temp[i] << 8; *(processed_pcm+(i*4)) = prev_sp_l+(cur_sp-prev_sp_l)/4; *(processed_pcm+(i*4 + 1)) = prev_sp_l+(cur_sp-prev_sp_l)/2; *(processed_pcm+(i*4 + 2)) = prev_sp_l+(cur_sp-prev_sp_l)*3/4; *(processed_pcm+(i*4 + 3)) = cur_sp; prev_sp_l = cur_sp; } } else { snd_set_duplicate(sound_dev, SND_DUP_NONE); for (i=0; i<out_samp_num; ++i) { cur_sp = (INT32)out_buf_temp[i*ogg_file->channel] << 8; *(processed_pcm+(i*4)) = prev_sp_l+(cur_sp-prev_sp_l)/4; *(processed_pcm+(i*4 + 1)) = prev_sp_l+(cur_sp-prev_sp_l)/2; *(processed_pcm+(i*4 + 2)) = prev_sp_l+(cur_sp-prev_sp_l)*3/4; *(processed_pcm+(i*4 + 3)) = cur_sp; prev_sp_l = cur_sp; cur_sp = (INT32)out_buf_temp[i*ogg_file->channel+1] << 8; *(processed_pcm + 1152 + (i*4)) = prev_sp_r+(cur_sp-prev_sp_r)/4; *(processed_pcm + 1152 + (i*4 + 1))= prev_sp_r+(cur_sp-prev_sp_r)/2; *(processed_pcm + 1152 + (i*4 + 2))= prev_sp_r+(cur_sp-prev_sp_r)*3/4; *(processed_pcm + 1152 + (i*4 + 3))= cur_sp; prev_sp_r = cur_sp; } } pcm.samp_num = out_samp_num<<2; low_sprt_ogg_output(sound_dev, &pcm); } else //out_samp_num>288 { UINT32 start_point; UINT32 full_count, count; full_count = out_samp_num / 288; count = out_samp_num % 288; if(pcm.ch_num == 1) //(SINGLE_CHANNEL) { snd_set_duplicate(sound_dev, SND_DUP_L); for (start_point = 0; start_point < full_count; start_point++) { for(i=0; i<288; i++) { cur_sp = (INT32)out_buf_temp[start_point*288+i] << 8; *(processed_pcm+(i*4)) = prev_sp_l+(cur_sp-prev_sp_l)/4; *(processed_pcm+(i*4 + 1)) = prev_sp_l+(cur_sp-prev_sp_l)/2; *(processed_pcm+(i*4 + 2)) = prev_sp_l+(cur_sp-prev_sp_l)*3/4; *(processed_pcm+(i*4 + 3)) = cur_sp; prev_sp_l = cur_sp; } pcm.samp_num = 1152; low_sprt_ogg_output(sound_dev, &pcm); } for (i=0; i<count; ++i) { cur_sp = (INT32)out_buf_temp[start_point*288+i] << 8; *(processed_pcm+(i*4)) = prev_sp_l+(cur_sp-prev_sp_l)/4; *(processed_pcm+(i*4 + 1)) = prev_sp_l+(cur_sp-prev_sp_l)/2; *(processed_pcm+(i*4 + 2)) = prev_sp_l+(cur_sp-prev_sp_l)*3/4; *(processed_pcm+(i*4 + 3)) = cur_sp; prev_sp_l = cur_sp; } if (count) { pcm.samp_num = count * 4; low_sprt_ogg_output(sound_dev, &pcm); } } else { snd_set_duplicate(sound_dev, SND_DUP_NONE); for (start_point = 0; start_point < full_count; start_point++) { for(i=0; i<288; i++) { cur_sp = (INT32)out_buf_temp[start_point*288*ogg_file->channel+i*ogg_file->channel] << 8; *(processed_pcm+(i*4)) = prev_sp_l+(cur_sp-prev_sp_l)/4; *(processed_pcm+(i*4 + 1)) = prev_sp_l+(cur_sp-prev_sp_l)/2; *(processed_pcm+(i*4 + 2)) = prev_sp_l+(cur_sp-prev_sp_l)*3/4; *(processed_pcm+(i*4 + 3)) = cur_sp; prev_sp_l = cur_sp; cur_sp = (INT32)out_buf_temp[start_point*288*ogg_file->channel+i*ogg_file->channel+1] << 8; *(processed_pcm + 1152 + (i*4)) = prev_sp_r+(cur_sp-prev_sp_r)/4; *(processed_pcm + 1152 + (i*4 + 1))= prev_sp_r+(cur_sp-prev_sp_r)/2; *(processed_pcm + 1152 + (i*4 + 2))= prev_sp_r+(cur_sp-prev_sp_r)*3/4; *(processed_pcm + 1152 + (i*4 + 3))= cur_sp; prev_sp_r = cur_sp; } pcm.samp_num = 1152; low_sprt_ogg_output(sound_dev, &pcm); } for (i=0; i<count; ++i) { cur_sp = (INT32)out_buf_temp[start_point*288*ogg_file->channel+i*ogg_file->channel] << 8; *(processed_pcm+(i*4)) = prev_sp_l+(cur_sp-prev_sp_l)/4; *(processed_pcm+(i*4 + 1)) = prev_sp_l+(cur_sp-prev_sp_l)/2; *(processed_pcm+(i*4 + 2)) = prev_sp_l+(cur_sp-prev_sp_l)*3/4; *(processed_pcm+(i*4 + 3)) = cur_sp; prev_sp_l = cur_sp; cur_sp = (INT32)out_buf_temp[start_point*288*ogg_file->channel+i*ogg_file->channel+1] << 8; *(processed_pcm + 1152 + (i*4)) = prev_sp_r+(cur_sp-prev_sp_r)/4; *(processed_pcm + 1152 + (i*4 + 1))= prev_sp_r+(cur_sp-prev_sp_r)/2; *(processed_pcm + 1152 + (i*4 + 2))= prev_sp_r+(cur_sp-prev_sp_r)*3/4; *(processed_pcm + 1152 + (i*4 + 3))= cur_sp; prev_sp_r = cur_sp; } if (count) { pcm.samp_num = count * 4; low_sprt_ogg_output(sound_dev, &pcm); } } } if(bytes_left > 0) { MEMCPY((char*)(g_temp_pcm_buff),(char*)(ogg_file->pcm_out_buff+(bytes_readed-bytes_left)),bytes_left); g_pcm_current_using = bytes_left; g_pcm_sample_num = bytes_left/ogg_file->channel/2; } return; } //normal samprate if(pcm.ch_num == 1) //(SINGLE_CHANNEL==ogg_file->aud_mode) { snd_set_duplicate(sound_dev, SND_DUP_L); for(i=0;i<out_samp_num;i++) { *(processed_pcm + i) = (INT32)out_buf_temp[i] << 8; } } else { snd_set_duplicate(sound_dev, SND_DUP_NONE); for(i=0;i<out_samp_num;i++) { *(processed_pcm + i) = (INT32)out_buf_temp[i*ogg_file->channel] << 8; *(processed_pcm + 1152 + i) = (INT32)out_buf_temp[i*ogg_file->channel+1] << 8; } } ogg_dup_samplerate = ogg_file->samplerate; low_sprt_ogg_output(sound_dev, &pcm); if(bytes_left > 0) { MEMCPY((char*)(g_temp_pcm_buff),(char*)(ogg_file->pcm_out_buff+(bytes_readed-bytes_left)),bytes_left); g_pcm_current_using = bytes_left; g_pcm_sample_num = bytes_left/ogg_file->channel/2; } }