Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources
This commit is contained in:
768
sdk/app/audio_media_ctrl/mp3/mp3_decode.c
Normal file
768
sdk/app/audio_media_ctrl/mp3/mp3_decode.c
Normal file
@@ -0,0 +1,768 @@
|
||||
#include "basic_include.h"
|
||||
#include "csi_kernel.h"
|
||||
#include "lib/multimedia/msi.h"
|
||||
#include "lib/multimedia/framebuff.h"
|
||||
#include "lib/audio/audio_code/audio_code.h"
|
||||
#include "autpc_msi/autpc_msi.h"
|
||||
#include "osal_file.h"
|
||||
#include "mp3_decode.h"
|
||||
#include "mp3_getInfo.h"
|
||||
|
||||
#define BUFF_SIZE 2048
|
||||
#define MAX_MP3_DECODE_RXBUF 4
|
||||
#define MAX_MP3_DECODE_TXBUF 8
|
||||
|
||||
struct mp3_decode_struct {
|
||||
AUDIO_TRACK audio_track;
|
||||
struct fbpool tx_pool;
|
||||
struct os_event event;
|
||||
struct msi *msi;
|
||||
struct msi *src_msi;
|
||||
struct msi *autpc_msi;
|
||||
char *msi_name;
|
||||
void *task_hdl;
|
||||
void *mp3_fp;
|
||||
uint8_t mp3_filename[20];
|
||||
uint8_t loop_mode;
|
||||
uint8_t direct_to_dac;
|
||||
uint8_t use_tpc;
|
||||
uint8_t speed;
|
||||
uint8_t pitch;
|
||||
uint8_t destroy_self;
|
||||
uint8_t get_first_frame;
|
||||
uint8_t next_status;
|
||||
uint8_t current_status;
|
||||
uint8_t inbuf[BUFF_SIZE];
|
||||
int16_t dec_buf[1152*2];
|
||||
uint32_t file_size;
|
||||
uint32_t buf_offset;
|
||||
uint32_t buf_size;
|
||||
CUR_MP3_INFO *cur_mp3_info;
|
||||
};
|
||||
|
||||
static int32_t mp3_file_read(struct mp3_decode_struct *mp3_decode_s, uint8_t *buf, uint32_t size)
|
||||
{
|
||||
int32_t read_len = 0;
|
||||
|
||||
read_len = osal_fread(buf, size, 1, mp3_decode_s->mp3_fp);
|
||||
return read_len;
|
||||
}
|
||||
|
||||
static void mp3_file_decode(struct mp3_decode_struct *s)
|
||||
{
|
||||
uint8_t endOfRead = 0;
|
||||
uint8_t *enc_ptr = NULL;
|
||||
int16_t *data = NULL;
|
||||
int32_t ret = 0;
|
||||
int32_t dec_samples = 0;
|
||||
int32_t read_len = 0;
|
||||
int32_t unproc_data_size = 0;
|
||||
int32_t ID3V2_offset = 0;
|
||||
uint32_t ID3V2_len = 0;
|
||||
uint32_t enc_ptr_offset = 0;
|
||||
uint32_t bytes_to_read = 0;
|
||||
uint32_t interval_time = 0;
|
||||
struct framebuff *frame_buf = NULL;
|
||||
AUCODE_HDL *mp3_dec = NULL;
|
||||
AUCODE_FRAME_INFO mp3_info;
|
||||
AUDIO_TRACK *audac_fiter_track = NULL;
|
||||
|
||||
while(!s->get_first_frame) {
|
||||
bytes_to_read = BUFF_SIZE - unproc_data_size;
|
||||
read_len = mp3_file_read(s, s->inbuf+unproc_data_size,bytes_to_read);
|
||||
if(read_len <= 0) {
|
||||
MP3_INFO("mp3 read fail,ret:%d,line:%d!\r\n",read_len,__LINE__);
|
||||
goto mp3_decode_end;
|
||||
}
|
||||
s->buf_size = read_len + unproc_data_size;
|
||||
if(os_strncmp(s->inbuf, "ID3", 3) == 0) {
|
||||
if (s->buf_size < 10) {
|
||||
unproc_data_size = s->buf_size;
|
||||
os_sleep_ms(1);
|
||||
continue;
|
||||
}
|
||||
ID3V2_len = (s->inbuf[6]&0x7F)*0x200000+ (s->inbuf[7]&0x7F)*0x4000 +
|
||||
(s->inbuf[8]&0x7F)*0x80 +(s->inbuf[9]&0x7F);
|
||||
ID3V2_offset = (ID3V2_len+10);
|
||||
while(ID3V2_offset >= s->buf_size) {
|
||||
os_sleep_ms(1);
|
||||
ID3V2_offset -= s->buf_size;
|
||||
read_len = mp3_file_read(s, s->inbuf,BUFF_SIZE);
|
||||
if(read_len <= 0) {
|
||||
MP3_INFO("mp3 read fail,ret:%d,line:%d!\r\n",read_len,__LINE__);
|
||||
goto mp3_decode_end;
|
||||
}
|
||||
s->buf_size = read_len;
|
||||
}
|
||||
if(ID3V2_offset) {
|
||||
s->buf_size -= ID3V2_offset;
|
||||
os_memcpy(s->inbuf, s->inbuf+ID3V2_offset, s->buf_size);
|
||||
}
|
||||
if(s->buf_size <= 1) {
|
||||
os_sleep_ms(1);
|
||||
unproc_data_size = s->buf_size;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for(uint32_t i=0; i<(s->buf_size-1); i++) {
|
||||
if( ( (s->inbuf[i] << 8) | (s->inbuf[i+1] & 0xE0) ) == 0xFFE0 ) {
|
||||
s->get_first_frame = 1;
|
||||
unproc_data_size = s->buf_size - i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!s->get_first_frame) {
|
||||
unproc_data_size = 1;
|
||||
s->inbuf[0] = s->inbuf[s->buf_size-1];
|
||||
}
|
||||
os_sleep_ms(1);
|
||||
}
|
||||
|
||||
mp3_dec = audio_coder_open(MP3_DEC, 0, 0);
|
||||
if(mp3_dec == NULL)
|
||||
return;
|
||||
enc_ptr = s->inbuf;
|
||||
while(1) {
|
||||
if(s->next_status == AUCODEC_PAUSE) {
|
||||
if(s->current_status == AUCODEC_RUN) {
|
||||
msi_output_cmd(s->msi,MSI_CMD_AUTPC,MSI_AUTPC_END_STREAM,(uint32_t)(&(s->audio_track)));
|
||||
msi_cmd("R_AUDAC",MSI_CMD_AUDAC,MSI_AUDAC_END_STREAM,(uint32_t)(&(s->audio_track)));
|
||||
}
|
||||
s->current_status = AUCODEC_PAUSE;
|
||||
while(s->next_status == AUCODEC_PAUSE) {
|
||||
os_sleep_ms(1);
|
||||
}
|
||||
}
|
||||
if(s->next_status == AUCODEC_EXIT) {
|
||||
s->current_status = AUCODEC_EXIT;
|
||||
goto mp3_decode_end;
|
||||
}
|
||||
s->current_status = AUCODEC_RUN;
|
||||
if(unproc_data_size < BUFF_SIZE && !endOfRead) {
|
||||
bytes_to_read = BUFF_SIZE - unproc_data_size;
|
||||
if(unproc_data_size)
|
||||
os_memcpy(s->inbuf, enc_ptr+enc_ptr_offset, unproc_data_size);
|
||||
read_len = mp3_file_read(s, s->inbuf+unproc_data_size, bytes_to_read);
|
||||
if(read_len <= 0) {
|
||||
MP3_INFO("mp3 read fail,ret:%d,line:%d!\r\n",read_len,__LINE__);
|
||||
endOfRead = 1;
|
||||
}
|
||||
else
|
||||
unproc_data_size += read_len;
|
||||
enc_ptr = s->inbuf;
|
||||
enc_ptr_offset = 0;
|
||||
}
|
||||
if(unproc_data_size > 0) {
|
||||
while(!frame_buf) {
|
||||
frame_buf = fbpool_get(&s->tx_pool, 0, s->msi);
|
||||
if(!frame_buf)
|
||||
os_sleep_ms(1);
|
||||
}
|
||||
data = (int16_t*)frame_buf->data;
|
||||
dec_samples = audio_decode_data(mp3_dec, enc_ptr+enc_ptr_offset, unproc_data_size, s->dec_buf, &mp3_info);
|
||||
if(dec_samples <= 0) {
|
||||
enc_ptr_offset += 1;
|
||||
unproc_data_size -= 1;
|
||||
msi_delete_fb(s->msi, frame_buf);
|
||||
frame_buf = NULL;
|
||||
continue;
|
||||
}
|
||||
if(mp3_info.channels == 2) {
|
||||
for(uint32_t i=0; i<dec_samples; i++)
|
||||
data[i] = s->dec_buf[2*i];
|
||||
}
|
||||
else {
|
||||
for(uint32_t i=0; i<dec_samples; i++)
|
||||
data[i] = s->dec_buf[i];
|
||||
}
|
||||
enc_ptr_offset += mp3_info.frame_bytes;
|
||||
unproc_data_size -= mp3_info.frame_bytes;
|
||||
frame_buf->len = dec_samples*2;
|
||||
frame_buf->mtype = F_AUDIO;
|
||||
frame_buf->stype = FSTYPE_AUDIO_PCM;
|
||||
s->audio_track.samplerate = mp3_info.samplerate;
|
||||
if(s->use_tpc && !s->autpc_msi) {
|
||||
s->autpc_msi = autpc_msi_init(s->audio_track.samplerate, s->speed, s->pitch, dec_samples, &(s->audio_track));
|
||||
if(s->autpc_msi == NULL) {
|
||||
goto mp3_decode_end;
|
||||
}
|
||||
if(s->direct_to_dac) {
|
||||
msi_add_output(s->autpc_msi, NULL, "R_AUDAC");
|
||||
}
|
||||
msi_add_output(s->msi, NULL, s->autpc_msi->name);
|
||||
}
|
||||
ret = msi_output_fb(s->msi, frame_buf);
|
||||
MP3_DEBUG("mp3 decode send framebuff:%p,ret:%d\r\n",frame_buf,ret);
|
||||
msi_cmd("R_AUDAC", MSI_CMD_AUDAC, MSI_AUDAC_GET_FILTER_TRACK, (uint32_t)(&audac_fiter_track));
|
||||
if(s->direct_to_dac && (!s->use_tpc) && (audac_fiter_track != (&(s->audio_track)))) {
|
||||
interval_time = (frame_buf->len>>1)*1000/(mp3_info.samplerate);
|
||||
os_sleep_ms(interval_time);
|
||||
}
|
||||
frame_buf = NULL;
|
||||
}
|
||||
else if(endOfRead){
|
||||
goto mp3_decode_end;
|
||||
}
|
||||
}
|
||||
mp3_decode_end:
|
||||
msi_output_cmd(s->msi,MSI_CMD_AUTPC,MSI_AUTPC_END_STREAM,(uint32_t)(&(s->audio_track)));
|
||||
msi_cmd("R_AUDAC",MSI_CMD_AUDAC,MSI_AUDAC_END_STREAM,(uint32_t)(&(s->audio_track)));
|
||||
if(frame_buf) {
|
||||
msi_delete_fb(s->msi, frame_buf);
|
||||
frame_buf = NULL;
|
||||
}
|
||||
if(mp3_dec) {
|
||||
audio_coder_close(mp3_dec);
|
||||
}
|
||||
}
|
||||
|
||||
static void update_frame_buf(struct msi *msi, struct framebuff * frame_buf)
|
||||
{
|
||||
msi_delete_fb(NULL, frame_buf);
|
||||
frame_buf = NULL;
|
||||
while(!frame_buf) {
|
||||
frame_buf = msi_get_fb(msi, 0);
|
||||
os_sleep_ms(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void mp3_msi_decode(struct mp3_decode_struct *s)
|
||||
{
|
||||
uint8_t clear_finish = 1;
|
||||
uint8_t find_ID3 = 0;
|
||||
uint8_t endOfRead = 0;
|
||||
uint8_t *recv_data = NULL;
|
||||
int16_t *send_data = NULL;
|
||||
uint8_t *enc_ptr = NULL;
|
||||
int32_t ret = 0;
|
||||
int32_t data_len = 0;
|
||||
int32_t dec_samples = 0;
|
||||
int32_t unproc_data_size = 0;
|
||||
int32_t ID3V2_offset = 0;
|
||||
uint32_t ID3V2_len = 0;
|
||||
uint32_t bytes_to_copy = 0;
|
||||
uint32_t recv_data_offset = 0;
|
||||
uint32_t enc_ptr_offset = 0;
|
||||
uint32_t clear_flag = 0;
|
||||
struct framebuff *recv_frame_buf = NULL;
|
||||
struct framebuff *send_frame_buf = NULL;
|
||||
AUCODE_HDL *mp3_dec = NULL;
|
||||
AUCODE_FRAME_INFO mp3_info;
|
||||
|
||||
mp3_dec = audio_coder_open(MP3_DEC, 0, 0);
|
||||
if(mp3_dec == NULL)
|
||||
return;
|
||||
enc_ptr = s->inbuf;
|
||||
while(1) {
|
||||
get_recv_frame_buf_again:
|
||||
os_event_wait(&s->event, coder_clear_event, &clear_flag, OS_EVENT_WMODE_OR | OS_EVENT_WMODE_CLEAR, 0);
|
||||
if(clear_flag & coder_clear_event) {
|
||||
clear_flag = 0;
|
||||
clear_finish = 0;
|
||||
}
|
||||
recv_frame_buf = msi_get_fb(s->msi, 0);
|
||||
if(recv_frame_buf) {
|
||||
data_len = recv_frame_buf->len;
|
||||
recv_data = recv_frame_buf->data;
|
||||
recv_data_offset = 0;
|
||||
if(data_len <= 0)
|
||||
endOfRead = 1;
|
||||
if(!s->get_first_frame) {
|
||||
if(data_len <= 0)
|
||||
goto mp3_decode_end;
|
||||
if((os_strncmp(recv_data, "ID3", 3) == 0) && !find_ID3) {
|
||||
ID3V2_len = (recv_data[6]&0x7F)*0x200000+ (recv_data[7]&0x7F)*0x4000 +
|
||||
(recv_data[8]&0x7F)*0x80 +(recv_data[9]&0x7F);
|
||||
ID3V2_offset = (ID3V2_len+10);
|
||||
while(ID3V2_offset >= data_len) {
|
||||
ID3V2_offset -= data_len;
|
||||
update_frame_buf(s->msi, recv_frame_buf);
|
||||
data_len = recv_frame_buf->len;
|
||||
if(data_len <= 0)
|
||||
goto mp3_decode_end;
|
||||
}
|
||||
recv_data_offset = ID3V2_offset;
|
||||
data_len -= ID3V2_offset;
|
||||
if(data_len <= 1) {
|
||||
os_memcpy(s->inbuf, recv_data+recv_data_offset, data_len);
|
||||
s->buf_size = data_len;
|
||||
unproc_data_size = data_len;
|
||||
update_frame_buf(s->msi, recv_frame_buf);
|
||||
recv_data_offset = 0;
|
||||
data_len = recv_frame_buf->len;
|
||||
if(data_len <= 0)
|
||||
goto mp3_decode_end;
|
||||
}
|
||||
}
|
||||
find_ID3 = 1;
|
||||
while(data_len) {
|
||||
bytes_to_copy = data_len>(BUFF_SIZE-unproc_data_size)?(BUFF_SIZE-unproc_data_size):data_len;
|
||||
os_memcpy(s->inbuf+unproc_data_size, recv_data+recv_data_offset, bytes_to_copy);
|
||||
s->buf_size += bytes_to_copy;
|
||||
data_len -= bytes_to_copy;
|
||||
recv_data_offset += bytes_to_copy;
|
||||
for(uint32_t i=0; i<(s->buf_size-1); i++) {
|
||||
if( ( (s->inbuf[i] << 8) | (s->inbuf[i+1] & 0xE0) ) == 0xFFE0 ) {
|
||||
s->get_first_frame = 1;
|
||||
unproc_data_size = s->buf_size - i;
|
||||
s->buf_size -= i;
|
||||
enc_ptr_offset += i;
|
||||
goto mp3_get_first_frame;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!s->get_first_frame) {
|
||||
unproc_data_size = 1;
|
||||
s->inbuf[0] = s->inbuf[s->buf_size-1];
|
||||
s->buf_size = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(clear_finish == 0) {
|
||||
clear_finish = 1;
|
||||
os_event_set(&s->event, coder_clear_finish_event, NULL);
|
||||
}
|
||||
os_sleep_ms(1);
|
||||
}
|
||||
mp3_get_first_frame:
|
||||
if(s->next_status == AUCODEC_EXIT) {
|
||||
s->current_status = AUCODEC_EXIT;
|
||||
goto mp3_decode_end;
|
||||
}
|
||||
if(s->next_status == AUCODEC_PAUSE) {
|
||||
if(recv_frame_buf)
|
||||
msi_delete_fb(s->msi, recv_frame_buf);
|
||||
recv_frame_buf = NULL;
|
||||
enc_ptr_offset = 0;
|
||||
unproc_data_size = 0;
|
||||
if(s->current_status == AUCODEC_RUN) {
|
||||
audio_coder_close(mp3_dec);
|
||||
if(send_frame_buf) {
|
||||
msi_delete_fb(s->msi, send_frame_buf);
|
||||
}
|
||||
send_frame_buf = NULL;
|
||||
msi_output_cmd(s->msi,MSI_CMD_AUTPC,MSI_AUTPC_END_STREAM,(uint32_t)(&(s->audio_track)));
|
||||
msi_cmd("R_AUDAC",MSI_CMD_AUDAC,MSI_AUDAC_END_STREAM,(uint32_t)(&(s->audio_track)));
|
||||
mp3_dec = audio_coder_open(MP3_DEC, 0, 0);
|
||||
if(mp3_dec == NULL)
|
||||
return;
|
||||
}
|
||||
s->current_status = AUCODEC_PAUSE;
|
||||
}
|
||||
else
|
||||
s->current_status = AUCODEC_RUN;
|
||||
if(clear_finish == 0) {
|
||||
if(recv_frame_buf)
|
||||
msi_delete_fb(s->msi, recv_frame_buf);
|
||||
recv_frame_buf = NULL;
|
||||
enc_ptr_offset = 0;
|
||||
unproc_data_size = 0;
|
||||
continue;
|
||||
}
|
||||
while((data_len>0) || (unproc_data_size>0)) {
|
||||
if((data_len) >= (BUFF_SIZE-unproc_data_size)) {
|
||||
os_memcpy(enc_ptr, enc_ptr+enc_ptr_offset, unproc_data_size);
|
||||
bytes_to_copy = BUFF_SIZE - unproc_data_size;
|
||||
os_memcpy(enc_ptr+unproc_data_size, recv_data+recv_data_offset, bytes_to_copy);
|
||||
data_len -= bytes_to_copy;
|
||||
recv_data_offset += bytes_to_copy;
|
||||
enc_ptr_offset = 0;
|
||||
unproc_data_size += bytes_to_copy;
|
||||
}
|
||||
else if(!endOfRead) {
|
||||
bytes_to_copy = data_len;
|
||||
if(bytes_to_copy) {
|
||||
os_memcpy(enc_ptr, enc_ptr+enc_ptr_offset, unproc_data_size);
|
||||
os_memcpy(enc_ptr+unproc_data_size, recv_data+recv_data_offset, bytes_to_copy);
|
||||
data_len -= bytes_to_copy;
|
||||
recv_data_offset += bytes_to_copy;
|
||||
enc_ptr_offset = 0;
|
||||
unproc_data_size += bytes_to_copy;
|
||||
}
|
||||
msi_delete_fb(NULL, recv_frame_buf);
|
||||
recv_frame_buf = NULL;
|
||||
goto get_recv_frame_buf_again;
|
||||
}
|
||||
while(!send_frame_buf) {
|
||||
send_frame_buf = fbpool_get(&s->tx_pool, 0, s->msi);
|
||||
if(!send_frame_buf)
|
||||
os_sleep_ms(1);
|
||||
}
|
||||
send_data = (int16_t*)send_frame_buf->data;
|
||||
dec_samples = audio_decode_data(mp3_dec, enc_ptr+enc_ptr_offset, unproc_data_size, s->dec_buf, &mp3_info);
|
||||
if(dec_samples <= 0) {
|
||||
enc_ptr_offset += 1;
|
||||
unproc_data_size -= 1;
|
||||
msi_delete_fb(s->msi, send_frame_buf);
|
||||
send_frame_buf = NULL;
|
||||
continue;
|
||||
}
|
||||
if(mp3_info.channels == 2) {
|
||||
for(uint32_t i=0; i<dec_samples; i++)
|
||||
send_data[i] = s->dec_buf[2*i];
|
||||
}
|
||||
else {
|
||||
for(uint32_t i=0; i<dec_samples; i++)
|
||||
send_data[i] = s->dec_buf[i];
|
||||
}
|
||||
enc_ptr_offset += mp3_info.frame_bytes;
|
||||
unproc_data_size -= mp3_info.frame_bytes;
|
||||
send_frame_buf->len = dec_samples*2;
|
||||
send_frame_buf->mtype = F_AUDIO;
|
||||
send_frame_buf->stype = FSTYPE_AUDIO_PCM;
|
||||
s->audio_track.samplerate = mp3_info.samplerate;
|
||||
if(s->use_tpc && !s->autpc_msi) {
|
||||
s->autpc_msi = autpc_msi_init(s->audio_track.samplerate, s->speed, s->pitch, dec_samples, &(s->audio_track));
|
||||
if(s->autpc_msi == NULL) {
|
||||
goto mp3_decode_end;
|
||||
}
|
||||
if(s->direct_to_dac) {
|
||||
msi_add_output(s->autpc_msi, NULL, "R_AUDAC");
|
||||
}
|
||||
msi_add_output(s->msi, NULL, s->autpc_msi->name);
|
||||
}
|
||||
ret = msi_output_fb(s->msi, send_frame_buf);
|
||||
MP3_DEBUG("mp3 decode send framebuff:%p,ret:%d\r\n",send_frame_buf,ret);
|
||||
send_frame_buf = NULL;
|
||||
}
|
||||
if(endOfRead)
|
||||
goto mp3_decode_end;
|
||||
}
|
||||
mp3_decode_end:
|
||||
msi_output_cmd(s->msi,MSI_CMD_AUTPC,MSI_AUTPC_END_STREAM,(uint32_t)(&(s->audio_track)));
|
||||
msi_cmd("R_AUDAC",MSI_CMD_AUDAC,MSI_AUDAC_END_STREAM,(uint32_t)(&(s->audio_track)));
|
||||
if(recv_frame_buf) {
|
||||
msi_delete_fb(NULL, recv_frame_buf);
|
||||
recv_frame_buf = NULL;
|
||||
}
|
||||
if(send_frame_buf) {
|
||||
msi_delete_fb(s->msi, send_frame_buf);
|
||||
send_frame_buf = NULL;
|
||||
}
|
||||
if(mp3_dec) {
|
||||
audio_coder_close(mp3_dec);
|
||||
}
|
||||
}
|
||||
|
||||
static void mp3_decode_thread(void *d)
|
||||
{
|
||||
struct mp3_decode_struct *s = (struct mp3_decode_struct *)d;
|
||||
|
||||
if(s->mp3_fp) {
|
||||
curmp3_info_init(&s->cur_mp3_info, s->mp3_filename);
|
||||
s->file_size = osal_fsize(s->mp3_fp);
|
||||
get_curmp3_size(s->cur_mp3_info, s->file_size);
|
||||
find_first_frame(s->cur_mp3_info, s->mp3_fp);
|
||||
if(s->cur_mp3_info->normal_frame_offset)
|
||||
s->get_first_frame = 1;
|
||||
}
|
||||
|
||||
msi_get(s->msi);
|
||||
|
||||
if(s->direct_to_dac) {
|
||||
msi_cmd("R_AUDAC",MSI_CMD_AUDAC,MSI_AUDAC_SET_FILTER_TRACK,(uint32_t)(&(s->audio_track)));
|
||||
}
|
||||
|
||||
s->msi->enable = 1;
|
||||
if(s->mp3_fp) {
|
||||
do {
|
||||
if(s->cur_mp3_info)
|
||||
osal_fseek(s->mp3_fp, s->cur_mp3_info->first_frame_offset);
|
||||
else
|
||||
osal_fseek(s->mp3_fp, 0);
|
||||
mp3_file_decode(s);
|
||||
if(s->current_status == AUCODEC_EXIT) {
|
||||
break;
|
||||
}
|
||||
}while(s->loop_mode);
|
||||
}
|
||||
else
|
||||
mp3_msi_decode(s);
|
||||
|
||||
if(s->direct_to_dac) {
|
||||
s->audio_track.priority = play_disabled;
|
||||
msi_cmd("R_AUDAC",MSI_CMD_AUDAC,MSI_AUDAC_SET_FILTER_TRACK,(uint32_t)(&(s->audio_track)));
|
||||
}
|
||||
|
||||
os_event_set(&s->event, coder_exit_event, NULL);
|
||||
|
||||
while((s->next_status != AUCODEC_EXIT) && (s->destroy_self == 0)) {
|
||||
s->current_status = AUCODEC_END;
|
||||
os_sleep_ms(5);
|
||||
}
|
||||
if(s->cur_mp3_info)
|
||||
clear_curmp3_info(s->cur_mp3_info);
|
||||
|
||||
if(s->src_msi) {
|
||||
msi_del_output(s->src_msi, NULL, s->msi->name);
|
||||
s->src_msi = NULL;
|
||||
}
|
||||
|
||||
if(s->next_status != AUCODEC_EXIT)
|
||||
msi_destroy(s->msi);
|
||||
|
||||
msi_put(s->msi);
|
||||
}
|
||||
|
||||
static int32_t mp3_decode_msi_action(struct msi *msi, uint32_t cmd_id, uint32_t param1, uint32_t param2)
|
||||
{
|
||||
int32_t ret = RET_OK;
|
||||
struct mp3_decode_struct *mp3_decode_s = (struct mp3_decode_struct*)(msi->priv);
|
||||
switch(cmd_id) {
|
||||
case MSI_CMD_AUCODER:
|
||||
{
|
||||
ret = RET_ERR;
|
||||
if(mp3_decode_s) {
|
||||
uint32_t cmd_self = (uint32_t)param1;
|
||||
switch(cmd_self) {
|
||||
case MSI_AUCODER_PAUSE:
|
||||
{
|
||||
if(mp3_decode_s->current_status == AUCODEC_RUN) {
|
||||
mp3_decode_s->next_status = AUCODEC_PAUSE;
|
||||
}
|
||||
ret = RET_OK;
|
||||
break;
|
||||
}
|
||||
case MSI_AUCODER_CONTINUE:
|
||||
{
|
||||
if(mp3_decode_s->current_status == AUCODEC_PAUSE) {
|
||||
mp3_decode_s->next_status = AUCODEC_RUN;
|
||||
}
|
||||
ret = RET_OK;
|
||||
break;
|
||||
}
|
||||
case MSI_AUCODER_GET_STATUS:
|
||||
{
|
||||
*((uint32_t*)param2) = (uint32_t)(mp3_decode_s->current_status);
|
||||
ret = RET_OK;
|
||||
break;
|
||||
}
|
||||
case MSI_AUCODER_SET_SPEED:
|
||||
{
|
||||
mp3_decode_s->speed = (uint8_t)param2;
|
||||
ret = msi_output_cmd(mp3_decode_s->msi,MSI_CMD_AUTPC,MSI_AUTPC_SET_SPEED,(uint32_t)(mp3_decode_s->speed));
|
||||
break;
|
||||
}
|
||||
case MSI_AUCODER_GET_SPEED:
|
||||
{
|
||||
*((uint32_t*)param2) = (uint32_t)(mp3_decode_s->speed);
|
||||
ret = RET_OK;
|
||||
break;
|
||||
}
|
||||
case MSI_AUCODER_SET_PITCH:
|
||||
{
|
||||
mp3_decode_s->pitch = (uint8_t)param2;
|
||||
ret = msi_output_cmd(mp3_decode_s->msi,MSI_CMD_AUTPC,MSI_AUTPC_SET_PITCH,(uint32_t)(mp3_decode_s->pitch));
|
||||
break;
|
||||
}
|
||||
case MSI_AUCODER_GET_PITCH:
|
||||
{
|
||||
*((uint32_t*)param2) = (uint32_t)(mp3_decode_s->pitch);
|
||||
ret = RET_OK;
|
||||
break;
|
||||
}
|
||||
case MSI_AUCODER_CLEAR_STREAM:
|
||||
{
|
||||
os_event_set(&mp3_decode_s->event, coder_clear_event, NULL);
|
||||
os_event_wait(&mp3_decode_s->event, coder_clear_finish_event, NULL, OS_EVENT_WMODE_OR | OS_EVENT_WMODE_CLEAR, osWaitForever);
|
||||
msi_output_cmd(mp3_decode_s->msi,MSI_CMD_AUTPC,MSI_AUTPC_END_STREAM,(uint32_t)(&(mp3_decode_s->audio_track)));
|
||||
msi_cmd("R_AUDAC",MSI_CMD_AUDAC,MSI_AUDAC_CLEAR_STREAM,(uint32_t)(&(mp3_decode_s->audio_track)));
|
||||
ret = RET_OK;
|
||||
break;
|
||||
}
|
||||
case MSI_AUCODER_SET_SRCMSI:
|
||||
{
|
||||
if(mp3_decode_s->src_msi) {
|
||||
msi_del_output(mp3_decode_s->src_msi, NULL, msi->name);
|
||||
}
|
||||
mp3_decode_s->src_msi = NULL;
|
||||
ret = msi_add_output((struct msi*)param2, NULL, msi->name);
|
||||
if(ret == RET_OK) {
|
||||
mp3_decode_s->src_msi = (struct msi*)param2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSI_AUCODER_DIRECT_TO_DAC:
|
||||
{
|
||||
uint32_t direct_to_dac = param2;
|
||||
if(direct_to_dac && mp3_decode_s->direct_to_dac == 0) {
|
||||
mp3_decode_s->direct_to_dac = 1;
|
||||
if(mp3_decode_s->use_tpc == 0) {
|
||||
msi_add_output(msi, NULL, "R_AUDAC");
|
||||
}
|
||||
else if(mp3_decode_s->autpc_msi) {
|
||||
msi_add_output(mp3_decode_s->autpc_msi, NULL, "R_AUDAC");
|
||||
}
|
||||
msi_cmd("R_AUDAC",MSI_CMD_AUDAC,MSI_AUDAC_SET_FILTER_TRACK,(uint32_t)(&(mp3_decode_s->audio_track)));
|
||||
}
|
||||
else if(mp3_decode_s->direct_to_dac == 1) {
|
||||
mp3_decode_s->direct_to_dac = 0;
|
||||
if(mp3_decode_s->use_tpc == 0) {
|
||||
msi_del_output(msi, NULL, "R_AUDAC");
|
||||
}
|
||||
else if(mp3_decode_s->autpc_msi) {
|
||||
msi_del_output(mp3_decode_s->autpc_msi, NULL, "R_AUDAC");
|
||||
}
|
||||
mp3_decode_s->audio_track.priority &= 0x3F;
|
||||
msi_cmd("R_AUDAC",MSI_CMD_AUDAC,MSI_AUDAC_SET_FILTER_TRACK,(uint32_t)(&(mp3_decode_s->audio_track)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSI_AUCODER_DEINIT:
|
||||
{
|
||||
msi_destroy(msi);
|
||||
ret = RET_OK;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSI_CMD_TRANS_FB:
|
||||
{
|
||||
ret = RET_ERR;
|
||||
struct framebuff *frame_buf = (struct framebuff *)param1;
|
||||
if(frame_buf->mtype == F_AUDIO) {
|
||||
ret = RET_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSI_CMD_FREE_FB:
|
||||
{
|
||||
ret = RET_ERR;
|
||||
if(mp3_decode_s) {
|
||||
struct framebuff *frame_buf = (struct framebuff *)param1;
|
||||
fbpool_put(&mp3_decode_s->tx_pool, frame_buf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSI_CMD_PRE_DESTROY:
|
||||
{
|
||||
if(mp3_decode_s && mp3_decode_s->task_hdl) {
|
||||
mp3_decode_s->next_status = AUCODEC_EXIT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSI_CMD_POST_DESTROY:
|
||||
{
|
||||
if(mp3_decode_s) {
|
||||
if(mp3_decode_s->task_hdl) {
|
||||
os_event_wait(&mp3_decode_s->event, coder_exit_event, NULL, OS_EVENT_WMODE_OR | OS_EVENT_WMODE_CLEAR, osWaitForever);
|
||||
}
|
||||
for(uint32_t i=0; i<MAX_MP3_DECODE_TXBUF; i++) {
|
||||
struct framebuff *frame_buf = (mp3_decode_s->tx_pool.pool)+i;
|
||||
if(frame_buf->data) {
|
||||
MP3_DECODE_FREE(frame_buf->data);
|
||||
frame_buf->data = NULL;
|
||||
}
|
||||
}
|
||||
fbpool_destroy(&mp3_decode_s->tx_pool);
|
||||
if(mp3_decode_s->event.hdl) {
|
||||
os_event_del(&mp3_decode_s->event);
|
||||
}
|
||||
if(mp3_decode_s->mp3_fp) {
|
||||
osal_fclose(mp3_decode_s->mp3_fp);
|
||||
mp3_decode_s->mp3_fp = NULL;
|
||||
}
|
||||
if(mp3_decode_s->autpc_msi) {
|
||||
autpc_msi_deinit(mp3_decode_s->autpc_msi);
|
||||
mp3_decode_s->autpc_msi = NULL;
|
||||
}
|
||||
if(mp3_decode_s->msi_name) {
|
||||
MP3_DECODE_FREE(mp3_decode_s->msi_name);
|
||||
mp3_decode_s->msi_name = NULL;
|
||||
}
|
||||
MP3_DECODE_FREE(mp3_decode_s);
|
||||
mp3_decode_s = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct msi *mp3_decode_init(char *filename, uint8_t loop_mode, AUDEC_INIT *audec_init)
|
||||
{
|
||||
#if AUDIO_EN
|
||||
char *msi_name = NULL;
|
||||
|
||||
msi_name = (char*)MP3_DECODE_ZALLOC(sizeof(char)*32);
|
||||
if(msi_name == NULL) {
|
||||
os_printf("alloc autpc msi namefail\n");
|
||||
return NULL;
|
||||
}
|
||||
os_snprintf(msi_name, 20, "SR_MP3_DECODE_""%04d", (int)(os_jiffies()));
|
||||
struct msi *msi = msi_new(msi_name, MAX_MP3_DECODE_RXBUF, NULL);
|
||||
os_printf("mp3 msi name:%s\n",msi_name);
|
||||
if(msi == NULL) {
|
||||
MP3_INFO("create mp3 decode msi fail!\r\n");
|
||||
return NULL;
|
||||
}
|
||||
struct mp3_decode_struct *mp3_decode_s = (struct mp3_decode_struct*)MP3_DECODE_ZALLOC(sizeof(struct mp3_decode_struct));
|
||||
if(!mp3_decode_s) {
|
||||
MP3_INFO("mp3_decode_s malloc fail!\r\n");
|
||||
goto mp3_decode_init_err;
|
||||
}
|
||||
msi->priv = mp3_decode_s;
|
||||
msi->action = (msi_action)mp3_decode_msi_action;
|
||||
fbpool_init(&mp3_decode_s->tx_pool, MAX_MP3_DECODE_TXBUF);
|
||||
for(uint32_t i=0; i<MAX_MP3_DECODE_TXBUF; i++) {
|
||||
struct framebuff *frame_buf = (mp3_decode_s->tx_pool.pool)+i;
|
||||
frame_buf->data = (uint8_t*)MP3_DECODE_MALLOC(1152 * sizeof(int16_t));
|
||||
if(frame_buf->data == NULL)
|
||||
{
|
||||
MP3_INFO("mp3 decode malloc framebuff data fail!\r\n");
|
||||
goto mp3_decode_init_err;
|
||||
}
|
||||
frame_buf->priv = &(mp3_decode_s->audio_track);
|
||||
}
|
||||
if(os_event_init(&mp3_decode_s->event) != RET_OK) {
|
||||
MP3_INFO("create mp3 decode event fail!\r\n");
|
||||
goto mp3_decode_init_err;
|
||||
}
|
||||
if(filename) {
|
||||
os_memcpy(mp3_decode_s->mp3_filename, filename, 20);
|
||||
mp3_decode_s->mp3_fp = osal_fopen((const char*)mp3_decode_s->mp3_filename, "rb");
|
||||
if(mp3_decode_s->mp3_fp == NULL) {
|
||||
MP3_INFO("open mp3 file %s fail!\r\n", mp3_decode_s->mp3_filename);
|
||||
goto mp3_decode_init_err;
|
||||
}
|
||||
}
|
||||
if(audec_init->src_msi && (msi_add_output(audec_init->src_msi, NULL, msi->name) != RET_OK)) {
|
||||
goto mp3_decode_init_err;
|
||||
}
|
||||
mp3_decode_s->msi = msi;
|
||||
mp3_decode_s->msi_name = msi_name;
|
||||
mp3_decode_s->src_msi = audec_init->src_msi;
|
||||
mp3_decode_s->loop_mode = loop_mode;
|
||||
mp3_decode_s->direct_to_dac = audec_init->direct_to_dac;
|
||||
mp3_decode_s->use_tpc = audec_init->use_tpc;
|
||||
mp3_decode_s->speed = audec_init->speed;
|
||||
mp3_decode_s->pitch = audec_init->pitch;
|
||||
mp3_decode_s->destroy_self = audec_init->destroy_self;
|
||||
mp3_decode_s->audio_track.priority = audec_init->priority;
|
||||
mp3_decode_s->audio_track.track_type = audec_init->track_type;
|
||||
mp3_decode_s->next_status = AUCODEC_RUN;
|
||||
mp3_decode_s->current_status = AUCODEC_RUN;
|
||||
if(audec_init->direct_to_dac && !mp3_decode_s->use_tpc) {
|
||||
msi_add_output(msi, NULL, "R_AUDAC");
|
||||
}
|
||||
mp3_decode_s->task_hdl = os_task_create("mp3_decode_thread", mp3_decode_thread, (void*)mp3_decode_s, OS_TASK_PRIORITY_BELOW_NORMAL, 0, NULL, 3072);
|
||||
if(mp3_decode_s->task_hdl == NULL) {
|
||||
MP3_INFO("create mp3 decode task fail!\r\n");
|
||||
goto mp3_decode_init_err;
|
||||
}
|
||||
return msi;
|
||||
|
||||
mp3_decode_init_err:
|
||||
msi_destroy(msi);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
26
sdk/app/audio_media_ctrl/mp3/mp3_decode.h
Normal file
26
sdk/app/audio_media_ctrl/mp3/mp3_decode.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef _MP3_DECODE_MSI_H_
|
||||
#define _MP3_DECODE_MSI_H_
|
||||
|
||||
#include "basic_include.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
#include "audio_code_ctrl.h"
|
||||
|
||||
#ifdef PSRAM_HEAP
|
||||
#define MP3_DECODE_MALLOC av_psram_malloc
|
||||
#define MP3_DECODE_ZALLOC av_psram_zalloc
|
||||
#define MP3_DECODE_CALLOC av_psram_calloc
|
||||
#define MP3_DECODE_FREE av_psram_free
|
||||
#else
|
||||
#define MP3_DECODE_MALLOC av_malloc
|
||||
#define MP3_DECODE_ZALLOC av_zalloc
|
||||
#define MP3_DECODE_CALLOC av_calloc
|
||||
#define MP3_DECODE_FREE av_free
|
||||
#endif
|
||||
|
||||
#define MP3_DEBUG(fmt, args...) //os_printf(fmt, ##args)
|
||||
#define MP3_INFO os_printf
|
||||
|
||||
struct msi *mp3_decode_init(char *filename, uint8_t loop_mode, AUDEC_INIT *audec_init);
|
||||
|
||||
#endif
|
||||
472
sdk/app/audio_media_ctrl/mp3/mp3_getInfo.c
Normal file
472
sdk/app/audio_media_ctrl/mp3/mp3_getInfo.c
Normal file
@@ -0,0 +1,472 @@
|
||||
#include "basic_include.h"
|
||||
//#include "keyWork.h"
|
||||
//#include "keyScan.h"
|
||||
#include "osal_file.h"
|
||||
#include "mp3_getInfo.h"
|
||||
#include "mp3_decode.h"
|
||||
#include "audio_code_ctrl.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
|
||||
#define MP3_SAVE_INFO 0
|
||||
|
||||
#if MP3_SAVE_INFO
|
||||
#define MAX_FORWARD_TIME 10
|
||||
struct key_callback_list_s *key_seek_list = NULL;
|
||||
#endif
|
||||
|
||||
const uint32_t bitrate_table[5][15] = {
|
||||
/* MPEG-1 */
|
||||
{ 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, /* Layer I */
|
||||
256000, 288000, 320000, 352000, 384000, 416000, 448000 },
|
||||
{ 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer II */
|
||||
128000, 160000, 192000, 224000, 256000, 320000, 384000 },
|
||||
{ 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, /* Layer III */
|
||||
112000, 128000, 160000, 192000, 224000, 256000, 320000 },
|
||||
/* MPEG-2 ,MPEG-2.5 */
|
||||
{ 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer I */
|
||||
128000, 144000, 160000, 176000, 192000, 224000, 256000 },
|
||||
{ 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, /* Layer */
|
||||
64000, 80000, 96000, 112000, 128000, 144000, 160000 } /* II & III */
|
||||
};
|
||||
const uint32_t samplingrate_table[4][3] = { //value s are in Hz
|
||||
{11025 , 12000 , 8000}, //MPEG Version 2.5
|
||||
{0,0,0}, //reserved
|
||||
{22050, 24000, 16000}, //MPEG Version 2 (ISO/IEC 13818-3)
|
||||
{44100, 48000, 32000} //MPEG Version 1 (ISO/IEC 11172-3)
|
||||
};
|
||||
const uint8_t layerIII_inbytes[4][4] = {
|
||||
{17,17,17,9}, /*MPEG Version 2.5*/
|
||||
{0, 0, 0, 0}, /*reserved*/
|
||||
{17,17,17,9}, /*MPEG Version 2*/
|
||||
{32,32,32,17} /*MPEG Version 1*/
|
||||
};
|
||||
const uint16_t samples_table[4][4] = {
|
||||
{0,576,1152,384}, /*MPEG Version 2.5 {reserve,layerIII,layerII,layerI}*/
|
||||
{0,0,0,0}, /*reserved {reserve,layerIII,layerII,layerI}*/
|
||||
{0,576,1152,384}, /*MPEG Version 2 {reserve,layerIII,layerII,layerI}*/
|
||||
{0,1152,1152,384} /*MPEG Version 1 {reserve,layerIII,layerII,layerI}*/
|
||||
};
|
||||
|
||||
uint32_t get_curmp3_size(CUR_MP3_INFO *cur_mp3_info, uint32_t s)
|
||||
{
|
||||
if(!cur_mp3_info)
|
||||
return 0;
|
||||
cur_mp3_info->total_size =s;
|
||||
return cur_mp3_info->total_size;
|
||||
}
|
||||
|
||||
void curmp3_info_init(CUR_MP3_INFO **cur_mp3_info, uint8_t *mp3_filename)
|
||||
{
|
||||
#if MP3_SAVE_INFO
|
||||
char dirname_len = strlen("0:mp3/");
|
||||
char extension_len = strlen("mp3");
|
||||
char filename_temp[50] = {0};
|
||||
#endif
|
||||
if(!(*cur_mp3_info))
|
||||
(*cur_mp3_info) = (CUR_MP3_INFO*)MP3_DECODE_ZALLOC(sizeof(CUR_MP3_INFO));
|
||||
else
|
||||
os_memset((*cur_mp3_info), 0, sizeof(CUR_MP3_INFO));
|
||||
#if MP3_SAVE_INFO
|
||||
os_memcpy(filename_temp, mp3_filename+dirname_len, strlen(mp3_filename)-dirname_len-extension_len);
|
||||
filename_temp[strlen(mp3_filename)-dirname_len-extension_len] = '\0';
|
||||
os_sprintf((*cur_mp3_info)->mp3_st_filename, "0:MP3_SEEK/%s%s", filename_temp, "st");
|
||||
os_printf("mp3_st_filename:%s\n",(*cur_mp3_info)->mp3_st_filename);
|
||||
#endif
|
||||
}
|
||||
|
||||
// void get_curmp3_totaltime_ergodic(void *fp, uint32_t first_frame_offset)
|
||||
// {
|
||||
|
||||
// uint8_t bitrate_index = 0;
|
||||
// uint8_t padding = 0;
|
||||
// uint8_t frame_head[4];
|
||||
// int32_t read_len = 0;
|
||||
// uint32_t bitrate = 0;
|
||||
// uint32_t frame_len = 0;
|
||||
// uint32_t offset = 0;
|
||||
// uint32_t current_seek = 0;
|
||||
// uint32_t read_frame_cnt = 0;
|
||||
// uint32_t read_second_cnt = 0;
|
||||
|
||||
// if(!cur_mp3_info)
|
||||
// return;
|
||||
|
||||
// current_seek = osal_ftell(fp);
|
||||
// osal_fseek(fp, first_frame_offset);
|
||||
// osal_fread(frame_head, 1, 4, fp);
|
||||
// offset = first_frame_offset;
|
||||
|
||||
// bitrate_index = (frame_head[2]>>4)&0xf;
|
||||
// bitrate = bitrate_table[cur_mp3_info->bitrate_table_index][bitrate_index];
|
||||
// padding = ((frame_head[2]>>1)&0x1) * cur_mp3_info->padding_mul;
|
||||
// frame_len = cur_mp3_info->samples/8*bitrate/cur_mp3_info->samplingrate + padding;
|
||||
|
||||
// offset = first_frame_offset+4;
|
||||
// // printf("samples:%d samplingrate:%d bitrate:%d\n",cur_mp3_info->samples,cur_mp3_info->samplingrate,bitrate);
|
||||
// INIT_LIST_HEAD((struct list_head *)&cur_mp3_info->seek_table_head);
|
||||
// MP3_SEEK_TABLE *sub_seek_table = MP3_DECODE_ZALLOC(sizeof(MP3_SEEK_TABLE));
|
||||
// list_add_tail((struct list_head *)&sub_seek_table->sub_table_list,(struct list_head *)&cur_mp3_info->seek_table_head);
|
||||
// sub_seek_table->sub_table[0] = first_frame_offset;
|
||||
// while(1) {
|
||||
// osal_fseek(fp, offset+frame_len-4);
|
||||
// offset += frame_len;
|
||||
// read_len = osal_fread(frame_head, 1, 4, fp);
|
||||
// if(((cur_mp3_info->total_size-offset)==124) && (strncmp((const char*)frame_head, "TAG", 3)==0)) { //ID3V1
|
||||
// break;
|
||||
// }
|
||||
// if(((frame_head[0]<<8) | (frame_head[1]&0xE0)) != 0xFFE0) {
|
||||
// break;
|
||||
// }
|
||||
// if((offset+frame_len-4) >= cur_mp3_info->total_size ) { //end
|
||||
// break;
|
||||
// }
|
||||
// cur_mp3_info->total_frame++;
|
||||
// bitrate_index = (frame_head[2]>>4)&0xf;
|
||||
// bitrate = bitrate_table[cur_mp3_info->bitrate_table_index][bitrate_index];
|
||||
// padding = ((frame_head[2]>>1)&0x1) * cur_mp3_info->padding_mul;
|
||||
// frame_len = cur_mp3_info->samples/8*bitrate/cur_mp3_info->samplingrate + padding;
|
||||
// read_frame_cnt++;
|
||||
// if(read_frame_cnt >= (cur_mp3_info->one_second_frame)) {
|
||||
// read_second_cnt++;
|
||||
// if(read_second_cnt >= 100) {
|
||||
// sub_seek_table = (MP3_SEEK_TABLE*)MP3_DECODE_ZALLOC(sizeof(MP3_SEEK_TABLE));
|
||||
// list_add_tail((struct list_head *)&sub_seek_table->sub_table_list,(struct list_head *)&cur_mp3_info->seek_table_head);
|
||||
// read_second_cnt -= 100;
|
||||
// }
|
||||
// sub_seek_table->sub_table[read_second_cnt] = offset-4;
|
||||
// read_frame_cnt -= (cur_mp3_info->one_second_frame);
|
||||
// }
|
||||
// }
|
||||
// cur_mp3_info->totaltime = cur_mp3_info->total_frame * cur_mp3_info->samples / cur_mp3_info->samplingrate;
|
||||
// cur_mp3_info->once_move_time = (cur_mp3_info->totaltime%100)?(cur_mp3_info->totaltime/100+1):(cur_mp3_info->totaltime/100);
|
||||
// MP3_INFO("total_frame:%d total_time:%d once_move_time:%d\n",cur_mp3_info->total_frame, cur_mp3_info->totaltime,cur_mp3_info->once_move_time);
|
||||
// cur_mp3_info->get_totaltime = 1;
|
||||
// osal_fseek(fp, current_seek);
|
||||
// }
|
||||
|
||||
// uint32_t get_mp3_seek(void)
|
||||
// {
|
||||
// if(!cur_mp3_info)
|
||||
// return 0;
|
||||
|
||||
// return cur_mp3_info->offset_seek;
|
||||
// }
|
||||
|
||||
// uint32_t get_curmp3_playtime(void)
|
||||
// {
|
||||
// if(!cur_mp3_info)
|
||||
// return 0;
|
||||
|
||||
// cur_mp3_info->playtime = cur_mp3_info->play_frame * cur_mp3_info->samples / cur_mp3_info->samplingrate;
|
||||
// // printf("record:%d %d\n",cur_mp3_info->playtime,cur_mp3_info->play_frame);
|
||||
// return cur_mp3_info->playtime;
|
||||
// }
|
||||
// uint32_t get_curmp3_playframe(void)
|
||||
// {
|
||||
// if(!cur_mp3_info)
|
||||
// return 0;
|
||||
|
||||
// cur_mp3_info->play_frame++;
|
||||
// return cur_mp3_info->play_frame;
|
||||
// }
|
||||
// void update_curmp3_playtime(uint32_t update_time)
|
||||
// {
|
||||
// if(!cur_mp3_info)
|
||||
// return;
|
||||
|
||||
// cur_mp3_info->playtime = update_time;
|
||||
// }
|
||||
// void update_curmp3_playframe(uint32_t update_frame)
|
||||
// {
|
||||
// if(!cur_mp3_info)
|
||||
// return;
|
||||
|
||||
// cur_mp3_info->play_frame = update_frame;
|
||||
// }
|
||||
|
||||
// void set_mp3_seek(int16_t move_time)
|
||||
// {
|
||||
// uint8_t table_pos = 0;
|
||||
// uint32_t offset_seek = 0;
|
||||
// uint32_t target_time = 0;
|
||||
// uint32_t target_frame = 0;
|
||||
// uint32_t table_index = 0;
|
||||
// struct list_head *seek_table_list = NULL;
|
||||
// MP3_SEEK_TABLE *seek_table = NULL;
|
||||
|
||||
// target_time = ((cur_mp3_info->playtime + move_time)<0)?0:(cur_mp3_info->playtime + move_time);
|
||||
// target_time = (target_time>cur_mp3_info->totaltime)?cur_mp3_info->totaltime:target_time;
|
||||
// target_frame = cur_mp3_info->one_second_frame*target_time;
|
||||
// table_index = target_time/100;
|
||||
// table_pos = target_time%100;
|
||||
// seek_table_list = cur_mp3_info->seek_table_head.next;
|
||||
// while(table_index>0) {
|
||||
// seek_table_list = seek_table_list->next;
|
||||
// table_index--;
|
||||
// }
|
||||
// seek_table = list_entry((struct list_head *)seek_table_list,MP3_SEEK_TABLE,sub_table_list);
|
||||
// offset_seek = seek_table->sub_table[table_pos];
|
||||
// osal_fseek(cur_mp3_info->mp3_fp,offset_seek);
|
||||
// update_curmp3_playtime(target_time);
|
||||
// update_curmp3_playframe(target_frame);
|
||||
// cur_mp3_info->offset_seek = offset_seek;
|
||||
// MP3_INFO("**file pos:%x time:%d frame:%d**\n",offset_seek,cur_mp3_info->playtime,cur_mp3_info->play_frame);
|
||||
// }
|
||||
// //
|
||||
// //uint32_t key_seek_callback(struct key_callback_list_s *callback_list,uint32_t keyvalue,uint32_t extern_value)
|
||||
// //{
|
||||
// // uint32 key_val = 0;
|
||||
// //
|
||||
// // if(!cur_mp3_info)
|
||||
// // return 0;
|
||||
// //
|
||||
// // if(((keyvalue>>8) != AD_A) && ((keyvalue>>8) != AD_B))
|
||||
// // return 0;
|
||||
// // if(get_mp3_decode_status() == MP3_STOP) {
|
||||
// // _os_printf("mp3 stop\n");
|
||||
// // return 0;
|
||||
// // }
|
||||
// // key_val = (keyvalue & 0xff);
|
||||
// // if((keyvalue>>8) == AD_A) {
|
||||
// // if(key_val == KEY_EVENT_DOWN) {
|
||||
// // os_sema_down(&seek_sema,5000);
|
||||
// // set_mp3_seek(-cur_mp3_info->once_move_time);
|
||||
// // }
|
||||
// // else if((key_val == KEY_EVENT_LDOWN) || (key_val == KEY_EVENT_REPEAT)) {
|
||||
// // set_mp3_seek(-cur_mp3_info->once_move_time);
|
||||
// // }
|
||||
// // else if((key_val == KEY_EVENT_SUP) || (key_val == KEY_EVENT_LUP)) {
|
||||
// // cur_mp3_info->update_fops = 1;
|
||||
// // os_sema_up(&seek_sema);
|
||||
// // }
|
||||
// // }
|
||||
// // else if((keyvalue>>8) == AD_B) {
|
||||
// // if(key_val == KEY_EVENT_DOWN) {
|
||||
// // os_sema_down(&seek_sema,5000);
|
||||
// // set_mp3_seek(cur_mp3_info->once_move_time);
|
||||
// // }
|
||||
// // else if((key_val == KEY_EVENT_LDOWN) || (key_val == KEY_EVENT_REPEAT)) {
|
||||
// // set_mp3_seek(cur_mp3_info->once_move_time);
|
||||
// // }
|
||||
// // else if((key_val == KEY_EVENT_SUP) || (key_val == KEY_EVENT_LUP)) {
|
||||
// // cur_mp3_info->update_fops = 1;
|
||||
// // os_sema_up(&seek_sema);
|
||||
// // }
|
||||
// // }
|
||||
// // return 1;
|
||||
// //}
|
||||
|
||||
// int32_t at_set_mp3_seek(const char *cmd, char *argv[], uint32_t argc)
|
||||
// {
|
||||
// int32_t seek_time = 0;
|
||||
// uint32_t forward_time = 0;
|
||||
|
||||
// if(!cur_mp3_info)
|
||||
// return 0;
|
||||
// // if(get_mp3_decode_status() == AUCODEC_EXIT) {
|
||||
// // MP3_INFO("mp3 stop\n");
|
||||
// // return 0;
|
||||
// // }
|
||||
// if(argc < 1) {
|
||||
// MP3_INFO("%s %d,enter the seek\n",__FUNCTION__,argc);
|
||||
// return 0;
|
||||
// }
|
||||
// if(argv[0]) {
|
||||
// seek_time = os_atoi(argv[0]);
|
||||
// if(seek_time == 0)
|
||||
// return 1;
|
||||
// // forward_time = (seek_time<MAX_FORWARD_TIME)?seek_time:MAX_FORWARD_TIME;
|
||||
// forward_time = seek_time;
|
||||
// os_sema_down(&seek_sema,5000);
|
||||
// set_mp3_seek(forward_time);
|
||||
// cur_mp3_info->update_fops = 1;
|
||||
// os_sema_up(&seek_sema);
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// int seektable_check(CUR_MP3_INFO *mp3_info)
|
||||
// {
|
||||
// int32_t ret = 0;
|
||||
// uint32_t read_buf[4] = {0};
|
||||
// uint32_t seek_table_len = 0;
|
||||
// uint32_t *cache_buf = NULL;
|
||||
|
||||
// cache_buf = (uint32_t*)MP3_DECODE_ZALLOC(sizeof(uint32_t)*100);
|
||||
// if(!cache_buf)
|
||||
// goto seektable_check_end;
|
||||
// osal_fread(read_buf, 4, 4, mp3_info->mp3_st_fp);
|
||||
// if((read_buf[0]==mp3_info->total_size) && (read_buf[1]==mp3_info->first_frame_offset)
|
||||
// && (read_buf[2]==mp3_info->normal_frame_offset)) {
|
||||
// mp3_info->total_frame = read_buf[3];
|
||||
// seek_table_len = osal_fsize(mp3_info->mp3_st_fp) - sizeof(read_buf);
|
||||
// INIT_LIST_HEAD((struct list_head *)&mp3_info->seek_table_head);
|
||||
// while(seek_table_len) {
|
||||
// MP3_SEEK_TABLE *sub_seek_table = MP3_DECODE_ZALLOC(sizeof(MP3_SEEK_TABLE));
|
||||
// list_add_tail((struct list_head *)&sub_seek_table->sub_table_list,(struct list_head *)&mp3_info->seek_table_head);
|
||||
// osal_fread((void*)cache_buf, 4, 100, mp3_info->mp3_st_fp);
|
||||
// os_memcpy(sub_seek_table->sub_table, cache_buf, sizeof(uint32_t)*100);
|
||||
// seek_table_len -= 100*4;
|
||||
// }
|
||||
// cur_mp3_info->totaltime = cur_mp3_info->total_frame * cur_mp3_info->samples / cur_mp3_info->samplingrate;
|
||||
// cur_mp3_info->once_move_time = (cur_mp3_info->totaltime%100)?(cur_mp3_info->totaltime/100+1):(cur_mp3_info->totaltime/100);
|
||||
// MP3_INFO("total_frame:%d total_time:%d once_move_time:%d\n",cur_mp3_info->total_frame, cur_mp3_info->totaltime,cur_mp3_info->once_move_time);
|
||||
// cur_mp3_info->get_totaltime = 1;
|
||||
// ret = 1;
|
||||
// }
|
||||
// seektable_check_end:
|
||||
// if(cache_buf)
|
||||
// MP3_DECODE_FREE((void*)cache_buf);
|
||||
// osal_fclose(mp3_info->mp3_st_fp);
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
void find_first_frame(CUR_MP3_INFO *cur_mp3_info, void *fp)
|
||||
{
|
||||
uint8_t mp3_head[512];
|
||||
uint8_t bitrate_index = 0;
|
||||
uint8_t channel_mode = 0x11;
|
||||
uint8_t padding = 0;
|
||||
uint8_t layer_index = 0;
|
||||
uint8_t mpeg_index = 0;
|
||||
uint8_t samplingrate_index = 0;
|
||||
int32_t bitrate = 0;
|
||||
uint32_t offset = 0;
|
||||
uint32_t first_frame_offset = 0;
|
||||
uint32_t seek = 0;
|
||||
uint32_t frame_len = 0;
|
||||
|
||||
if(!cur_mp3_info) {
|
||||
return;
|
||||
}
|
||||
osal_fread(mp3_head, 512, 1, fp);
|
||||
if(os_strncmp(mp3_head+offset, "ID3", 3) == 0) {
|
||||
uint32_t ID3V2_len = (mp3_head[6]&0x7F)*0x200000+ (mp3_head[7]&0x7F)*0x4000 +
|
||||
(mp3_head[8]&0x7F)*0x80 +(mp3_head[9]&0x7F);
|
||||
offset += (ID3V2_len+10);
|
||||
}
|
||||
MP3_INFO("ID3 offset:%x\n",offset);
|
||||
osal_fseek(fp,offset);
|
||||
seek = offset;
|
||||
osal_fread(mp3_head,1,512,fp);
|
||||
while(((mp3_head[offset-seek]<<8) | (mp3_head[offset-seek+1]&0xE0)) != 0xFFE0) {
|
||||
offset++;
|
||||
if((offset+1) > (seek+512)) {
|
||||
osal_fseek(fp,offset);
|
||||
osal_fread(mp3_head, 1, 512, fp);
|
||||
seek = offset;
|
||||
}
|
||||
}
|
||||
osal_fseek(fp,offset);
|
||||
seek = offset;
|
||||
osal_fread(mp3_head,1,512,fp);
|
||||
cur_mp3_info->mp3_fp = fp;
|
||||
first_frame_offset = offset;
|
||||
// os_printf("\n***first frame offset:%x****\n",first_frame_offset);
|
||||
cur_mp3_info->first_frame_offset = first_frame_offset;
|
||||
layer_index = (mp3_head[first_frame_offset-seek+1]>>1)&0x3;
|
||||
mpeg_index = (mp3_head[first_frame_offset-seek+1]>>3)&0x3;
|
||||
samplingrate_index = (mp3_head[first_frame_offset-seek+2]>>2)&0x3;
|
||||
cur_mp3_info->samplingrate = samplingrate_table[mpeg_index][samplingrate_index];
|
||||
cur_mp3_info->samples = samples_table[mpeg_index][layer_index];
|
||||
channel_mode = (mp3_head[first_frame_offset-seek+3]>>6)&0x3;
|
||||
if(mpeg_index == 3) { /*MPEG 1*/
|
||||
switch(layer_index) {
|
||||
case 0:break;
|
||||
case 1:cur_mp3_info->bitrate_table_index = 2;break; /*layer III*/
|
||||
case 2:cur_mp3_info->bitrate_table_index = 1;break; /*layer II*/
|
||||
case 3:cur_mp3_info->bitrate_table_index = 0;break; /*layer I*/
|
||||
default:break;
|
||||
}
|
||||
}
|
||||
else if((mpeg_index == 0) || (mpeg_index == 2)) { /*MPEG 2、MPEG2.5*/
|
||||
switch(layer_index) {
|
||||
case 0:break;
|
||||
case 1:cur_mp3_info->bitrate_table_index = 4;break;
|
||||
case 2:cur_mp3_info->bitrate_table_index = 4;break;
|
||||
case 3:cur_mp3_info->bitrate_table_index = 3;break;
|
||||
default:break;
|
||||
}
|
||||
}
|
||||
bitrate_index = (mp3_head[first_frame_offset-seek+2]>>4)&0xf;
|
||||
bitrate = bitrate_table[cur_mp3_info->bitrate_table_index][bitrate_index];
|
||||
if(layer_index == 3)
|
||||
cur_mp3_info->padding_mul = 4;
|
||||
else if((layer_index == 1) || (layer_index == 2))
|
||||
cur_mp3_info->padding_mul = 1;
|
||||
padding = ((mp3_head[first_frame_offset-seek+2]>>1)&0x1) * cur_mp3_info->padding_mul;
|
||||
frame_len = cur_mp3_info->samples/8*bitrate/cur_mp3_info->samplingrate + padding;
|
||||
MP3_INFO("first frame samples:%d samplingrate:%d channel_mode:%d bitrate:%d frame_len:%d\n",
|
||||
cur_mp3_info->samples,cur_mp3_info->samplingrate,channel_mode,bitrate,frame_len);
|
||||
cur_mp3_info->normal_frame_offset = cur_mp3_info->first_frame_offset+frame_len;
|
||||
cur_mp3_info->one_second_frame = cur_mp3_info->samplingrate/cur_mp3_info->samples;
|
||||
|
||||
#if MP3_SAVE_INFO
|
||||
int32_t ret = 0;
|
||||
DIR st_dir;
|
||||
os_sema_init(&seek_sema, 1);
|
||||
if(!key_seek_list)
|
||||
key_seek_list = add_keycallback(key_seek_callback, NULL);
|
||||
MP3_INFO("one_second_frame:%d",cur_mp3_info->one_second_frame);
|
||||
ret = f_opendir(&st_dir,"0:/MP3_SEEK");
|
||||
if(ret == FR_OK) {
|
||||
cur_mp3_info->mp3_st_fp = osal_fopen(cur_mp3_info->mp3_st_filename, "r");
|
||||
if(cur_mp3_info->mp3_st_fp) {
|
||||
if(seektable_check(cur_mp3_info)) {
|
||||
return;
|
||||
}
|
||||
osal_fclose(cur_mp3_info->mp3_st_fp);
|
||||
}
|
||||
}
|
||||
else{
|
||||
ret = f_mkdir("0:/MP3_SEEK");
|
||||
}
|
||||
get_curmp3_totaltime_ergodic(fp, first_frame_offset);
|
||||
cur_mp3_info->mp3_st_fp = osal_fopen(cur_mp3_info->mp3_st_filename, "wb");
|
||||
if(cur_mp3_info->mp3_st_fp) {
|
||||
osal_fwrite(cur_mp3_info, 4, 4, cur_mp3_info->mp3_st_fp);
|
||||
struct list_head *seek_table_list = cur_mp3_info->seek_table_head.next;
|
||||
struct list_head *seek_table_head = &cur_mp3_info->seek_table_head;
|
||||
while(seek_table_list != seek_table_head) {
|
||||
MP3_SEEK_TABLE *seek_table = list_entry((struct list_head *)seek_table_list,MP3_SEEK_TABLE,sub_table_list);
|
||||
osal_fwrite(seek_table->sub_table, 100, 4, cur_mp3_info->mp3_st_fp);
|
||||
seek_table_list = seek_table_list->next;
|
||||
}
|
||||
osal_fclose(cur_mp3_info->mp3_st_fp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// uint32_t get_curmp3_songtime(uint32_t brate)
|
||||
// {
|
||||
// if(!cur_mp3_info) {
|
||||
// return 0;
|
||||
// }
|
||||
// if(cur_mp3_info->get_totaltime == 1) {
|
||||
// return cur_mp3_info->totaltime;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
void clear_curmp3_info(CUR_MP3_INFO *cur_mp3_info)
|
||||
{
|
||||
if(cur_mp3_info) {
|
||||
MP3_DECODE_FREE(cur_mp3_info);
|
||||
}
|
||||
#if MP3_SAVE_INFO
|
||||
if(key_seek_list) {
|
||||
remove_keycallback(key_seek_list);
|
||||
key_seek_list = NULL;
|
||||
}
|
||||
struct list_head *list_n = (struct list_head *)&cur_mp3_info->seek_table_head;
|
||||
struct list_head *head = (struct list_head *)&cur_mp3_info->seek_table_head;
|
||||
MP3_SEEK_TABLE *seek_table = NULL;
|
||||
while(list_n->next != head) {
|
||||
list_n = list_n->next;
|
||||
seek_table = list_entry((struct list_head *)list_n,MP3_SEEK_TABLE,sub_table_list);
|
||||
MP3_DECODE_FREE(seek_table);
|
||||
}
|
||||
os_sema_del(&seek_sema);
|
||||
#endif
|
||||
}
|
||||
46
sdk/app/audio_media_ctrl/mp3/mp3_getInfo.h
Normal file
46
sdk/app/audio_media_ctrl/mp3/mp3_getInfo.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef _MP3_GETINFO_MSI_H_
|
||||
#define _MP3_GETINFO_MSI_H_
|
||||
|
||||
#include "basic_include.h"
|
||||
|
||||
typedef struct {
|
||||
struct list_head sub_table_list;
|
||||
uint32_t sub_table[100];
|
||||
}MP3_SEEK_TABLE;
|
||||
|
||||
typedef struct {
|
||||
uint32_t total_size;
|
||||
uint32_t first_frame_offset;
|
||||
uint32_t normal_frame_offset;
|
||||
uint32_t total_frame;
|
||||
uint32_t once_move_time;
|
||||
uint32_t offset_seek;
|
||||
uint32_t samplingrate;
|
||||
uint32_t one_second_frame;
|
||||
int32_t playtime;
|
||||
int32_t play_frame;
|
||||
|
||||
uint16_t totaltime;
|
||||
uint16_t samples;
|
||||
|
||||
uint8_t get_totaltime;
|
||||
uint8_t update_fops;
|
||||
|
||||
uint8_t bitrate_table_index;
|
||||
uint8_t padding_mul;
|
||||
|
||||
void *mp3_fp;
|
||||
void *mp3_st_fp;
|
||||
char mp3_st_filename[50];
|
||||
|
||||
struct list_head seek_table_head;
|
||||
}CUR_MP3_INFO;
|
||||
|
||||
struct os_semaphore seek_sema;
|
||||
|
||||
uint32_t get_curmp3_size(CUR_MP3_INFO *cur_mp3_info, uint32_t s);
|
||||
void curmp3_info_init(CUR_MP3_INFO **cur_mp3_info, uint8_t *mp3_filename);
|
||||
void clear_curmp3_info(CUR_MP3_INFO *cur_mp3_info);
|
||||
void find_first_frame(CUR_MP3_INFO *cur_mp3_info, void *fp);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user