首页 > 代码库 > Cocos2d-x项目移植到WP8系列之五:播放MP3
Cocos2d-x项目移植到WP8系列之五:播放MP3
这一块的细节还是不太了解,只是东凑西拼能跑起来而已
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; 这句代码之前的代码改成如下:
1 if (m_engineExperiencedCriticalError) { 2 return; 3 } 4 5 std::string path(pszFilePath); 6 7 int sound = Hash(pszFilePath); 8 9 MediaStreamer mediaStreamer;10 11 12 // no MP3 support for CC_PLATFORM_WP813 std::string::size_type pos = path.find(".mp3");14 if (pos != path.npos)15 {16 //path.replace(pos, path.length(), ".wav");17 18 mediaStreamer.Initialize_MP3(CCUtf8ToUnicode(pszFilePath).c_str());19 }20 else21 {22 mediaStreamer.Initialize(CCUtf8ToUnicode(pszFilePath).c_str());23 }24 25 26 // mediaStreamer.Initialize(CCUtf8ToUnicode(pszFilePath).c_str());27 m_soundEffects[sound].m_soundID = sound;
3、CocosDenshion工程里的MediaStreamer类加多一个方法:void MediaStreamer::Initialize_MP3(__in const WCHAR* url),实现如下:
1 void MediaStreamer::Initialize_MP3(__in const WCHAR* url) 2 { 3 4 WCHAR filePath[MAX_PATH] = {0}; 5 if ((wcslen(url) > 1 && url[1] == ‘:‘)) 6 { 7 // path start with "x:", is absolute path 8 wcscat_s(filePath, url); 9 } 10 else if (wcslen(url) > 0 11 && (L‘/‘ == url[0] || L‘\\‘ == url[0])) 12 { 13 // path start with ‘/‘ or ‘\‘, is absolute path without driver name 14 wcscat_s(filePath, m_locationPath->Data()); 15 // remove ‘/‘ or ‘\\‘ 16 wcscat_s(filePath, (const WCHAR*)url[1]); 17 }else 18 { 19 wcscat_s(filePath, m_locationPath->Data()); 20 wcscat_s(filePath, url); 21 } 22 23 24 hip_t hip = hip_decode_init(); 25 if (!hip) 26 { 27 printf("创建mp3解码失败"); 28 return ; 29 } 30 31 mp3data_struct mp3str;//mp3文件编码信息 32 std::vector<short*> mp3Buffer;// mp3数据流 33 std::vector<int> mp3BufferSize; 34 35 int samples; 36 int mp3_bytes; 37 int write_bytes = 0; 38 39 const int BUF_SIZE = 512; 40 const int INBUF_SIZE = 4096; 41 const int MP3BUF_SIZE = (int)(1.25 * BUF_SIZE) + 7200; 42 43 short pcm_l[INBUF_SIZE]; 44 short pcm_r[INBUF_SIZE]; 45 unsigned char mp3_buf[MP3BUF_SIZE]; 46 47 FILE * MP3File; 48 49 50 std::wstring wstr = std::wstring(filePath); 51 // return std::string(wstr.begin(),wstr.end()); 52 53 std::string str_filePath = std::string(wstr.begin(),wstr.end());//"C:\\Data\\Programs\\{4AE99D96-62EE-4A1C-A345-F1B0A81D07BC}\\Install\\Assets\\Resources\\islandbg.mp3"; 54 55 56 auto error = fopen_s(&MP3File, str_filePath.c_str(), "rb"); 57 mp3data_struct mp3Header; 58 59 while ((mp3_bytes = fread(mp3_buf, 1, 210, MP3File)) > 0) 60 { 61 samples = hip_decode_headers(hip, mp3_buf, 210, pcm_l, pcm_r, &mp3Header); 62 if (samples > 0) 63 { 64 short *tt = new short[samples*sizeof(short)]; 65 memcpy((void*)tt, (const void*)pcm_l, samples*sizeof(short)); 66 mp3Buffer.push_back(tt); 67 write_bytes += samples*sizeof(short); 68 mp3BufferSize.push_back(samples*sizeof(short)); 69 //write_bytes = fwrite(pcm_l, sizeof(short), samples, wavfp); 70 } 71 } 72 73 74 byte* _mp3Buffer = new byte[write_bytes]; 75 byte* temp = _mp3Buffer; 76 int size = mp3BufferSize.size(); 77 for(int i=0;i<size;i++) 78 { 79 memcpy(temp, mp3Buffer[i],mp3BufferSize[i]); 80 delete mp3Buffer[i]; 81 temp += mp3BufferSize[i]; 82 } 83 mp3Buffer.clear(); 84 hip_decode_exit(hip); 85 //m_soundEffects[sound].m_soundEffectBufferData 86 87 m_data.resize(write_bytes); 88 for(int i=0;i<write_bytes;i++) 89 { 90 m_data[i]=_mp3Buffer[i]; 91 } 92 93 fclose(MP3File); 94 95 96 97 m_waveFormat.wFormatTag = WAVE_FORMAT_PCM; //固定 98 m_waveFormat.nChannels = 1; //固定 99 m_waveFormat.nSamplesPerSec = (DWORD) mp3Header.samplerate;// 固定 100 101 m_waveFormat.wBitsPerSample = 16;// mp3Header.bitrate * m_waveFormat.nChannels / 8; 102 //m_waveFormat.wBitsPerSample = mp3Header.bitrate * m_waveFormat.nChannels / 8.0; 103 m_waveFormat.nBlockAlign = m_waveFormat.nChannels * m_waveFormat.wBitsPerSample / 8.0; 104 m_waveFormat.nAvgBytesPerSec = m_waveFormat.nSamplesPerSec * m_waveFormat.nBlockAlign; //越大越快105 m_waveFormat.cbSize = 0;106 107 }
完成。
大概流程就是,通过lamb的两个lib库的方法,读取MP3文件的流构建成wav文件格式的流,重点在于通过MP3的文件头信息mp3data_struct 构建出 wav文件的文件头信息WAVEFORMATEX。
另外,因为只读取了一个声道的流,所以m_waveFormat.nChannels = 1;如果对声道有要求的,可以在while循环里把右声道的流也处理一下。
附上一些参考文章: lame mp3解码 Suche MP3 to WAV decoder
Cocos2d-x项目移植到WP8系列之五:播放MP3
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。