先上官網下載 minimp3 原始檔: https://github.com/lieff/minimp3
只需將檔案 minimp3.h 複製到專案目錄. 再編輯 mp3 播放主程式, 同樣透過 ALSA library 來播放:
// mp3play.cpp
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include "alsa/asoundlib.h"
#define MINIMP3_IMPLEMENTATION
#include "minimp3.h"
int main(int argc, char *argv[]) {
const char *filename = (argc > 1) ? argv[1] : "test.mp3";
int fd = open(filename, O_RDONLY);
if (fd < 0) {
printf("%s => not found\n", filename);
return -1;
}
int fileLength = lseek(fd, 0, SEEK_END);
unsigned char *fileMMAP = (unsigned char *) mmap(0, fileLength, PROT_READ, MAP_PRIVATE, fd, 0);
int16_t speaker[MINIMP3_MAX_SAMPLES_PER_FRAME];
mp3dec_frame_info_t info;
mp3dec_t mp3decoder;
mp3dec_init(&mp3decoder);
int uframes = mp3dec_decode_frame(&mp3decoder, fileMMAP, fileLength, speaker, &info);// 1st frame to get channels && sampleRate
if (uframes > 0) {
printf("play uframes = %d, offset =%d, channels=%d, sampleRate=%d, frame_bytes=%d\n", uframes, info.frame_offset, info.channels, info.hz, info.frame_bytes);
unsigned int channels = info.channels;
unsigned int sampleRate = info.hz;
snd_pcm_t *handle;
if (snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0) == 0) { // hw:0,0 , default
if (snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_INTERLEAVED, channels, sampleRate, 1, sampleRate / 4) == 0) {
do {
const int err = snd_pcm_writei(handle, speaker, uframes);
if (err < 0) {
if (snd_pcm_recover(handle, err, 0) < 0) break;// alsa try to recover
}
fileMMAP += info.frame_bytes;// mp3 file position goes ahead
uframes = mp3dec_decode_frame(&mp3decoder, fileMMAP, uframes, speaker, &info);// is 1152 enough?
} while (uframes > 0);
}
snd_pcm_close(handle);
}
}
close(fd);
return 0;
}
編譯並執行
g++ mp3play.cpp -lasound && ./a.out
沒有留言:
張貼留言