⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp3_dbg.c

📁 ARM_CORTEX-M3应用实例开发详解光盘
💻 C
字号:
/******************************* (C) Embest ***********************************
* File Name          : mp3_dbg.c
* Author             : tary
* Date               : 2009-05-25
* Version            : 0.1
* Description        : 播放wav及mp3音乐文件
******************************************************************************/

/* Includes -----------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include "ucos_ii.h"
#include "drv_init.h"
#include "mp3_dbg.h"

#define LOCAL_DBG		1

/* Variables ----------------------------------------------------------------*/
OS_STK App_TaskMp3Stk[APP_TASK_MP3_STK_SIZE];
OS_EVENT* fr_evt = NULL;

// FATFS fs;
FIL fil;
char filebuf[FILEBUF_CNT][FILEBUF_SIZ + 4];
int filebuf_rdy[FILEBUF_CNT] = {1, 0};
int filebuf_idx = 0;

int wave_file_read(char* filename, int mode) {
	char fnambuf[0x80];
	int r;
	int br;

#if 0
	r = f_mount(1, &fs);
	if (FR_OK != r) {
		return -1;
	}
#endif

	sprintf(fnambuf, "1:\\wavefile\\%s", filename);
	r = f_open(&fil, fnambuf, FA_READ | FA_OPEN_EXISTING);
	if (FR_OK != r) {
		printf("\r\nopen file %s err %d", filename, r);
		return -2;
	}

	r = f_read(&fil, filebuf[filebuf_idx], FILEBUF_SIZ, (UINT*)&br);
	if (FR_OK != r) {
		return -3;
	}

	if (br != FILEBUF_SIZ) {
		return -4;
	}

	return 0;	
}

int wave_data_parse(char* binfile, int* fmt_of, int* data_of) {
	riff_chunk_t* prc;
	int bof = 0;
	int fact = 0;

	prc = (riff_chunk_t*)&binfile[bof];
	if (0 != strncmp(prc->id, "RIFF", 4)) {
		return -1;
	}

	if (0 != strncmp(prc->data, "WAVE", 4)) {
		return -2;
	}

	bof += 12;
	prc = (riff_chunk_t*)&binfile[bof];
	if (0 != strncmp(prc->id, "fmt ", 4)) {
		return -3;
	}

	if (fmt_of != NULL) {
		*fmt_of = (char*)prc->data - binfile;
	}

	if (prc->size != 0x10) {
		fact = 1;
	}

	if (fact) {
		//get fact thunk
		bof += 8 + prc->size;
		prc = (riff_chunk_t*)&binfile[bof];
	}

	//get data chunk
	bof += 8 + prc->size;
	prc = (riff_chunk_t*)&binfile[bof];

	if (0 != strncmp(prc->id, "data", 4)) {
		return -4;
	}

	if (data_of != NULL) {
		*data_of = (char*)prc->data - binfile;
	}
	return 0;
}

// 当前缓冲操作(播放)完成, 该函数将被调用
// 将当前缓冲置为"未准备好"( rdy = 0 )
// 并置另一缓冲区为当前缓冲
// 并发送信号量给fr_evt
int wave_end_inform(char* buf, int idx, int cnt) {
	INT8U r;

	filebuf_rdy[filebuf_idx] = 0;

	filebuf_idx = !filebuf_idx;
	if (filebuf_rdy[filebuf_idx] == 0) {
		// stop the play
		return -1;
	}

	dcodec_set_buf(filebuf[filebuf_idx], filebuf_rdy[filebuf_idx]); 

	r = OSSemPost(fr_evt);
	if (OS_ERR_NONE != r) {
		return 0;
	}

	return 0;	
}

int wave_play_cont (void) {
	// INT8U r;

	if (filebuf_rdy[filebuf_idx] == 0) {
		filebuf_idx = !filebuf_idx;
		if (filebuf_rdy[filebuf_idx] == 0) {
			return -1;
		}
	}

	// 打开定时器,继续播放
	dcodec_set_buf(filebuf[filebuf_idx], filebuf_rdy[filebuf_idx]); 
	dcodec_start();
	return 0;
}

int wave_play_svr(void) {
	INT8U err;
	int idx;
	int br, r;

	r = 0;
	while (0
	|| filebuf_rdy[0]
	|| filebuf_rdy[1]
	) {
		OSSemPend(fr_evt, OS_TICKS_PER_SEC / 3, &err);
		if (OS_ERR_NONE != err) {
			// r = -1;
			// 信号超时
			// 表示缓冲区播放完成时
			// 读数据到新缓冲区未完成
			// 播放定时器已停止
			r = wave_play_cont();
			if (r < 0) {
				break;
			}
		}

		idx = !filebuf_idx;
		if (filebuf_rdy[idx]) {
			// r = -2;
			continue;
		}

		r = f_read(&fil, filebuf[idx], FILEBUF_SIZ, (UINT*)&br);
		if (FR_OK != r) {
			r = -3;
			break;
		}

		if (br == 0) {
			r = -4;
			break;
		}
		filebuf_rdy[idx] = br;

#if 0
		r = key_accept();
		if (r < 0) {
			continue;
		}

		if (r == KEY_WAKE) {
			v = dcodec_get_vol();
			if (v < 3) {
				v = 3;
			}
			dcodec_set_vol(v * 4 / 3);
		}
		if (r == KEY_TAMP) {
			dcodec_set_vol(dcodec_get_vol() * 3 / 4);
		}
#endif
	}

	return r;
}

int wave_start(int fmt_of, int data_of) {
	filebuf_rdy[filebuf_idx] = FILEBUF_SIZ - data_of;
	filebuf_rdy[!filebuf_idx] = 0;

	dcodec_set_fmt((data_fmt_t*)&filebuf[filebuf_idx][fmt_of]);
	dcodec_set_buf(&filebuf[filebuf_idx][data_of], filebuf_rdy[filebuf_idx]);
	dcodec_set_inform(wave_end_inform);

	fr_evt = OSSemCreate(1);
	if (fr_evt == NULL) {
		return -1;
	}
	
	dcodec_start();
	return 0;	
}

int wave_inc_volume(void){
	int v;

	v = dcodec_get_vol();
	if (v < 3) {
		v = 3;
	}
	dcodec_set_vol(v * 4 / 3);
	return 0;
}

int wave_dec_volume(void) {
	dcodec_set_vol(dcodec_get_vol() * 3 / 4);
	return 0;
}

int wave_exit(int err_code) {
	INT8U err;
	int i;

	for (i = 0; i < FILEBUF_CNT; i++) {
		filebuf_rdy[i] = 0;
	}

	f_close(&fil);
	if (fr_evt != NULL) {
		OSSemDel(fr_evt, OS_DEL_ALWAYS, &err);
		fr_evt = NULL;
	}
	printf(" err %d", err_code);
	return 0;
}

/*=============================================================================
* Function	: 
* Description	: 
* Input Para	: 
* Output Para	: 
* Return Value  : 
=============================================================================*/
void mp3_dbg(void* parg) {
	int fmt_of, data_of;
	char* filename;
	int r;

	// gets(filename);
	filename = ((char**)parg)[1];

	if (filename == NULL) {
		printf("\r\nargument");
		wave_exit(-1);
		return;
	}

	filebuf_idx = 0;

	r = wave_file_read(filename, 0);
	if (r < 0) {
		printf("\r\nfile read");
		wave_exit(r);
		return;
	}

	r = wave_data_parse(filebuf[filebuf_idx], &fmt_of, &data_of);
	if (r < 0) {
		printf("\r\nfile parse");
		wave_exit(r);
		return;
	}

	r = wave_start(fmt_of, data_of);
	if (r < 0) {
		printf("\r\nfile start");
		wave_exit(r);
		return;
	}

	r = wave_play_svr();

	printf("\r\nplay svr");
	wave_exit(r);

	// printf("\r\nthe task mp3_dbg() is running!");
	return;
}

/************************************END OF FILE******************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -