CRI ADX  Last Updated: 2024-07-17 10:48 p
播放Raw PCM

示例目录

/cri/pc/samples/criatomex/raw_pcm_playback


示例描述

输出程序生成的原始PCM数据的示例。
使用Raw PCM音频和无缝连接播放功能,输出无限生成的正弦波形。
生成并输出Raw PCM数据的示例代码如下。
void main()
{
/* 创建Raw PCM Voice池 */
rawpcm_vpconfig.identifier = RAW_PCM_VOICE_POOL_ID;
rawpcm_vpconfig.num_voices = 1;
rawpcm_vpconfig.player_config.max_channels = 1;
raw]pcm_vpconfig.player_config.max_sampling_rate = PCM_SAMPLING_RATE;
rawpcm_vpconfig.player_config.pcm_format = CRIATOM_PCM_FORMAT_SINT16;
&rawpcm_vpconfig, NULL, 0);
/* 指定要播放的音频数据的格式信息 */
criAtomExPlayer_SetSamplingRate(player, PCM_SAMPLING_RATE);
criAtomExPlayer_SetVoicePoolIdentifier(app_obj->player, RAW_PCM_VOICE_POOL_ID);
/* 指定用于下次提供数据的回调函数 */
criAtomExPlayer_SetDataRequestCallback(player, app_data_request_func, app_obj);
/* 指定第一个数据并播放 */
memset(app_obj->pcm_buffer[0], 0, PCM_BUFFER_LENGTH * sizeof(CriSint16));
app_obj->sin_offset = 0.0f;
app_obj->pcm_buffer_current = 0;
criAtomExPlayer_SetData(app_obj->player,
app_obj->pcm_buffer[0], PCM_BUFFER_LENGTH * sizeof(CriSint16));
}
static void app_data_request_func(
void *obj, CriAtomExPlaybackId id, CriAtomPlayerHn player)
{
AppObj *app_obj = (AppObj*)obj;
CriFloat32 sin_offset = app_obj->sin_offset;
CriFloat32 sin_step = 2.0f * 3.141592f * app_obj->sin_frequency / PCM_SAMPLING_RATE;
/* 切换使用缓冲区 */
app_obj->pcm_buffer_current++;
app_obj->pcm_buffer_current %= 2;
CriSint16 *buffer = app_obj->pcm_buffer[app_obj->pcm_buffer_current];
/* 生成正弦波形 */
for (i = 0; i < PCM_BUFFER_LENGTH; i++) {
buffer[i] = (CriSint16)(sinf(sin_offset) * 32767.0f);
sin_offset += sin_step;
}
app_obj->sin_offset = fmodf(sin_offset, 2.0f * 3.141592f);
/* 为Player设置下一个数据 */
criAtomPlayer_SetData(player, buffer, PCM_BUFFER_LENGTH * sizeof(CriSint16));
}
#define CRIATOMEX_FORMAT_RAW_PCM
Definition: cri_le_atom_ex.h:1932
void criAtomExPlayer_SetVoicePoolIdentifier(CriAtomExPlayerHn player, CriAtomExVoicePoolIdentifier identifier)
Specify the Voice Pool identifier
void criAtomExPlayer_SetData(CriAtomExPlayerHn player, void *buffer, CriSint32 size)
Set the sound data to play (specifying in-memory data)
void criAtomExPlayer_SetFormat(CriAtomExPlayerHn player, CriAtomExFormat format)
Specify the format of a sound
CriAtomExPlaybackId criAtomExPlayer_Start(CriAtomExPlayerHn player)
Start the playback
void criAtomExPlayer_SetDataRequestCallback(CriAtomExPlayerHn player, CriAtomExPlayerDataRequestCbFunc func, void *obj)
Register the data request callback function
CriUint32 CriAtomExPlaybackId
Playback ID
Definition: cri_le_atom_ex.h:3722
void criAtomExPlayer_SetNumChannels(CriAtomExPlayerHn player, CriSint32 num_channels)
Specify the number of channels of a sound
void criAtomExPlayer_SetSamplingRate(CriAtomExPlayerHn player, CriSint32 sampling_rate)
Specify the sampling rate of a sound
#define criAtomExVoicePool_SetDefaultConfigForRawPcmVoicePool(p_config)
Assign the default values to the configuration structure used to create a raw PCM Voice Pool
Definition: cri_le_atom_ex.h:672
CriAtomExVoicePoolHn criAtomExVoicePool_AllocateRawPcmVoicePool(const CriAtomExRawPcmVoicePoolConfig *config, void *work, CriSint32 work_size)
Create a raw PCM Voice Pool
struct CriAtomPlayerTag * CriAtomPlayerHn
Atom player handle
Definition: cri_le_atom.h:2339
void criAtomPlayer_SetData(CriAtomPlayerHn player, void *buffer, CriSint32 buffer_size)
Set sound data (specify On-memory data)


关于使用的缓冲区

指定::criAtomExPlayer_SetData的缓冲区后,在第2次回调调用之前不得丢弃。
基本上要使用双缓冲区或更多缓冲区运行。
如果::criAtomExGetStatus变为::CRIATOMEXPLAYER_STATUS_STOP则可以丢弃。

如果缓冲区太小,可能会发生声音中断。
如果需要一个服务器周期或更多的缓冲区,请参照以下公式。

  • 1个服务器周期 = 采样率 / 服务器频率
  • 缓冲区大小 = 1个服务器周期的量 + 安全容错的量 
    例如当48000Hz时,应准备1024个样本的缓冲区。

多声道数量据

如果是多声道数量据,则必须以交错格式创建数据。
创建交错数据的方法请参照以下代码。
float L_ch[1024];
float R_ch[1024];
float *buffer[1024 * 2];
buffer[0] = L_ch[0];
buffer[1] = R_ch[0];
buffer[2] = L_ch[1];
buffer[3] = R_ch[1];
buffer[4] = L_ch[2];
buffer[5] = R_ch[2];
:
:
criAtomPlayer_SetData(player, buffer, sizeof(buffer));