ESP32 ADF pipeline切换时遇到问题---音频没有放出

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhejfl/article/details/88538444

1、问题描述

成功切换的LOG

[2019-03-13 14:48:06.736]# RECV ASCII>
[0;32mI (5181) STAGEFRIGHTMP3_DECODER: MP3 decodig done[0m
[0;32mI (5181) STAGEFRIGHTMP3_DECODER: Closed[0m
[0;32mI (5231) AUDIO_ELEMENT: IN-[i2s] AEL_IO_DONE,-2[0m
[0;33mW (5261) Somnic_music: [ * ] Stop event received[0m
[0;33mW (5271) AUDIO_PIPELINE: create new rb, linked:1, rb:0x3f802bd8, cur_el:bt[0m
[0;32mI (5271) AUDIO_ELEMENT: [bt] Element task created[0m
[0;32mI (5271) AUDIO_PIPELINE: Func:audio_pipeline_run, Line:278, MEM Total:4280908 Bytes, Inter:125296 Bytes, Dram:106384 Byte

[2019-03-13 14:48:06.809]# RECV ASCII>
s

[0m
[0;32mI (5281) AUDIO_PIPELINE: Pipeline started[0m
[0;32mI (5281) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:1[0m
[0;32mI (5291) I2S_STREAM: AUDIO_STREAM_WRITER[0m
[0;32mI (5311) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:2[0m


[2019-03-13 14:48:41.994]# RECV ASCII>
[0;31mE (40461) BT_APPL: bta_av_rc_create ACP handle exist for shdl:0[0m
[0;32mI (40501) Somnic_music: [ * ] Receive music info from Bluetooth, sample_rates=44100, bits=16, ch=2[0m
[0;32mI (40521) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_PAUSE[0m
[0;32mI (40521) I2S: APLL: Req RATE: 44100, real rate: 43945.238, BITS: 16, CLKM: 1, BCK_M: 8, MCLK: 11249981.000, SCLK: 1406247.625000, diva: 1, divb: 0[0m
[0;33mW (40531) BT_APPL: new conn_srvc id:19, app_id:0[0m
[0;32mI (40531) AUDIO_ELEMENT: [i2s] AEL_M

[2019-03-13 14:48:42.068]# RECV ASCII>
SG_CMD_RESUME,state:3[0m
[0;32mI (40541) I2S_STREAM: AUDIO_STREAM_WRITER[0m
[0;31mE (40551) Somnic_music: [ * ] Action command error: src_type:1048585, source:0x3ffe463c cmd:1, data:0x0, data_len:0[0m
[0;32mI (40561) Somnic_music: [ * ] Bluetooth audio connected

[0m


[2019-03-13 14:48:44.490]# RECV ASCII>
[0;32mI (42991) BT_LOG: bta_av_link_role_ok hndl:x41 role:1 conn_audio:x1 bits:1 features:x824b
[0m
[0;33mW (42991) BT_APPL: new conn_srvc id:19, app_id:1[0m
[0;32mI (42991) Somnic_music: [ * ] Bluetooth audio started

失败的切换LOG

[0;32mI (63011) STAGEFRIGHTMP3_DECODER: MP3 decodig done[0m
[0;32mI (63011) STAGEFRIGHTMP3_DECODER: Closed[0m
[0;32mI (63061) AUDIO_ELEMENT: IN-[i2s] AEL_IO_DONE,-2[0m
[0;33mW (63091) Somnic_music: [ * ] Stop event received[0m
[0;32mI (63091) AUDIO_PIPELINE: found kept rb:0x3f802bd8 kept:1,linked:1, el:0x3f80017c, name:bt[0m
[0;32mI (63101) AUDIO_PIPELINE: Func:audio_pipeline_run, Line:278, MEM Total:4271628 Bytes, Inter:124288 Bytes, Dram:105376 Bytes

[0m
[0;32mI (63111) AUDIO_PIPELINE

[2019-03-13 14:49:04.640]# RECV ASCII>
: Pipeline started[0m
[0;32mI (63111) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:1[0m
[0;32mI (63121) I2S_STREAM: AUDIO_STREAM_WRITER[0m
[0;32mI (63141) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:2[0m


[2019-03-13 14:49:12.510]# RECV ASCII>
[0;31mE (70971) BT_APPL: rcb[0].lidx=3, lcb.conn_msk=x1[0m
[0;31mE (70981) BT_APPL: bta_av_rc_create ACP handle exist for shdl:0[0m
[0;32mI (71021) Somnic_music: [ * ] Receive music info from Bluetooth, sample_rates=44100, bits=16, ch=2[0m
[0;33mW (71041) BT_APPL: new conn_srvc id:19, app_id:0[0m
[0;32mI (71041) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_PAUSE[0m
[0;32mI (71051) I2S: APLL: Req RATE: 44100, real rate: 43945.238, BITS: 16, CLKM: 1, BCK_M: 8, MCLK: 11249981.000, SCLK: 1406247.625000, div

[2019-03-13 14:49:12.581]# RECV ASCII>
a: 1, divb: 0[0m
[0;31mE (71061) Somnic_music: [ * ] Action command error: src_type:1048585, source:0x3ffe463c cmd:1, data:0x0, data_len:0[0m
[0;32mI (71061) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:3[0m
[0;32mI (71071) Somnic_music: [ * ] Bluetooth audio connected

[0m
[0;32mI (71071) I2S_STREAM: AUDIO_STREAM_WRITER[0m


对比看,没发现有多大不同。

#define AUDIO_MEM_SHOW(x)  audio_mem_print(x, __LINE__, __func__)
void audio_mem_print(const char *tag, int line, const char *func)
{
#ifdef CONFIG_SPIRAM_BOOT_INIT
    ESP_LOGI(tag, "Func:%s, Line:%d, MEM Total:%d Bytes, Inter:%d Bytes, Dram:%d Bytes\r\n", func, line, esp_get_free_heap_size(),
             heap_caps_get_free_size(MALLOC_CAP_INTERNAL), heap_caps_get_free_size(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT));
#else
    ESP_LOGI(tag, "Func:%s, Line:%d, MEM Total:%d Bytes\r\n", func, line, esp_get_free_heap_size());
#endif
}

2、原因查找 

static void bt_a2d_sink_data_cb(const uint8_t *data, uint32_t len)
{
	if (g_bt_service->stream) {
		if (audio_element_get_state(g_bt_service->stream) == AEL_STATE_RUNNING) {
			audio_element_output(g_bt_service->stream, (char *)data, len);

		}
	}

}

问题出在data_cb上,由于蓝牙数据流在AEL_STATE_INIT状态,不能把数据传给下一个元素(即I2S数据流)的buffer中去。

因此就需要查看为什么蓝牙数据流没有切换至AEL_STATE_RUNNING。

经过分析

esp_err_t audio_element_resume(audio_element_handle_t el, float wait_for_rb_threshold, TickType_t timeout)
{

    if (!el->task_run) {
        ESP_LOGW(TAG, "[%s] Element has not create when AUDIO_ELEMENT_RESUME", el->tag);
        return ESP_FAIL;
    }

    if ((el->is_running) || (el->state == AEL_STATE_RUNNING)) {
        ESP_LOGD(TAG, "[%s] RESUME: Element is already running, state:%d, task_run:%d", el->tag, el->state, el->task_run);
       // audio_element_force_set_state(el, AEL_STATE_RUNNING);
        return ESP_OK;
    }

    if (el->task_stack <= 0) {
    	ESP_LOGI(TAG,"[%s] FORCE SET RUNNING STATE\r\n",el->tag);
        audio_element_force_set_state(el, AEL_STATE_RUNNING);
        return ESP_OK;
    }

    if (el->state == AEL_STATE_ERROR) {
        ESP_LOGE(TAG, "[%s] RESUME: Element error, state:%d", el->tag, el->state);
        return ESP_FAIL;
    }
    if (el->state == AEL_STATE_FINISHED) {
        ESP_LOGI(TAG, "[%s] RESUME: Element has finished, state:%d", el->tag, el->state);
        return ESP_OK;
    }
    if (wait_for_rb_threshold > 1 || wait_for_rb_threshold < 0) {
        return ESP_FAIL;
    }
    int ret =  ESP_OK;
    audio_element_cmd_send(el, AEL_MSG_CMD_RESUME);
    if (wait_for_rb_threshold != 0 && el->read_type == IO_TYPE_RB) {
        ret = audio_element_wait_for_buffer(el, rb_get_size(el->in.input_rb) * wait_for_rb_threshold, timeout);
    }
    return ret;
}

主要是对于蓝牙数据流el->is_running是true,直接返回,但是其实el->state却是AEL_STATE_INIT,而回调函数判的是state的状态。

解决方法,就是把上述代码// audio_element_force_set_state(el, AEL_STATE_RUNNING);的注释打开。

3、解决问题的方法

首先这是本地播放和蓝牙播放互相切换造成的问题,而本地播放时可以的,蓝牙播放却不行。,根据下图分析,应该是蓝牙数据流到I2S数据流之间的数据有问题,或者蓝牙其他原因。

 

展开阅读全文

移植后的mplayer无法播放出音频

04-21

在CSDN里看到一高手移植后, 我也照他的方法移植了mplayer,出现在情况一样rnrn不过我用的是QQ2440 ,内核是2.6.23rnrn在内核里找了好久,都找不到那段代码.rnrn在UDA1341.C里找不到要改的代码,那位大哥帮帮忙rnrn哪位对驱动熟悉的帮一下哦rnrnrn解决的办法是在音频驱动源码的smdk2410_audio_open()函数体,加上如下一段代码, rn rn if (!output_stream .buffers && audio_setup_buf(&output_stream)) rn rn rn return -ENOMEM; rn rn 添加的位置具体见以下代码的粗体部分: rn rn rn rn static int smdk2410_audio_open(struct inode *inode, struct file *file) rn rn rn rn int cold = !audio_active; rn rn rn rn DPRINTK("audio_open\n"); rn rn rn rn if ((file->f_flags & O_ACCMODE) == O_RDONLY) rn rn if (audio_rd_refcount || audio_wr_refcount) rn rn return -EBUSY; rn rn audio_rd_refcount++; rn rn else if ((file->f_flags & O_ACCMODE) == O_WRONLY) rn rn if (audio_wr_refcount) rn rn return -EBUSY; rn rn audio_wr_refcount++; rn rn else if ((file->f_flags & O_ACCMODE) == O_RDWR) rn rn if (audio_rd_refcount || audio_wr_refcount) rn rn return -EBUSY; rn rn audio_rd_refcount++; rn rn audio_wr_refcount++; rn rn else rn rn return -EINVAL; rn rn rn rn if (cold) rn rn audio_rate = AUDIO_RATE_DEFAULT; rn rn audio_channels = AUDIO_CHANNELS_DEFAULT; rn rn audio_fragsize = AUDIO_FRAGSIZE_DEFAULT; rn rn audio_nbfrags = AUDIO_NBFRAGS_DEFAULT; rn rn if ((file->f_mode & FMODE_WRITE)) rn rn init_s3c2410_iis_bus_tx(); rn rn audio_clear_buf(&output_stream); rn rn // 加上以下这行代码 rn rn rn if (!output_stream .buffers && audio_setup_buf(&output_stream)) rn rn rn return -ENOMEM; rn rn rn rn if ((file->f_mode & FMODE_READ)) rn rn init_s3c2410_iis_bus_rx(); rn rn audio_clear_buf(&input_stream); rn rn rn rn rn rn rn rn MOD_INC_USE_COUNT; rn rn rn rn return 0; rn rn rn 论坛

放出代码

04-09

电子科技大学电子工程学院, 张舒编写rnrn简单的BP神经网络训练程序移植,抛砖引玉rnrnNERVENET.TXT : 原来的MATLAB程序rnNERVENET.CU : HOST程序rnNERNENET_KERNEL.CU : GLOBAL 和 DEVICE 程序rnNERVENET_EVLUE.TXT : 用于察看CUDA运行后结果的MATLAB程序rnrn程序在MATLAB 7.1,VS 2005,CUDA 1.0 下编译通过,注意:不能用EMUDEBUG,EMURELEASE模式进行编译。rn运行完CUDA程序后会在D盘生成两个DAT文件,结束程序时会报错,水平有限还不知道怎么解决。在MATLAB中把NERVENET_EVALUE.TXT的内容考进命令行即可看结果。rnrn可以尝试用CUBLAS的内存分配程序修改rn如果要提高效率可以把样本矩阵放进TEXTURE,不过CUBLAS好像不认,可能要自己写CORE了rnrn本例程中神经元个数太少,体现不出CUDA的优势,对MATLAB程序的加速比也只有9-10左右rn据我分析,CUBLAS的SGEMM用的好像也是棋盘法rnrn好像没法上传附件...直接贴代码了rnrn原来的matlab程序:rn[code=MSIL]rnrnInDim = 2;rnOutDim = 3;rnrnfigurerncolordef(gcf,'white')rnecho offrnclcrnaxis([-2,2,-2,2])rnaxis on rngridrnxlabel('Input x')rnylabel('input y')rnline([-1 1],[1 1])rnline([1 -1],[1 0])rnline([-1 -1],[0 1])rnline([-1 1],[-0.5 -0.5])rnline([-1 1],[-1.5 -1.5])rnline([-1 -1],[-0.5 -1.5])rnline([1 1],[-0.5 -1.5])rnhold onrnrnSamNum=200;rnrand('state',sum(100*clock))rnSamIn=(rand(2,SamNum)-0.5)*4;rnrnSamOut=[];rnfor i =1:SamNumrnSam = SamIn(:,i);rnx = Sam(1,1);rny = Sam(2,1);rnif((x>-1)&(x<1))==1rnif((y>x/2+1/2)&(y<1))==1rnplot(x,y,'k+')rnclass=[0 1 0]';rnelseif((y<-0.5)&(y>-1.5))==1rnplot(x,y,'ks')rnclass=[0 0 1]';rnelsernplot(x,y,'ko')rnclass=[1 0 0]';rnendrnelsernplot(x,y,'ko')rnclass=[1 0 0]';rnendrnSamOut=[SamOut class];rnendrnrnHiddenUnitNum=10;rnMaxEpochs=10000;rnlr=0.1;rnE0=0.01;rnrnW1=0.2*rand(HiddenUnitNum,InDim)-0.1;rnB1=0.2*rand(HiddenUnitNum,1)-0.1;rnW2=0.2*rand(OutDim,HiddenUnitNum)-0.1;rnB2=0.2*rand(OutDim,1)-0.1;rnrnW1Ex=[W1 B1];rnW2Ex=[W2 B2];rnrnSamInEx=[SamIn' ones(SamNum,1)]';rnErrHistory=[];rnrnfor i=1:MaxEpochsrnHiddenOut=logsig(W1Ex*SamInEx);rnHiddenOutEx=[HiddenOut' ones(SamNum,1)]';rnNetworkOut=logsig(W2Ex*HiddenOutEx);rnError=SamOut-NetworkOut;rnSSE=sumsqr(Error);rnrnErrHistory=[ErrHistory SSE];rnrnif SSE-1)&(x<1))==1rnif((y>x/2+0.5)&(y<1))==1rnTestTargetOut=[TestTargetOut 2];rnelseif((y<-0.5)&(y>-1.5))==1;rnTestTargetOut=[TestTargetOut 3];rnelsernTestTargetOut=[TestTargetOut 1];rnendrnelsernTestTargetOut=[TestTargetOut 1];rnendrnendrnrnrnNNC1Flag=abs(NNClass-1)<0.1;rnNNC2Flag=abs(NNClass-2)<0.1;rnNNC3Flag=abs(NNClass-3)<0.1;rnrnTargetC1Flag=abs(TestTargetOut-1)<0.1;rnTargetC2Flag=abs(TestTargetOut-2)<0.1;rnTargetC3Flag=abs(TestTargetOut-3)<0.1;rnrnTest_C1_num=sum(NNC1Flag)rnTest_C2_num=sum(NNC2Flag)rnTest_C3_num=sum(NNC3Flag)rnrnTest_C1_C1=1.0*NNC1Flag*TargetC1Flag'rnTest_C1_C2=1.0*NNC1Flag*TargetC2Flag'rnTest_C1_C3=1.0*NNC1Flag*TargetC3Flag'rnrnTest_C2_c1=1.0*NNC2Flag*TargetC1Flag'rnTest_C2_C2=1.0*NNC2Flag*TargetC2Flag'rnTest_C2_C3=1.0*NNC2Flag*TargetC3Flag'rnrnTest_C3_C1=1.0*NNC3Flag*TargetC1Flag'rnTest_C3_C2=1.0*NNC3Flag*TargetC2Flag'rnTest_C3_C3=1.0*NNC3Flag*TargetC3Flag'rnrnTest_Correct=(Test_C1_C1+Test_C2_C2+Test_C3_C3)/TestSamNum[/code] 论坛

没有更多推荐了,返回首页