xref: /MusicPlayer2/MusicPlayer2/MciCore.cpp (revision 8959a120c2c1a8b30f887255062f37449f37dee8)
1 #include "stdafx.h"
2 #include "MciCore.h"
3 #include "AudioCommon.h"
4 #include "MusicPlayer2.h"
5 #include "AudioTag.h"
6 #include "FilePathHelper.h"
7 
8 
CMciCore()9 CMciCore::CMciCore()
10 {
11     CDllLib::Init(L"winmm.dll");
12 
13     if (!IsSucceed())
14     {
15         const wstring& info = theApp.m_str_table.LoadText(L"LOG_MCI_INIT_FAILED");
16         theApp.WriteLog(info);
17     }
18 }
19 
20 
~CMciCore()21 CMciCore::~CMciCore()
22 {
23     //if (m_dll_module != NULL)
24     //{
25     //    FreeLibrary(m_dll_module);
26     //    m_dll_module = NULL;
27     //}
28     CDllLib::UnInit();
29 }
30 
GetFunction()31 bool CMciCore::GetFunction()
32 {
33     bool rtn = true;
34     //获取函数入口
35     mciSendStringW = (_mciSendStringW)::GetProcAddress(m_dll_module, "mciSendStringW");
36     mciGetErrorStringW = (_mciGetErrorStringW)::GetProcAddress(m_dll_module, "mciGetErrorStringW");
37     //判断是否成功
38     rtn &= (mciSendStringW != NULL);
39     rtn &= (mciGetErrorStringW != NULL);
40     return rtn;
41 }
42 
InitCore()43 void CMciCore::InitCore()
44 {
45     //向支持的文件列表插入原生支持的文件格式
46     CAudioCommon::m_surpported_format.clear();
47     SupportedFormat format;
48     format.description = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_BASE");
49     format.extensions.push_back(L"mp3");
50     format.extensions.push_back(L"wma");
51     format.extensions.push_back(L"wav");
52     format.extensions.push_back(L"mid");
53     format.extensions_list = L"*.mp3;*.wma;*.wav;*.mid";
54     CAudioCommon::m_surpported_format.push_back(format);
55     CAudioCommon::m_all_surpported_extensions = format.extensions;
56 
57 }
58 
UnInitCore()59 void CMciCore::UnInitCore()
60 {
61     Stop();
62     Close();
63 }
64 
GetAudioType()65 std::wstring CMciCore::GetAudioType()
66 {
67     return std::wstring();
68 }
69 
GetChannels()70 int CMciCore::GetChannels()
71 {
72     return 0;
73 }
74 
GetFReq()75 int CMciCore::GetFReq()
76 {
77     return 0;
78 }
79 
GetSoundFontName()80 wstring CMciCore::GetSoundFontName()
81 {
82     return wstring();
83 }
84 
Open(const wchar_t * file_path)85 void CMciCore::Open(const wchar_t * file_path)
86 {
87     m_file_path = file_path;
88     CFilePathHelper path_helper{ file_path };
89     m_file_type = path_helper.GetFileExtension();
90     if(m_success)
91     {
92         m_error_code = mciSendStringW((L"open \"" + m_file_path + L"\"").c_str(), NULL, 0, 0);
93 
94         //获取MIDI信息
95         if (IsMidi())
96         {
97             wchar_t buff[16];
98             m_error_code = mciSendStringW((L"status \"" + m_file_path + L"\" length").c_str(), buff, 15, 0);
99             m_midi_info.midi_length = _wtoi(buff) / 4;
100             m_error_code = mciSendStringW((L"status \"" + m_file_path + L"\" tempo").c_str(), buff, 15, 0);
101             m_midi_info.speed = _wtoi(buff);
102             if(m_midi_info.speed > 0)
103                 m_midi_info.tempo = 60000000 / m_midi_info.speed;
104         }
105     }
106 
107 }
108 
Close()109 void CMciCore::Close()
110 {
111     if (m_success)
112     {
113         m_error_code = mciSendStringW((L"close \"" + m_file_path + L"\"").c_str(), NULL, 0, 0);
114         m_playing = PS_STOPED;
115     }
116 }
117 
Play()118 void CMciCore::Play()
119 {
120     if (m_success)
121     {
122         m_error_code = mciSendStringW((L"play \"" + m_file_path + L"\"").c_str(), NULL, 0, 0);
123         m_playing = PS_PLAYING;
124     }
125 }
126 
Pause()127 void CMciCore::Pause()
128 {
129     if (m_success)
130     {
131         m_error_code = mciSendStringW((L"pause \"" + m_file_path + L"\"").c_str(), NULL, 0, 0);
132         m_playing = PS_PAUSED;
133     }
134 }
135 
Stop()136 void CMciCore::Stop()
137 {
138     if (m_success)
139     {
140         m_error_code = mciSendStringW((L"stop \"" + m_file_path + L"\"").c_str(), NULL, 0, 0);
141         m_playing = PS_STOPED;
142         SetCurPosition(0);
143     }
144 }
145 
SetVolume(int volume)146 void CMciCore::SetVolume(int volume)
147 {
148     if (m_success && !IsMidi())
149     {
150         wchar_t buff[16];
151         _itow_s(volume * 10, buff, 10);		//设置音量100%时为1000
152         m_error_code = mciSendStringW((L"setaudio \"" + m_file_path + L"\" volume to " + buff).c_str(), NULL, 0, 0);
153     }
154 }
155 
SetSpeed(float speed)156 void CMciCore::SetSpeed(float speed)
157 {
158 }
159 
SetPitch(int pitch)160 void CMciCore::SetPitch(int pitch)
161 {
162 }
163 
SongIsOver()164 bool CMciCore::SongIsOver()
165 {
166     return false;
167 }
168 
GetCurPosition()169 int CMciCore::GetCurPosition()
170 {
171     if (m_success)
172     {
173         wchar_t buff[16];
174         m_error_code = mciSendStringW((L"status \"" + m_file_path + L"\" position").c_str(), buff, 15, 0);
175         int position = _wtoi(buff);
176         if(IsMidi())        //如果是MIDI,MCI获取到的长度并不是毫秒数,而是MIDI的节拍数
177         {
178             m_midi_info.midi_position = position / 4;
179             position = position * m_midi_info.speed;
180         }
181         return position;
182     }
183     return 0;
184 }
185 
GetSongLength()186 int CMciCore::GetSongLength()
187 {
188     if (m_success)
189     {
190         return GetMciSongLength(m_file_path);
191     }
192     return 1;
193 }
194 
SetCurPosition(int position)195 void CMciCore::SetCurPosition(int position)
196 {
197     if (m_success)
198     {
199         if (IsMidi())
200         {
201             if (m_midi_info.speed > 0)
202                 position = position / m_midi_info.speed;
203         }
204 
205         wchar_t buff[16];
206         _itow_s(position, buff, 10);
207         m_error_code = mciSendStringW((L"seek \"" + m_file_path + L"\" to " + buff).c_str(), NULL, 0, 0);		//定位到新的位置
208         if (m_playing)
209             m_error_code = mciSendStringW((L"play \"" + m_file_path + L"\"").c_str(), NULL, 0, 0);		//继续播放
210 
211     }
212 }
213 
GetAudioInfo(SongInfo & song_info,int flag)214 void CMciCore::GetAudioInfo(SongInfo & song_info, int flag)
215 {
216     if (m_success)
217     {
218         if (flag&AF_LENGTH)
219             song_info.end_pos.fromInt(GetMciSongLength(song_info.file_path));
220         if (flag&AF_BITRATE)
221             song_info.bitrate = GetMciBitrate(song_info.file_path);
222         if (flag&AF_TAG_INFO)
223         {
224             CAudioTag audio_tag(song_info);
225             audio_tag.GetAudioTag();
226             audio_tag.GetAudioRating();
227         }
228     }
229 
230 }
231 
GetAudioInfo(const wchar_t * file_path,SongInfo & song_info,int flag)232 void CMciCore::GetAudioInfo(const wchar_t * file_path, SongInfo & song_info, int flag)
233 {
234     if (m_success && ((flag&AF_LENGTH) || (flag&AF_BITRATE)))
235     {
236         m_error_code = mciSendStringW((L"open \"" + wstring(file_path) + L"\"").c_str(), NULL, 0, 0);
237         if (flag&AF_LENGTH)
238         {
239             wchar_t buff[16];
240             m_error_code = mciSendStringW((L"status \"" + wstring(file_path) + L"\" length").c_str(), buff, 15, 0);		//获取当前歌曲的长度,并储存在buff数组里
241             song_info.end_pos.fromInt(_wtoi(buff));
242         }
243         if (flag&AF_BITRATE)
244             song_info.bitrate = GetMciBitrate(file_path);
245         if (flag&AF_TAG_INFO)
246         {
247             CAudioTag audio_tag(song_info);
248             audio_tag.GetAudioTag();
249             audio_tag.GetAudioRating();
250         }
251 
252         m_error_code = mciSendStringW((L"close \"" + wstring(file_path) + L"\"").c_str(), NULL, 0, 0);
253     }
254 }
255 
IsMidi()256 bool CMciCore::IsMidi()
257 {
258     return m_file_type==L"mid" || m_file_type == L"midi";
259 }
260 
IsMidiConnotPlay()261 bool CMciCore::IsMidiConnotPlay()
262 {
263     return false;
264 }
265 
GetMidiInnerLyric()266 std::wstring CMciCore::GetMidiInnerLyric()
267 {
268     return std::wstring();
269 }
270 
GetMidiInfo()271 MidiInfo CMciCore::GetMidiInfo()
272 {
273     return m_midi_info;
274 }
275 
MidiNoLyric()276 bool CMciCore::MidiNoLyric()
277 {
278     return true;
279 }
280 
GetPlayingState()281 PlayingState CMciCore::GetPlayingState()
282 {
283     return m_playing;
284 }
285 
ApplyEqualizer(int channel,int gain)286 void CMciCore::ApplyEqualizer(int channel, int gain)
287 {
288 }
289 
SetReverb(int mix,int time)290 void CMciCore::SetReverb(int mix, int time)
291 {
292 }
293 
ClearReverb()294 void CMciCore::ClearReverb()
295 {
296 }
297 
GetFFTData(float fft_data[FFT_SAMPLE])298 void CMciCore::GetFFTData(float fft_data[FFT_SAMPLE])
299 {
300     memset(fft_data, 0, sizeof(fft_data));
301 }
302 
GetErrorCode()303 int CMciCore::GetErrorCode()
304 {
305     return m_error_code;
306 }
307 
GetErrorInfo(int error_code)308 std::wstring CMciCore::GetErrorInfo(int error_code)
309 {
310     wchar_t buff[128]{};
311     mciGetErrorStringW(error_code, buff, sizeof(buff) / sizeof(wchar_t));		//根据错误代码获取错误信息
312     return L"MCI: " + wstring(buff) + m_file_path;
313 }
314 
GetErrorInfo()315 std::wstring CMciCore::GetErrorInfo()
316 {
317     wchar_t buff[128]{};
318     mciGetErrorStringW(m_error_code, buff, sizeof(buff) / sizeof(wchar_t));
319     return buff;
320 }
321 
EncodeAudio(SongInfo song_info,const wstring & dest_file_path,EncodeFormat encode_format,void * encode_para,int dest_freq,EncodeAudioProc proc)322 bool CMciCore::EncodeAudio(SongInfo song_info, const wstring& dest_file_path, EncodeFormat encode_format, void* encode_para, int dest_freq, EncodeAudioProc proc)
323 {
324     return false;
325 }
326 
InitEncoder()327 bool CMciCore::InitEncoder()
328 {
329     return false;
330 }
331 
UnInitEncoder()332 void CMciCore::UnInitEncoder()
333 {
334 }
335 
IsFreqConvertAvailable()336 bool CMciCore::IsFreqConvertAvailable()
337 {
338     return false;
339 }
340 
GetMidiPosition()341 void CMciCore::GetMidiPosition()
342 {
343     if (IsMidi())
344     {
345         wchar_t buff[16];
346         m_error_code = mciSendStringW((L"status \"" + m_file_path + L"\" position").c_str(), buff, 15, 0);
347         m_midi_info.midi_position = _wtoi(buff) / 4;
348     }
349 }
350 
GetMciSongLength(const std::wstring & file_path)351 int CMciCore::GetMciSongLength(const std::wstring& file_path)
352 {
353     wchar_t buff[16];
354     m_error_code = mciSendStringW((L"status \"" + file_path + L"\" length").c_str(), buff, 15, 0);		//获取当前歌曲的长度,并储存在buff数组里
355     int length = _wtoi(buff);
356     if (IsMidi())
357     {
358         m_midi_info.midi_length = length / 4;
359         if (m_midi_info.speed > 0)
360             length = length * m_midi_info.speed;
361     }
362     return length;
363 }
364 
GetMciBitrate(const std::wstring & file_path)365 int CMciCore::GetMciBitrate(const std::wstring & file_path)
366 {
367     wchar_t buff[16];
368     m_error_code = mciSendStringW((L"status \"" + file_path + L"\" bytespersec").c_str(), buff, 15, 0);
369     int bitrate = _wtoi(buff);
370     bitrate = bitrate * 8 / 1000;
371     return bitrate;
372 }
373