示例#1
0
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);
		}
	}
}
示例#2
0
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;
    }
    
}