Cocos2d-x项目移植到WP8系列之五:播放MP3
原文链接: http://www.cnblogs.com/zouzf/p/3972549.html
这一块的细节还是不太了解,只是东凑西拼能跑起来而已
1、网上下载lamb库 生成需要的lib库,详情见 【Advanced Windows Phone Programming】在windows phone 8中录制MP3和AAC及Amr音频 第三点的前半部分,也就是生成lib那一部分,然后在CocosDenshion工程里引用那两个lib。
2、把CocosDenshion工程里的Audio.cpp里的void Audio::PreloadSoundEffect(const char* pszFilePath, bool isMusic) 方法里的m_soundEffects[sound].m_soundID = sound; 这句代码之前的代码改成如下:
if (m_engineExperiencedCriticalError) {
return;
} std::string path(pszFilePath); int sound = Hash(pszFilePath); MediaStreamer mediaStreamer; // no MP3 support for CC_PLATFORM_WP8
std::string::size_type pos = path.find(".mp3");
if (pos != path.npos)
{
//path.replace(pos, path.length(), ".wav"); mediaStreamer.Initialize_MP3(CCUtf8ToUnicode(pszFilePath).c_str());
}
else
{
mediaStreamer.Initialize(CCUtf8ToUnicode(pszFilePath).c_str());
} // mediaStreamer.Initialize(CCUtf8ToUnicode(pszFilePath).c_str());
m_soundEffects[sound].m_soundID = sound;
3、CocosDenshion工程里的MediaStreamer类加多一个方法:void MediaStreamer::Initialize_MP3(__in const WCHAR* url),实现如下:
void MediaStreamer::Initialize_MP3(__in const WCHAR* url)
{ WCHAR filePath[MAX_PATH] = {};
if ((wcslen(url) > && url[] == ':'))
{
// path start with "x:", is absolute path
wcscat_s(filePath, url);
}
else if (wcslen(url) >
&& (L'/' == url[] || L'\\' == url[]))
{
// path start with '/' or '\', is absolute path without driver name
wcscat_s(filePath, m_locationPath->Data());
// remove '/' or '\\'
wcscat_s(filePath, (const WCHAR*)url[]);
}else
{
wcscat_s(filePath, m_locationPath->Data());
wcscat_s(filePath, url);
} hip_t hip = hip_decode_init();
if (!hip)
{
printf("创建mp3解码失败");
return ;
} mp3data_struct mp3str;//mp3文件编码信息
std::vector<short*> mp3Buffer;// mp3数据流
std::vector<int> mp3BufferSize; int samples;
int mp3_bytes;
int write_bytes = ; const int BUF_SIZE = ;
const int INBUF_SIZE = ;
const int MP3BUF_SIZE = (int)(1.25 * BUF_SIZE) + ; short pcm_l[INBUF_SIZE];
short pcm_r[INBUF_SIZE];
unsigned char mp3_buf[MP3BUF_SIZE]; FILE * MP3File; std::wstring wstr = std::wstring(filePath);
// return std::string(wstr.begin(),wstr.end()); std::string str_filePath = std::string(wstr.begin(),wstr.end());//"C:\\Data\\Programs\\{4AE99D96-62EE-4A1C-A345-F1B0A81D07BC}\\Install\\Assets\\Resources\\islandbg.mp3"; auto error = fopen_s(&MP3File, str_filePath.c_str(), "rb");
mp3data_struct mp3Header; while ((mp3_bytes = fread(mp3_buf, , , MP3File)) > )
{
samples = hip_decode_headers(hip, mp3_buf, , pcm_l, pcm_r, &mp3Header);
if (samples > )
{
short *tt = new short[samples*sizeof(short)];
memcpy((void*)tt, (const void*)pcm_l, samples*sizeof(short));
mp3Buffer.push_back(tt);
write_bytes += samples*sizeof(short);
mp3BufferSize.push_back(samples*sizeof(short));
//write_bytes = fwrite(pcm_l, sizeof(short), samples, wavfp);
}
} byte* _mp3Buffer = new byte[write_bytes];
byte* temp = _mp3Buffer;
int size = mp3BufferSize.size();
for(int i=;i<size;i++)
{
memcpy(temp, mp3Buffer[i],mp3BufferSize[i]);
delete mp3Buffer[i];
temp += mp3BufferSize[i];
}
mp3Buffer.clear();
hip_decode_exit(hip);
//m_soundEffects[sound].m_soundEffectBufferData m_data.resize(write_bytes);
for(int i=;i<write_bytes;i++)
{
m_data[i]=_mp3Buffer[i];
} fclose(MP3File); m_waveFormat.wFormatTag = WAVE_FORMAT_PCM; //固定
m_waveFormat.nChannels = ; //固定
m_waveFormat.nSamplesPerSec = (DWORD) mp3Header.samplerate;// 固定 m_waveFormat.wBitsPerSample = ;// mp3Header.bitrate * m_waveFormat.nChannels / 8;
//m_waveFormat.wBitsPerSample = mp3Header.bitrate * m_waveFormat.nChannels / 8.0;
m_waveFormat.nBlockAlign = m_waveFormat.nChannels * m_waveFormat.wBitsPerSample / 8.0;
m_waveFormat.nAvgBytesPerSec = m_waveFormat.nSamplesPerSec * m_waveFormat.nBlockAlign; //越大越快
m_waveFormat.cbSize = ; }
完成。
大概流程就是,通过lamb的两个lib库的方法,读取MP3文件的流构建成wav文件格式的流,重点在于通过MP3的文件头信息mp3data_struct 构建出 wav文件的文件头信息WAVEFORMATEX。
另外,因为只读取了一个声道的流,所以m_waveFormat.nChannels = 1;如果对声道有要求的,可以在while循环里把右声道的流也处理一下。
附上一些参考文章: lame mp3解码 Suche MP3 to WAV decoder
原文链接: http://www.cnblogs.com/zouzf/p/3972549.html
最新文章
- PowerDesigner的使用一
- C++高精度计算代码运行时间(转载)
- ProgressBar 的使用
- POJ3415 Common Substrings
- Java web 项目搭建
- iOS网络开发-AFNetworking请求asp.net WebService
- 基于 webpack 的 chrome 扩展开发探索
- Linux - gcc 的简易用法 (编译、参数与链结)
- 20181117-python第二章学习小结-part1
- 低成本制作基于OpenWRT的渗透工具
- Kafka-Record(消息格式)
- Inotify机制的简单应用
- 在Docker环境下部署Kafka
- [dpdk] dpdk启动几个线程
- Codeforces 838 B - Diverging Directions
- 5、Docker网络配置(单机)
- java.lang.IllegalStateException: No typehandler found for mapping XXX
- Springboot统一参数验证方式
- VC++异常处理
- CSS基础范例
热门文章
- windows中控制台窗口和普通窗口有什么区别?
- spring 整合mybatis 学习笔记
- HBuilder 连接 夜神安卓模拟器
- C和MATLAB中:同时对多个变量连续赋值
- jodis遇到的问题
- Kotlin——中级篇(三):可见性修饰符详解
- java.lang.Error: Unresolved compilation problems: 	Syntax error on token ";return";, delete this token 	Type mismatch: cannot convert from Init to String
- IOS开发复习笔记(4)-TableView
- testlink1.9.3测试管理工具安装
- 一、2440裸机点亮led