原文链接: 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

Cocos2d-x项目移植到WP8系列之五:播放MP3的更多相关文章

  1. Cocos2d-x项目移植到WP8系列之二:开篇

    原文链接: http://www.cnblogs.com/zouzf/p/3970130.html 开发环境一笔带过吧,主板和CPU要支持虚拟化技术,要开启才行,装个64位win8.1系统,win8不 ...

  2. Cocos2d-x项目移植到WP8系列之三:C++和C#的交互

    原文链接: http://www.cnblogs.com/zouzf/p/3971021.html 上一篇提到工程使用 XAML 和 Direct3D 项目模板 是因为要涉及到C++和C#的交互,微软 ...

  3. Cocos2d-x项目移植到WP8系列之一:前传

    原文链接: http://www.cnblogs.com/zouzf/p/3969993.html 许久没动笔了,随想一直都有动笔的想法,但拖来拖去,归根到底还是一个懒字吧 .发现人的惰性真是太强大了 ...

  4. Cocos2d-x项目移植到WP8系列之九:使用自定义shader

    本文原链接:http://www.cnblogs.com/zouzf/p/3995132.html 有时候想得到一些例如灰度图等特殊的渲染效果,就得用到自定义shader,关于shader的一些背景知 ...

  5. Cocos2d-x项目移植到WP8系列之八:CCLabelTTF显示中文不换行

    原文链接: http://www.cnblogs.com/zouzf/p/3985330.html 在wp8平台上,CCLabeTTF显示中文不会自动换行,看了下源码,原来底层的实现是根据text的空 ...

  6. Cocos2d-x项目移植到WP8系列之六:C#工程使用C++的DLL

    原文链接: http://www.cnblogs.com/zouzf/p/3984510.html 此时,一些大问题都被解决后,整个工程基本能跑起来了,最后一个大问题是:业务层是用Lua开发的,底层的 ...

  7. Cocos2d-x项目移植到WP8系列之四:文件操作

    原文链接: http://www.cnblogs.com/zouzf/p/3972457.html 读写文件Cocos已经用fopen fwrite来做好了,这里说的主要是文件和文件夹的创建.删除.判 ...

  8. Cocos2d-x项目移植到WP8系列之七:中文显示乱码

    原文链接:http://www.cnblogs.com/zouzf/p/3984628.html C++和C#互调时经常会带一些参数过去例如最常见的字符串,如果字符串里有中文的话,会发现传递过去后变成 ...

  9. Cocos2d-x项目移植到WP8小记

    Cocos2d-x项目移植到WP8小记 作者: K.C. 日期: 10/24/2013 Date: 2013-10-24 00:33 Title: Cocos2d-x项目移植到WP8小记 Tags: ...

随机推荐

  1. 安装Oracle后修改IP总结(转载)

    转载自:http://blog.csdn.net/bleibo/article/details/5447198 安装Oracle后修改IP总结(转载) 针对ORACLE 10G 在安装完后,修改IP ...

  2. WPF 属性系统 依赖属性之内存占用分析

    关于WPF的属性系统园子内有不少这方面的文章.里面大都提到了WPF依赖属性的在内存方面的优化.但是里面大都一笔带过.那么WPF到底是怎么样节约内存的.我们通过WPF属性和普通的CLR属性对比来看一下W ...

  3. python3----基础 用while循环+iter()+next() 实现对字符串的遍历与输出

    my_str = 'hello' # for循环 for v in my_str: print(v) # while 配合迭代器实现字符串的遍历 ite = iter(my_str) while Tr ...

  4. 怎样利用JDBC启动Oracle 自己主动追踪(auto trace)

    有时我们须要对运行SQL的详细运行过程做一个追踪分析,特别是在应用程序性能优化的时候.Oracle两个工具能够帮助我们做好性能分析,一个是SQL_TRACE,一个是SESSION_EVENT.SQL_ ...

  5. 49、android ListView几个比较特别的属性

    由于这两天在做listView的东西,所以整理出来一些我个人认为比较特别的属性,通过设置这样的属性可以做出更加美观的列表 android:stackFromBottom="true" ...

  6. Android自定义Button字体颜色和背景颜色

    http://blog.csdn.net/breeze666/article/details/7747649

  7. 创建String字符串的方式与区别

    Java中创建一个字符串的方式有很多种,常见如: String s = new String("riqi"); String s = "riqi"; 但两者有什 ...

  8. 小程序 less wxss 混合 Mixins picker样式优化 箭头样式的实现原理

    lessc src/style/picker-arrow_.less src/style/picker-arrow_.wxss 快速入门 | Less.js 中文文档 https://less.boo ...

  9. Navigation

    Makedown常用语法 1.常用标题 # 代表h1(一级标题) ## 代表h2(二级标题) ### 代表h3(三级标题) #### 代表h4(四级标题) ##### 代表h5(五级标题) ##### ...

  10. django项目部署在Apache服务器中,静态文件路径的注意点

    django Apache部署静态文件的路径注意点 静态文件放在对应的 app 下的 static 文件夹中 或者 STATICFILES_DIRS 中的文件夹中. 当 DEBUG = True 时, ...