617 lines
18 KiB
C
617 lines
18 KiB
C
|
#include "audio_dec_midi_ctrl.h"
|
|||
|
|
|||
|
#if AUDIO_MIDI_CTRL_CONFIG
|
|||
|
/*
|
|||
|
*如遇到多按琴键同时按下或重复快速按某琴键出现卡顿的情况
|
|||
|
*处理方法:1、减少同时发声MIDI_KEY_NUM 个数
|
|||
|
* 2、提高外挂flash的 波特率(60M、90M),调整spi读线宽的为2线模式或4线
|
|||
|
* 3、提高系统时钟
|
|||
|
* */
|
|||
|
extern struct audio_dac_hdl dac_hdl;
|
|||
|
|
|||
|
#define MIDI_KEY_NUM (18)//(支持多少个key同时发声(1~18), 越大,需要的时钟越大)
|
|||
|
|
|||
|
const u16 midi_samplerate_tab[9] = {
|
|||
|
48000,
|
|||
|
44100,
|
|||
|
32000,
|
|||
|
24000,
|
|||
|
22050,
|
|||
|
16000,
|
|||
|
12000,
|
|||
|
11025,
|
|||
|
8000
|
|||
|
};
|
|||
|
|
|||
|
struct _midi_obj {
|
|||
|
u8 channel;
|
|||
|
u32 sample_rate;
|
|||
|
u32 id; // 唯一标识符,随机值
|
|||
|
u32 start : 1; // 正在解码
|
|||
|
char *path; //音色文件路径
|
|||
|
struct audio_res_wait wait; // 资源等待句柄
|
|||
|
struct midi_ctrl_decoder midi_ctrl_dec;
|
|||
|
struct audio_mixer_ch mix_ch; // 叠加句柄
|
|||
|
struct audio_stream *stream; // 音频流
|
|||
|
};
|
|||
|
|
|||
|
struct _midi_obj *midi_ctrl_dec_hdl = NULL;
|
|||
|
|
|||
|
void midi_ctrl_ioctrl(u32 cmd, void *priv);
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief midi ctrl解码释放
|
|||
|
@param
|
|||
|
@return
|
|||
|
@note
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
void midi_ctrl_dec_relaese()
|
|||
|
{
|
|||
|
if (midi_ctrl_dec_hdl) {
|
|||
|
audio_decoder_task_del_wait(&decode_task, &midi_ctrl_dec_hdl->wait);
|
|||
|
clock_remove(DEC_MIDI_CLK);
|
|||
|
local_irq_disable();
|
|||
|
free(midi_ctrl_dec_hdl);
|
|||
|
midi_ctrl_dec_hdl = NULL;
|
|||
|
local_irq_enable();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief midi音色文件获取
|
|||
|
@param
|
|||
|
@return
|
|||
|
@note 内部调用
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
static int midi_get_cfg_addr(u8 **addr)
|
|||
|
{
|
|||
|
if (!midi_ctrl_dec_hdl) {
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
#ifndef CONFIG_MIDI_DEC_ADDR
|
|||
|
//音色文件支持在外部存储卡或者外挂flash,sdk默认使用本方式
|
|||
|
/* FILE *file = fopen("storage/sd0/C/MIDI.bin\0", "r"); */
|
|||
|
FILE *file = fopen(midi_ctrl_dec_hdl->path, "r");
|
|||
|
|
|||
|
/* FILE *file = fopen(SDFILE_RES_ROOT_PATH"MIDI.bin\0", "r"); */
|
|||
|
if (!file) {
|
|||
|
log_e("MIDI.bin open err\n");
|
|||
|
return -1;
|
|||
|
}
|
|||
|
*addr = (u8 *)file;
|
|||
|
log_i("midi_file %x\n", file);
|
|||
|
#else
|
|||
|
//音色文件仅支持在内置flash
|
|||
|
/* FILE *file = fopen(SDFILE_RES_ROOT_PATH"MIDI.bin\0", "r"); */
|
|||
|
FILE *file = fopen(midi_ctrl_dec_hdl->path, "r");
|
|||
|
if (!file) {
|
|||
|
log_e("MIDI.bin open err\n");
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
struct vfs_attr attr = {0};
|
|||
|
fget_attrs(file, &attr);
|
|||
|
*addr = (u8 *)attr.sclust;
|
|||
|
fclose(file);
|
|||
|
#endif
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief midi音色文件读
|
|||
|
@param
|
|||
|
@return
|
|||
|
@note 内部调用
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
static int midi_fread(void *file, void *buf, u32 len)
|
|||
|
{
|
|||
|
#ifndef CONFIG_MIDI_DEC_ADDR
|
|||
|
FILE *hd = (FILE *)file;
|
|||
|
if (hd) {
|
|||
|
len = fread(hd, buf, len);
|
|||
|
}
|
|||
|
#endif
|
|||
|
return len;
|
|||
|
}
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief midi音色文件seek
|
|||
|
@param
|
|||
|
@return
|
|||
|
@note 内部调用
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
static int midi_fseek(void *file, u32 offset, int seek_mode)
|
|||
|
{
|
|||
|
#ifndef CONFIG_MIDI_DEC_ADDR
|
|||
|
FILE *hd = (FILE *)file;
|
|||
|
if (hd) {
|
|||
|
fseek(hd, offset, seek_mode);
|
|||
|
}
|
|||
|
#endif
|
|||
|
return 0;
|
|||
|
}
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief midi ctrl初始化函数,该函数由库调用
|
|||
|
@param 参数返回地址
|
|||
|
@return 0
|
|||
|
@note 该函数是弱定义函数,不可修改定义
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
int midi_ctrl_init(void *info)
|
|||
|
{
|
|||
|
if (!midi_ctrl_dec_hdl) {
|
|||
|
return -1;
|
|||
|
}
|
|||
|
u8 *cache_addr;
|
|||
|
if (midi_get_cfg_addr(&cache_addr)) {
|
|||
|
return -1;
|
|||
|
}
|
|||
|
midi_ctrl_open_parm *parm = (midi_ctrl_open_parm *)info;
|
|||
|
parm->ctrl_parm.tempo = 1024;//解码会改变播放速度,1024是正常值
|
|||
|
parm->ctrl_parm.track_num = 1;//支持音轨的最大个数0~15
|
|||
|
|
|||
|
parm->sample_rate = midi_ctrl_dec_hdl->midi_ctrl_dec.sample_rate;//midi_samplerate_tab[5];
|
|||
|
parm->cfg_parm.player_t = MIDI_KEY_NUM; //(支持多少个key同时发声,用户可修改)
|
|||
|
parm->cfg_parm.spi_pos = (unsigned int)cache_addr;
|
|||
|
parm->cfg_parm.fread = midi_fread;
|
|||
|
parm->cfg_parm.fseek = midi_fseek;
|
|||
|
|
|||
|
for (int i = 0; i < ARRAY_SIZE(midi_samplerate_tab); i++) {
|
|||
|
if (parm->sample_rate == midi_samplerate_tab[i]) {
|
|||
|
parm->cfg_parm.sample_rate = i;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief midi ctrl音色文件关闭
|
|||
|
@param
|
|||
|
@return
|
|||
|
@note 该函数在midi关闭时调用,该函数是弱定义函数,不可修改定义
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
int midi_ctrl_uninit(void *priv)
|
|||
|
{
|
|||
|
#ifndef CONFIG_MIDI_DEC_ADDR
|
|||
|
if (priv) {
|
|||
|
fclose((FILE *)priv);
|
|||
|
priv = NULL;
|
|||
|
}
|
|||
|
#endif
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief 乐器更新
|
|||
|
@param prog:乐器号
|
|||
|
@param trk_num :音轨 (0~15)
|
|||
|
@return
|
|||
|
@note
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
void midi_ctrl_set_porg(u8 prog, u8 trk_num)
|
|||
|
{
|
|||
|
struct set_prog_parm parm = {0};
|
|||
|
parm.prog = prog;
|
|||
|
parm.trk_num = trk_num;
|
|||
|
midi_ctrl_ioctrl(MIDI_CTRL_SET_PROG, &parm);
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief 按键按下
|
|||
|
@param nkey:按键序号(0~127)
|
|||
|
@param nvel:按键力度(0~127)
|
|||
|
@param chn :通道(0~15)
|
|||
|
@return
|
|||
|
@note
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
void midi_ctrl_note_on(u8 nkey, u8 nvel, u8 chn)
|
|||
|
{
|
|||
|
struct note_on_parm parm = {0};
|
|||
|
parm.nkey = nkey;
|
|||
|
parm.nvel = nvel;
|
|||
|
parm.chn = chn;
|
|||
|
midi_ctrl_ioctrl(MIDI_CTRL_NOTE_ON, &parm);
|
|||
|
}
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief 按键松开
|
|||
|
@param nkey:按键序号(0~127)
|
|||
|
@param chn :通道(0~15)
|
|||
|
@return
|
|||
|
@note
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
void midi_ctrl_note_off(u8 nkey, u8 chn)
|
|||
|
{
|
|||
|
struct note_off_parm parm = {0};
|
|||
|
parm.nkey = nkey;
|
|||
|
parm.chn = chn;
|
|||
|
midi_ctrl_ioctrl(MIDI_CTRL_NOTE_OFF, &parm);
|
|||
|
}
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief midi 配置接口
|
|||
|
@param cmd:命令
|
|||
|
@param priv:对应cmd的结构体
|
|||
|
@return
|
|||
|
@note
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
void midi_ctrl_confing(u32 cmd, void *priv)
|
|||
|
{
|
|||
|
midi_ctrl_ioctrl(cmd, priv);
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief midi keyboard 设置按键按下音符发声的衰减系数
|
|||
|
@param obj:控制句柄
|
|||
|
@param samp:对应samplerate_tab坐标
|
|||
|
@return
|
|||
|
@note 低11bit为调节衰减系数,值越小,衰减越快, 1024为默认值, 范围:0~1024
|
|||
|
大于11bit为延时系数,节尾音长度的,值越大拉德越长,0为默认值,31延长1s,范围:0~31(延时系数无效)
|
|||
|
@example midi_ctrl_confing_set_melody_decay((衰减系数&0x7fff) | (延时系数&0x1f <<11));
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
void midi_ctrl_confing_set_melody_decay(u16 val)
|
|||
|
{
|
|||
|
u32 cmd = CMD_MIDI_CTRL_TEMPO;
|
|||
|
MIDI_PLAY_CTRL_TEMPO tempo = {0};
|
|||
|
tempo.decay_val = val;
|
|||
|
tempo.tempo_val = 1024;//设置为固定1024即可
|
|||
|
midi_ctrl_confing(cmd, (void *)&tempo);
|
|||
|
}
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief 弯音轮配置
|
|||
|
@param pitch_val:弯音轮值,1 - 65535 ;256是正常值,对音高有作用
|
|||
|
@param chn :通道(0~15)
|
|||
|
@return
|
|||
|
@note
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
void midi_ctrl_pitch_bend(u16 pitch_val, u8 chn)
|
|||
|
{
|
|||
|
struct pitch_bend_parm parm = {0};
|
|||
|
parm.pitch_val = pitch_val;
|
|||
|
parm.chn = chn;
|
|||
|
midi_ctrl_ioctrl(MIDI_CTRL_PITCH_BEND, &parm);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief midi ctrl解码数据流激活
|
|||
|
@param *p: 私有句柄
|
|||
|
@return
|
|||
|
@note
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
static void midi_ctrl_dec_out_stream_resume(void *p)
|
|||
|
{
|
|||
|
struct _midi_obj *dec = p;
|
|||
|
#if FILE_DEC_USE_OUT_TASK
|
|||
|
if (dec->midi_ctrl_dec.dec_no_out_sound == 0) {
|
|||
|
audio_decoder_resume_out_task(&dec->midi_ctrl_dec.decoder);
|
|||
|
return ;
|
|||
|
}
|
|||
|
#endif
|
|||
|
audio_decoder_resume(&dec->midi_ctrl_dec.decoder);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief midi ctrl解码事件处理
|
|||
|
@param *decoder: 解码器句柄
|
|||
|
@param argc: 参数个数
|
|||
|
@param *argv: 参数
|
|||
|
@return
|
|||
|
@note
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
static void midi_ctrl_dec_event_handler(struct audio_decoder *decoder, int argc, int *argv)
|
|||
|
{
|
|||
|
switch (argv[0]) {
|
|||
|
case AUDIO_DEC_EVENT_END:
|
|||
|
if (!midi_ctrl_dec_hdl) {
|
|||
|
log_i("midi_ctrl_dec_hdl handle err ");
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if (midi_ctrl_dec_hdl->id != argv[1]) {
|
|||
|
log_w("midi_ctrl_dec_hdl id err : 0x%x, 0x%x \n", midi_ctrl_dec_hdl->id, argv[1]);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
midi_ctrl_dec_close();
|
|||
|
//audio_decoder_resume_all(&decode_task);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief midi ctrl解码开始
|
|||
|
@param
|
|||
|
@return 0:成功
|
|||
|
@return 非0:失败
|
|||
|
@note
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
int midi_ctrl_dec_start()
|
|||
|
{
|
|||
|
int err;
|
|||
|
struct _midi_obj *dec = midi_ctrl_dec_hdl;
|
|||
|
|
|||
|
struct audio_mixer *p_mixer = &mixer;
|
|||
|
|
|||
|
if (!dec) {
|
|||
|
return -EINVAL;
|
|||
|
}
|
|||
|
|
|||
|
log_i("midi_ctrl dec start: in\n");
|
|||
|
// 打开midi ctrl解码器
|
|||
|
err = midi_ctrl_decoder_open(&dec->midi_ctrl_dec, &decode_task);
|
|||
|
if (err) {
|
|||
|
goto __err1;
|
|||
|
}
|
|||
|
|
|||
|
midi_ctrl_decoder_set_event_handler(&dec->midi_ctrl_dec, midi_ctrl_dec_event_handler, dec->id);
|
|||
|
|
|||
|
// 设置叠加功能
|
|||
|
audio_mixer_ch_open_head(&dec->mix_ch, p_mixer);
|
|||
|
audio_mixer_ch_set_src(&dec->mix_ch, 1, 0);
|
|||
|
|
|||
|
#if FILE_DEC_USE_OUT_TASK
|
|||
|
if (dec->midi_ctrl_dec.dec_no_out_sound == 0) {
|
|||
|
audio_decoder_out_task_ch_enable(&dec->midi_ctrl_dec.decoder);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
// 数据流串联
|
|||
|
struct audio_stream_entry *entries[8] = {NULL};
|
|||
|
u8 entry_cnt = 0;
|
|||
|
|
|||
|
entries[entry_cnt++] = &dec->midi_ctrl_dec.decoder.entry;
|
|||
|
entries[entry_cnt++] = &dec->mix_ch.entry;
|
|||
|
|
|||
|
// 创建数据流,把所有节点连接起来
|
|||
|
|
|||
|
dec->stream = audio_stream_open(dec, midi_ctrl_dec_out_stream_resume);
|
|||
|
audio_stream_add_list(dec->stream, entries, entry_cnt);
|
|||
|
|
|||
|
// 设置音频输出音量
|
|||
|
audio_output_set_start_volume(APP_AUDIO_STATE_MUSIC);
|
|||
|
// 设置时钟
|
|||
|
clock_set_cur();
|
|||
|
|
|||
|
// 开始解码
|
|||
|
dec->midi_ctrl_dec.status = FILE_DEC_STATUS_PLAY;
|
|||
|
err = audio_decoder_start(&dec->midi_ctrl_dec.decoder);
|
|||
|
dec->start = 1;
|
|||
|
if (err) {
|
|||
|
goto __err3;
|
|||
|
}
|
|||
|
return 0;
|
|||
|
__err3:
|
|||
|
audio_mixer_ch_close(&dec->mix_ch);
|
|||
|
|
|||
|
midi_ctrl_decoder_close(&dec->midi_ctrl_dec);
|
|||
|
|
|||
|
if (dec->stream) {
|
|||
|
audio_stream_close(dec->stream);
|
|||
|
dec->stream = NULL;
|
|||
|
}
|
|||
|
__err1:
|
|||
|
log_w(" start err close\n");
|
|||
|
midi_ctrl_dec_relaese();
|
|||
|
return -1;
|
|||
|
}
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief midi ctrl解码关闭
|
|||
|
@param
|
|||
|
@return
|
|||
|
@note
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
static void __midi_ctrl_dec_close(void)
|
|||
|
{
|
|||
|
if (midi_ctrl_dec_hdl && midi_ctrl_dec_hdl->start) {
|
|||
|
midi_ctrl_dec_hdl->start = 0;
|
|||
|
|
|||
|
midi_ctrl_decoder_close(&midi_ctrl_dec_hdl->midi_ctrl_dec);
|
|||
|
|
|||
|
audio_mixer_ch_close(&midi_ctrl_dec_hdl->mix_ch);
|
|||
|
|
|||
|
// 先关闭各个节点,最后才close数据流
|
|||
|
if (midi_ctrl_dec_hdl->stream) {
|
|||
|
audio_stream_close(midi_ctrl_dec_hdl->stream);
|
|||
|
midi_ctrl_dec_hdl->stream = NULL;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief 关闭midi ctrl解码
|
|||
|
@param
|
|||
|
@return
|
|||
|
@note
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
void midi_ctrl_dec_close(void)
|
|||
|
{
|
|||
|
if (!midi_ctrl_dec_hdl) {
|
|||
|
return;
|
|||
|
}
|
|||
|
__midi_ctrl_dec_close();
|
|||
|
midi_ctrl_dec_relaese();
|
|||
|
clock_set_cur();
|
|||
|
log_i("midi ctrl dec close \n\n ");
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief midi ctrl解码资源等待
|
|||
|
@param *wait: 句柄
|
|||
|
@param event: 事件
|
|||
|
@return 0:成功
|
|||
|
@note 用于多解码打断处理
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
static void __midi_ctrl_dec_close(void);
|
|||
|
static int midi_ctrl_wait_res_handler(struct audio_res_wait *wait, int event)
|
|||
|
{
|
|||
|
int err = 0;
|
|||
|
log_i("midi_ctrl_wait_res_handler, event:%d\n", event);
|
|||
|
if (event == AUDIO_RES_GET) {
|
|||
|
// 启动解码
|
|||
|
err = midi_ctrl_dec_start();
|
|||
|
} else if (event == AUDIO_RES_PUT) {
|
|||
|
// 被打断
|
|||
|
__midi_ctrl_dec_close();
|
|||
|
}
|
|||
|
|
|||
|
return err;
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief 打开midi ctrl解码
|
|||
|
@param sample_rate: 采样率
|
|||
|
@param *path:音色文件路径
|
|||
|
@return 0:成功
|
|||
|
@return 非0:失败
|
|||
|
@note
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
int midi_ctrl_dec_open(u32 sample_rate, char *path)
|
|||
|
{
|
|||
|
int err = 0;
|
|||
|
int i = 0;
|
|||
|
struct _midi_obj *dec;
|
|||
|
dec = zalloc(sizeof(*dec));
|
|||
|
if (!dec) {
|
|||
|
return -ENOMEM;
|
|||
|
}
|
|||
|
midi_ctrl_dec_hdl = dec;
|
|||
|
dec->id = rand32();
|
|||
|
dec->path = path;
|
|||
|
|
|||
|
dec->midi_ctrl_dec.ch_num = 2;
|
|||
|
|
|||
|
dec->midi_ctrl_dec.output_ch_num = audio_output_channel_num();
|
|||
|
dec->midi_ctrl_dec.output_ch_type = audio_output_channel_type();
|
|||
|
#if TCFG_MIC_EFFECT_ENABLE
|
|||
|
dec->midi_ctrl_dec.sample_rate = MIC_EFFECT_SAMPLERATE;
|
|||
|
#else
|
|||
|
for (i = 0; i < ARRAY_SIZE(midi_samplerate_tab); i++) {
|
|||
|
if (sample_rate == midi_samplerate_tab[i]) {
|
|||
|
dec->midi_ctrl_dec.sample_rate = midi_samplerate_tab[i];
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if (i >= ARRAY_SIZE(midi_samplerate_tab)) {
|
|||
|
dec->midi_ctrl_dec.sample_rate = 16000;
|
|||
|
log_e("midi sample_rate check err ,will set default 16000 Hz\n");
|
|||
|
}
|
|||
|
#endif
|
|||
|
dec->wait.priority = 2;
|
|||
|
dec->wait.preemption = 0;
|
|||
|
dec->wait.snatch_same_prio = 1;
|
|||
|
/* dec->wait.protect = 1; */
|
|||
|
dec->wait.handler = midi_ctrl_wait_res_handler;
|
|||
|
clock_add(DEC_MIDI_CLK);
|
|||
|
|
|||
|
|
|||
|
err = audio_decoder_task_add_wait(&decode_task, &dec->wait);
|
|||
|
return err;
|
|||
|
}
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief midi ctrl控制函数
|
|||
|
@param cmd:
|
|||
|
MIDI_CTRL_NOTE_ON, //按键按下,参数结构对应struct note_on_parm
|
|||
|
MIDI_CTRL_NOTE_OFF, //按键松开,参数结构对应struct note_off_parm
|
|||
|
MIDI_CTRL_SET_PROG, //更改乐器,参数结构对应struct set_prog_parm
|
|||
|
MIDI_CTRL_PITCH_BEND, //弯音轮,参数结构对应struct pitch_bend_parm
|
|||
|
CMD_MIDI_CTRL_TEMPO, //改变节奏,参数结构对应 MIDI_PLAY_CTRL_TEMPO
|
|||
|
@param priv:对应cmd的参数地址
|
|||
|
@return 0
|
|||
|
@note midi解码控制例程
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
void midi_ctrl_ioctrl(u32 cmd, void *priv)
|
|||
|
{
|
|||
|
struct _midi_obj *dec = midi_ctrl_dec_hdl;
|
|||
|
if (!dec) {
|
|||
|
log_e("midi ctrl dec NULL\n");
|
|||
|
return ;
|
|||
|
}
|
|||
|
|
|||
|
log_i("midi ctrl cmd %x", cmd);
|
|||
|
audio_decoder_ioctrl(&dec->midi_ctrl_dec.decoder, cmd, priv);
|
|||
|
}
|
|||
|
|
|||
|
#if 0
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
/**@brief midi key 测试样例
|
|||
|
@param
|
|||
|
@return
|
|||
|
@note
|
|||
|
*/
|
|||
|
/*----------------------------------------------------------------------------*/
|
|||
|
void midi_paly_test(u32 key)
|
|||
|
{
|
|||
|
static u8 open_close = 0;
|
|||
|
static u8 change_prog = 0;
|
|||
|
static u8 note_on_off = 0;
|
|||
|
switch (key) {
|
|||
|
case KEY_IR_NUM_0:
|
|||
|
if (!open_close) {
|
|||
|
/* midi_ctrl_dec_open(16000);//启动midi key */
|
|||
|
/* midi_ctrl_dec_open(16000, "storage/sd0/C/MIDI.bin\0");//启动midi key */
|
|||
|
midi_ctrl_dec_open(16000, SDFILE_RES_ROOT_PATH"MIDI.bin\0");//启动midi key
|
|||
|
|
|||
|
} else {
|
|||
|
midi_ctrl_dec_close();//关闭midi key
|
|||
|
}
|
|||
|
open_close = !open_close;
|
|||
|
break;
|
|||
|
case KEY_IR_NUM_1:
|
|||
|
if (!change_prog) {
|
|||
|
midi_ctrl_set_porg(0, 0);//设置0号乐器,音轨0
|
|||
|
} else {
|
|||
|
midi_ctrl_set_porg(22, 0);//设置22号乐器,音轨0
|
|||
|
}
|
|||
|
change_prog = !change_prog;
|
|||
|
break;
|
|||
|
case KEY_IR_NUM_2:
|
|||
|
if (!note_on_off) {
|
|||
|
//模拟按键57、58、59、60、61、62,以力度127,通道0,按下测试
|
|||
|
midi_ctrl_note_on(57, 127, 0);
|
|||
|
midi_ctrl_note_on(58, 127, 0);
|
|||
|
midi_ctrl_note_on(59, 127, 0);
|
|||
|
midi_ctrl_note_on(60, 127, 0);
|
|||
|
midi_ctrl_note_on(61, 127, 0);
|
|||
|
midi_ctrl_note_on(62, 127, 0);
|
|||
|
} else {
|
|||
|
//模拟按键57、58、59、60、61、62松开测试
|
|||
|
midi_ctrl_note_off(57, 0);
|
|||
|
midi_ctrl_note_off(58, 0);
|
|||
|
midi_ctrl_note_off(59, 0);
|
|||
|
midi_ctrl_note_off(60, 0);
|
|||
|
midi_ctrl_note_off(61, 0);
|
|||
|
midi_ctrl_note_off(62, 0);
|
|||
|
}
|
|||
|
note_on_off = !note_on_off;
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
#endif
|