Initial import of NFC GNSS SDK project
This commit is contained in:
@@ -0,0 +1,485 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ql_rtos.h"
|
||||
#include "ql_application.h"
|
||||
#include "ql_audio.h"
|
||||
#include "ql_iic.h"
|
||||
#include "ql_gpio.h"
|
||||
#include "ql_fs.h"
|
||||
|
||||
#include "webclient.h"
|
||||
#include <netdb.h>
|
||||
#include "sockets.h"
|
||||
#include "mp3dec.h"
|
||||
#include "test_mp3.h"
|
||||
|
||||
#define RLOGD printf
|
||||
struct webclient_session *session = NULL;
|
||||
static int pos_length,total_length = 0;
|
||||
|
||||
static Mp3PlaybackHandle mp3_handle;
|
||||
static Mp3PlayConfigInfo mp3_configInfo;
|
||||
static unsigned char mp3_player_status = 0;
|
||||
QFILE *local_mp3_file_fd=NULL;
|
||||
|
||||
static int mp3_player_end_frame = 0;
|
||||
|
||||
int current_sample_rate = 0;
|
||||
static audio_track_handle track_hd;
|
||||
|
||||
static unsigned short pcm_buff[1152*2]={0x00};
|
||||
|
||||
struct mp3_decoder
|
||||
{
|
||||
/* mp3 information */
|
||||
HMP3Decoder decoder;
|
||||
MP3FrameInfo frame_info;
|
||||
// rt_uint32_t frames;
|
||||
|
||||
/* mp3 read session */
|
||||
uint8_t *read_buffer, *read_ptr;
|
||||
u32 bytes_left;
|
||||
|
||||
};
|
||||
|
||||
static void mp3_decoder_track_callback(acm_audio_track_handle handle, acm_audio_track_event_t event)
|
||||
{
|
||||
if(mp3_player_status==1 && mp3_player_end_frame==1){
|
||||
if(event == AUDIO_TRACK_EVENT_UNDERRUN){
|
||||
printf("AUDIO_TRACK_EVENT_UNDERRUN\r\n");
|
||||
mp3_player_status = 2;//
|
||||
}
|
||||
}
|
||||
|
||||
if(mp3_player_status==2){
|
||||
if(event == AUDIO_TRACK_EVENT_DRAINING){
|
||||
printf("AUDIO_TRACK_EVENT_DRAINING\r\n");
|
||||
mp3_player_status = 3;//
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mp3_decoder_init(struct mp3_decoder* decoder)
|
||||
{
|
||||
/* init read session */
|
||||
decoder->read_ptr = NULL;
|
||||
decoder->bytes_left = 0;
|
||||
|
||||
decoder->decoder = MP3InitDecoder();
|
||||
}
|
||||
|
||||
void mp3_decoder_detach(struct mp3_decoder* decoder)
|
||||
{
|
||||
/* release mp3 decoder */
|
||||
MP3FreeDecoder(decoder->decoder);
|
||||
}
|
||||
|
||||
struct mp3_decoder* mp3_decoder_create()
|
||||
{
|
||||
struct mp3_decoder* decoder;
|
||||
|
||||
/* allocate object */
|
||||
decoder = (struct mp3_decoder*) malloc(sizeof(struct mp3_decoder));
|
||||
if (decoder != NULL)
|
||||
{
|
||||
mp3_decoder_init(decoder);
|
||||
}
|
||||
|
||||
return decoder;
|
||||
}
|
||||
|
||||
void mp3_decoder_delete(struct mp3_decoder* decoder)
|
||||
{
|
||||
/* de-init mp3 decoder object */
|
||||
mp3_decoder_detach(decoder);
|
||||
/* release this object */
|
||||
free(decoder);
|
||||
decoder = NULL;
|
||||
}
|
||||
|
||||
|
||||
static int check_mp3_sync_word(struct mp3_decoder *codec)
|
||||
{
|
||||
int err;
|
||||
|
||||
memset(&codec->frame_info, 0, sizeof(MP3FrameInfo));
|
||||
|
||||
err = MP3GetNextFrameInfo(codec->decoder, &codec->frame_info, codec->read_ptr);
|
||||
if (err == ERR_MP3_INVALID_FRAMEHEADER)
|
||||
{
|
||||
goto __err;
|
||||
}
|
||||
else if (err != ERR_MP3_NONE)
|
||||
{
|
||||
goto __err;
|
||||
}
|
||||
else if (codec->frame_info.nChans != 1 && codec->frame_info.nChans != 2)
|
||||
{
|
||||
goto __err;
|
||||
}
|
||||
else if (codec->frame_info.bitsPerSample != 16 && codec->frame_info.bitsPerSample != 8)
|
||||
{
|
||||
goto __err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
__err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int mp3_decoder_run(struct mp3_decoder* decoder)
|
||||
{
|
||||
int err;
|
||||
int read_offset = 0;;
|
||||
|
||||
// rt_kprintf("decoder->bytes_left:%d,mp3_player_end_frame:%d\n", decoder->bytes_left,mp3_player_end_frame);
|
||||
extern int tts_playing;
|
||||
if(tts_playing==2){
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((decoder->read_ptr == NULL) || decoder->bytes_left < 2 * MAINBUF_SIZE)
|
||||
{
|
||||
mp3_player_end_frame = 1;
|
||||
}
|
||||
|
||||
// printf("mp3_player_end_frame:%d,decoder->bytes_left:%d\n", mp3_player_end_frame, decoder->bytes_left);
|
||||
|
||||
if(mp3_player_end_frame&& (decoder->bytes_left==0)){
|
||||
//mp3_player_end_frame = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
//loop_find:
|
||||
// rt_kprintf("read offset: 0x%08x\n", decoder->read_ptr - decoder->read_buffer);
|
||||
read_offset = MP3FindSyncWord(decoder->read_ptr, decoder->bytes_left);
|
||||
if (read_offset < 0)
|
||||
{
|
||||
//if(mp3_decoder_fill_buffer(decoder) == 0) goto loop_find;
|
||||
|
||||
/* discard this data */
|
||||
RLOGD("outof sync, byte left: %d\n", decoder->bytes_left);
|
||||
|
||||
decoder->bytes_left = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(read_offset > decoder->bytes_left)
|
||||
{
|
||||
RLOGD("find sync exception: %d:%d.", read_offset, decoder->bytes_left);
|
||||
decoder->read_ptr += decoder->bytes_left;
|
||||
decoder->bytes_left = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
decoder->read_ptr += read_offset;
|
||||
decoder->bytes_left -= read_offset;
|
||||
}
|
||||
|
||||
|
||||
if (check_mp3_sync_word(decoder) == -1)
|
||||
{
|
||||
if (decoder->bytes_left > 0)
|
||||
{
|
||||
decoder->bytes_left --;
|
||||
decoder->read_ptr ++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (decoder->bytes_left < 1024)
|
||||
{
|
||||
mp3_player_end_frame = 1;
|
||||
if(decoder->bytes_left==0) return -1;
|
||||
}
|
||||
|
||||
err = MP3Decode(decoder->decoder, &decoder->read_ptr,
|
||||
(int*)&decoder->bytes_left, (short*)pcm_buff, 0);
|
||||
|
||||
if (err != ERR_MP3_NONE)
|
||||
{
|
||||
switch (err)
|
||||
{
|
||||
case ERR_MP3_INDATA_UNDERFLOW:
|
||||
RLOGD("ERR_MP3_INDATA_UNDERFLOW\n");
|
||||
//decoder->bytes_left = 0;
|
||||
if(mp3_player_end_frame == 1)
|
||||
{
|
||||
/* release this memory block */
|
||||
if(decoder->bytes_left==0){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ERR_MP3_MAINDATA_UNDERFLOW:
|
||||
/* do nothing - next call to decode will provide more mainData */
|
||||
RLOGD("ERR_MP3_MAINDATA_UNDERFLOW\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
RLOGD("unknown error: %d, left: %d\n", err, decoder->bytes_left);
|
||||
|
||||
// skip this frame
|
||||
if (decoder->bytes_left > 0)
|
||||
{
|
||||
decoder->bytes_left --;
|
||||
decoder->read_ptr ++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO
|
||||
//RT_ASSERT(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int outputSamps;
|
||||
/* no error */
|
||||
MP3GetLastFrameInfo(decoder->decoder, &decoder->frame_info);
|
||||
|
||||
/* set sample rate */
|
||||
if (decoder->frame_info.samprate != current_sample_rate)
|
||||
{
|
||||
current_sample_rate = decoder->frame_info.samprate;
|
||||
}
|
||||
|
||||
ql_audio_track_write(track_hd, (char*)pcm_buff, 1152);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u32 local_mp3_data_fetch(const char *uri, uint8_t *buffer, u32 length)
|
||||
{
|
||||
int read_bytes;
|
||||
|
||||
if(local_mp3_file_fd==NULL){
|
||||
local_mp3_file_fd= ql_fopen(uri, "r");
|
||||
|
||||
if (local_mp3_file_fd==NULL){
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
read_bytes = ql_fread(buffer, 1, length, local_mp3_file_fd);
|
||||
|
||||
if (read_bytes <= 0) return 0;
|
||||
|
||||
return read_bytes;
|
||||
}
|
||||
|
||||
size_t url_mp3_data_fetch(const char *uri, uint8_t *buffer, size_t length)
|
||||
{
|
||||
int resp_status = -1;
|
||||
uint32_t nw = length;
|
||||
uint32_t page_pos = 0;
|
||||
int error_cnt = 0;
|
||||
|
||||
//printf("fd_fetch start\n");
|
||||
session = webclient_session_create(1024);
|
||||
if (!session)
|
||||
{
|
||||
printf("open uri failed.");
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
resp_status = webclient_get(session, uri);
|
||||
if (resp_status == 304)
|
||||
{
|
||||
printf("file download failed! Server http response : 304 not modified!");
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (resp_status != 200)
|
||||
{
|
||||
printf("file download failed! Server http response : %d,%s !", resp_status, uri);
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (session->content_length == 0)
|
||||
{
|
||||
printf("Request file size is 0!");
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
printf("start read\n");
|
||||
if(total_length < session->content_length)
|
||||
{
|
||||
if ((nw + total_length) > session->content_length)
|
||||
{
|
||||
nw = session->content_length - total_length;
|
||||
//log_i("last page, content_length:%d, total_length:%d, nw:%d\n", session->content_length, total_length, nw);
|
||||
}
|
||||
|
||||
/* read */
|
||||
page_pos = 0;
|
||||
do
|
||||
{
|
||||
if(vad_audio_is_recording()) {
|
||||
break;
|
||||
}
|
||||
|
||||
pos_length = webclient_read(session, buffer + page_pos, nw - page_pos);
|
||||
if(pos_length<0){
|
||||
if(error_cnt++<3){
|
||||
continue;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos_length == 0)
|
||||
{
|
||||
printf("read error: %d, content_pos:%d, page_pos:%d\n", pos_length, total_length, page_pos);
|
||||
break;
|
||||
}
|
||||
//LOG_I("webclient_read %d\n", length);
|
||||
page_pos += pos_length;
|
||||
}
|
||||
while (page_pos < nw); /* read */
|
||||
|
||||
total_length += page_pos;
|
||||
}
|
||||
|
||||
printf("end read:%d, %d\n", total_length, session->content_length);
|
||||
|
||||
__exit:
|
||||
|
||||
//printf("fd_fetch end\n");
|
||||
if (session != NULL){
|
||||
webclient_close(session);
|
||||
session = NULL;
|
||||
}
|
||||
|
||||
if(total_length<session->content_length){
|
||||
total_length = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct mp3_decoder* aofei_mp3_decoder = NULL;
|
||||
|
||||
int aofei_mp3_player_init(void)
|
||||
{
|
||||
if(aofei_mp3_decoder==NULL){
|
||||
aofei_mp3_decoder = mp3_decoder_create();
|
||||
if (aofei_mp3_decoder == NULL){
|
||||
RLOGD("mp3_decoder_create error\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aofei_mp3_player(char *file_name)
|
||||
{
|
||||
int ret = 0;
|
||||
uint8_t *mp3_buff = malloc(100*1024);
|
||||
|
||||
memset(mp3_buff, 0, 100*1024);
|
||||
//直接下载到一个100k的buffer
|
||||
if(strstr(file_name, "http:")){//播放url
|
||||
ret = url_mp3_data_fetch(file_name, mp3_buff, 100*1024);
|
||||
}else if(strstr(file_name, "test.mp3")){//播放本地音频
|
||||
total_length = test_data_size;
|
||||
memcpy(mp3_buff, test_data, total_length);
|
||||
}else{//播放本地音频
|
||||
total_length = local_mp3_data_fetch(file_name, mp3_buff, 100*1024);
|
||||
}
|
||||
|
||||
mp3_player_end_frame = 0;
|
||||
|
||||
|
||||
if(aofei_mp3_player_init()==-1)return;
|
||||
|
||||
if(ret>=0){
|
||||
aofei_mp3_decoder->read_ptr = mp3_buff;
|
||||
aofei_mp3_decoder->bytes_left = total_length;
|
||||
|
||||
track_hd = ql_audio_track_open(16000, 1, 0, mp3_decoder_track_callback);
|
||||
|
||||
app_codec_pa_open();
|
||||
|
||||
mp3_player_status = 1;
|
||||
|
||||
RLOGD("aofei_mp3_player0\n");
|
||||
|
||||
while(mp3_decoder_run(aofei_mp3_decoder)!=-1){
|
||||
if(vad_audio_is_recording()||tts_playing_ret()==2){
|
||||
mp3_player_status = 0;
|
||||
break;
|
||||
}
|
||||
ql_rtos_task_sleep_ms(35);
|
||||
}
|
||||
|
||||
|
||||
|
||||
while(mp3_player_status!=2){
|
||||
if(vad_audio_is_recording() || tts_playing_ret()==2){
|
||||
mp3_player_status = 0;
|
||||
break;
|
||||
}
|
||||
ql_rtos_task_sleep_ms(30);
|
||||
}
|
||||
|
||||
RLOGD("aofei_mp3_player1\n");
|
||||
|
||||
ql_audio_track_close(track_hd, 1);
|
||||
|
||||
while(mp3_player_status!=3){
|
||||
if(vad_audio_is_recording()||tts_playing_ret()==2){
|
||||
mp3_player_status = 0;
|
||||
break;
|
||||
}
|
||||
ql_rtos_task_sleep_ms(30);
|
||||
}
|
||||
|
||||
if(!vad_audio_is_recording()){
|
||||
ql_rtos_task_sleep_ms(200);
|
||||
}
|
||||
RLOGD("aofei_mp3_player2\n");
|
||||
app_codec_pa_close();
|
||||
}
|
||||
|
||||
if(aofei_mp3_decoder!=NULL){
|
||||
mp3_decoder_delete(aofei_mp3_decoder);
|
||||
aofei_mp3_decoder = NULL;
|
||||
}
|
||||
|
||||
if(local_mp3_file_fd!=NULL){
|
||||
ql_fclose(local_mp3_file_fd);
|
||||
local_mp3_file_fd = NULL;
|
||||
}
|
||||
|
||||
if (session != NULL){
|
||||
webclient_close(session);
|
||||
session = NULL;
|
||||
}
|
||||
|
||||
if(mp3_buff!=NULL){
|
||||
free(mp3_buff);
|
||||
mp3_buff = NULL;
|
||||
}
|
||||
|
||||
total_length = 0;
|
||||
mp3_player_end_frame = 0;
|
||||
mp3_player_status = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user