Просмотр исходного кода

fix:有部分MP3的一些帧是错误的,需要跳过

alienwalker 4 лет назад
Родитель
Сommit
3e549e4a7c
2 измененных файлов с 32 добавлено и 32 удалено
  1. 15 15
      components/multimedia/luat_lib_multimedia.c
  2. 17 17
      demo/multimedia/Air105/music_demo.lua

+ 15 - 15
components/multimedia/luat_lib_multimedia.c

@@ -256,6 +256,7 @@ decoder从文件数据中解析出音频数据
 @coder 解码用的decoder
 @zbuff 存放输入数据的zbuff
 @zbuff 存放输出数据的zbuff,空间必须不少于16KB
+@boolean后续有没有新数据,false表示没有了
 @return
 @boolean 是否成功解析
 @usage
@@ -264,10 +265,14 @@ local result = codec.get_audio_data(coder, "xxx", zbuff)
 static int l_codec_get_audio_data(lua_State *L) {
 	luat_multimedia_codec_t *coder = (luat_multimedia_codec_t *)lua_touserdata(L, 1);
 	uint32_t pos = 0;
-	uint32_t frame_len = 0;
 	int result;
 	luat_zbuff_t *in_buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
 	luat_zbuff_t *out_buff = ((luat_zbuff_t *)luaL_checkudata(L, 3, LUAT_ZBUFF_TYPE));
+	uint32_t is_not_end = 1;
+	if (lua_isboolean(L, 4))
+	{
+		is_not_end = lua_toboolean(L, 4);
+	}
 	mp3dec_frame_info_t info;
 	out_buff->used = 0;
 	if (coder)
@@ -277,24 +282,20 @@ static int l_codec_get_audio_data(lua_State *L) {
 		case MULTIMEDIA_DATA_TYPE_MP3:
 			do
 			{
+				memset(&info, 0, sizeof(info));
 				result = mp3dec_decode_frame(coder->mp3_decoder, in_buff->addr + pos, in_buff->used - pos, out_buff->addr + out_buff->used, &info);
-//				LLOGD("result %u,%u,%u", result, info.frame_bytes, pos);
+//				LLOGD("111 %u,%u,%u,%u,%u", result, info.frame_bytes, info.hz, info.layer, in_buff->used - pos);
 				out_buff->used += (result * info.channels * 2);
-				if (result)
-				{
-					pos += info.frame_bytes;
-					frame_len = (frame_len > info.frame_bytes)?frame_len:(info.frame_bytes + 16);
+				if (!result) {
+					LLOGD("jump %dbyte", info.frame_bytes);
 				}
-//				else
-//				{
-//					LLOGD("!!!");
-//				}
-				if ((out_buff->len - out_buff->used) < MINIMP3_MAX_SAMPLES_PER_FRAME)
+				pos += info.frame_bytes;
+				if ((out_buff->len - out_buff->used) < (MINIMP3_MAX_SAMPLES_PER_FRAME * 2))
 				{
 					__zbuff_resize(out_buff, out_buff->len * 2);
 				}
-			} while ((result > 0) && ((in_buff->used - pos) >= frame_len));
-//			LLOGD("result %u,%u,%u", result, in_buff->used - pos, info.frame_bytes);
+			} while ((in_buff->used - pos) >= (MINIMP3_MAX_SAMPLES_PER_FRAME * is_not_end + 1));
+//			LLOGD("result %u,%u,%u,%u", result, in_buff->used, pos, info.frame_bytes);
 			if (pos >= in_buff->used)
 			{
 				in_buff->used = 0;
@@ -311,8 +312,7 @@ static int l_codec_get_audio_data(lua_State *L) {
 
     }
 	lua_pushboolean(L, result);
-	lua_pushinteger(L, frame_len);
-	return 2;
+	return 1;
 }
 
 /**

+ 17 - 17
demo/multimedia/Air105/music_demo.lua

@@ -21,10 +21,10 @@ end)
 -- music文件夾,可以換成你自己的目录,不用加/sd/,demo里固定用TF卡目录,如果要本地目录,自行修改
 local music_dir = "/music/"
 
-sys.taskInit(function()
+function music_demo_start()
     sys.wait(100) -- 启动延时
     local tag_len = 0
-    local frame_len = 1045
+    local frame_len = 1152 * 4
     local spiId = 0
     local result = spi.setup(
         spiId,--串口id
@@ -44,7 +44,7 @@ sys.taskInit(function()
     -- usbapp.start(0)
     -- sys.wait(600000)
     local buff = zbuff.create(1024)
-    local in_buff = zbuff.create(8 * 1024 + 512)
+    local in_buff = zbuff.create(frame_len * 2 + 512)
     local play_list = {}
     if data then
         log.info("fatfs", "getfree", json.encode(data))
@@ -71,36 +71,36 @@ sys.taskInit(function()
                             f:seek(SEEK_SET, tag_len)
                         end
                         in_buff:del()
-                        data = f:read(2048)
+                        data = f:read(frame_len)
                         codecr = codec.create(codec.MP3)
                         local result, AudioFormat, NumChannels, SampleRate, BitsPerSample, is_signed = codec.get_audio_info(codecr, data)
                         if result then
                             log.info("mp3 info", NumChannels, SampleRate, BitsPerSample)
                             buff:resize(65536)
                             in_buff:copy(nil, data)
-                            result, frame_len = codec.get_audio_data(codecr, in_buff, buff)
-                            log.debug("frame_len",frame_len)
-                            in_buff:resize(frame_len * 8 + 512)
+                            result = codec.get_audio_data(codecr, in_buff, buff)
                             log.debug("start", audio.start(0, AudioFormat, NumChannels, SampleRate, BitsPerSample, is_signed))
                             audio.write(0, buff)
                             --local tick1,_ = mcu.tick64()
-                            data = f:read(frame_len * 4)
+                            data = f:read(frame_len)
                             in_buff:copy(nil, data) 
-                            result,_ = codec.get_audio_data(codecr, in_buff, buff)
+                            result = codec.get_audio_data(codecr, in_buff, buff)
                             --local tick2,_ = mcu.tick64()
                             --log.debug(mcu.dtick64(tick2, tick1)/_)
                             audio.write(0, buff)
-                            data = f:read(frame_len * 4)
-                            while result and data and #data > 0 do
+                            data = f:read(frame_len)
+                            while result do
                                 sys.waitUntil("moredata", 2000)
+                                data = f:read(frame_len)
                                 in_buff:copy(nil, data) 
-                                result,_= codec.get_audio_data(codecr, in_buff, buff)
-                                if result then
-                                    audio.write(0, buff)
-                                    data = f:read(frame_len * 4)
-                                else
+                                if #data ~= frame_len then
+                                    result = codec.get_audio_data(codecr, in_buff, buff, false)
                                     log.info("解码结束")
+                                    result = false
+                                else
+                                    result = codec.get_audio_data(codecr, in_buff, buff)
                                 end
+                                audio.write(0, buff)
                             end
                             sys.waitUntil("playover", 2000)           
                             
@@ -164,4 +164,4 @@ sys.taskInit(function()
     else
         log.info("fatfs", "err", err)
     end
-end)
+end