rtoss - Blame information for rev 26

Subversion Repositories:
Rev:
Rev Author Line No. Line
14 roytam 1 #include <windows.h>
2 #include <math.h>
3 #include "maplay.h"
4 #include "helper.h"
5 #include "player.h"
6 #include "libovd.h"
7  
8 #define INITIAL_THREAD_PRIORITY         THREAD_PRIORITY_BELOW_NORMAL
9  
10 CPlayer::CPlayer() :
11 m_Echo(TRUE), m_Reverb(FALSE)
12 {
13         m_hwndMessage = NULL;
14         m_szFile[0] = NULL;
15  
16         m_dwThreadID = 0;
17         m_hThread = NULL;
18  
19         m_nDuration = 0;
20         m_nSeek = 0;
21         m_nWritten = 0;
22         m_fSuppress = FALSE;
23         m_Status = MAP_STATUS_STOP;
24         m_StreamingStatus = MAP_STREAMING_DISABLED;
25         memset(&m_Info, 0, sizeof(MPEG_AUDIO_INFO));
26  
27         m_fOpen = OPEN_NONE;
28         m_fStop = FALSE;
29  
30         m_Options.nThreadPriority = THREAD_PRIORITY_ABOVE_NORMAL;
31         m_Output.GetOutputParam((LPDWORD)&m_Options.nOutputBufferLen,
32                                                         &m_Options.fAlwaysOpenDevice, &m_Options.fFadeIn);
33         //m_Options.fAlwaysOpenDevice = TRUE;
26 roytam 34         m_Options.nOutputPrebuffer = 50;
14 roytam 35         m_Options.fScanMpegCompletely = FALSE;
36         m_Options.fFadeIn = FALSE;
37         m_Options.fSuppressZeroSamples = FALSE;
38  
39         m_pOutHdr = NULL;
40         m_cbOutBuf = 0;
41         m_cbOutBufLeft = 0;
42         m_fPlay = FALSE;
43         m_fSeek = FALSE;
44         m_fFileBegin = TRUE;
45  
46         m_Decoder.GetEqualizer(&m_Equalizer);
47         m_fPreamp = FALSE;
48         m_nPreamp = 31;
49         m_nPreampRate = PREAMP_FIXED_FLAT;
50  
51         m_hOvd = NULL;
52         m_pOvd_buf = NULL;
53         m_fNet = NET_OPEN_NONE;
54         m_szOvdTitle[0] = NULL;
55  
56         m_hAcm = NULL;
57         m_pwfxSrc = NULL;
58         m_pwfxDst = NULL;
59         m_llDataOffset = 0;
60         m_dwDataSize = 0;
61         m_dwCurrentSize = 0;
62  
63         PlugInLoad();
64 }
65  
66 CPlayer::~CPlayer()
67 {
68         Close();
69         m_Output.CloseAll();
70         PlugInFree();
71 }
72  
73 BOOL CPlayer::OpenFile(LPCTSTR pszFile)
74 {
75         CAutoLock lock(&m_csecInterface);
76         Close();
77  
78         m_fFileBegin = TRUE;
79  
80         // PlugIn
81         if (PlugInOpenFile(pszFile))
82                 return TRUE;
83  
84         // MPEG Audio
85         if (MpgOpenFile(pszFile))
86                 return TRUE;
87  
88         // Ogg Vorbis
89         if (OvOpenFile(pszFile))
90                 return TRUE;
91  
92         // Wave
93         if (WavOpenFile(pszFile))
94                 return TRUE;
95  
96         return FALSE;
97 }
98  
99 BOOL CPlayer::OpenURL(LPCTSTR pszURL)
100 {
101         CAutoLock lock(&m_csecInterface);
102         Close();
103  
104         if (!m_Receiver.Open(pszURL))
105                 return FALSE;
106  
107         m_fOpen = OPEN_URL;
108         m_StreamingStatus = MAP_STREAMING_DISCONNECTED;
109         return TRUE;
110 }
111  
112 void CPlayer::Close()
113 {
114         CAutoLock lock(&m_csecInterface);
115         Stop();
116  
117         PlugInClose();
118         MpgClose();
119         OvClose();
120         WavClose();
121         NetClose();
122  
123         memset(&m_Info, 0, sizeof(m_Info));
124         m_szFile[0] = NULL;
125         m_nDuration = 0;
126  
127         m_fOpen = OPEN_NONE;
128         m_StreamingStatus = MAP_STREAMING_DISABLED;
129 }
130  
131 BOOL CPlayer::Play()
132 {
133         CAutoLock lock(&m_csecInterface);
134         if (m_fOpen == OPEN_NONE)
135                 return FALSE;
136  
137         if (m_Status == MAP_STATUS_PAUSE) {
138                 Pause();
139                 return TRUE;
140         }
141         if (m_Status == MAP_STATUS_STOP) {
142                 m_hThread = CreateThread(NULL, 0, PlayerThreadProc, this, 0, &m_dwThreadID);
143                 return m_hThread != NULL;
144         }
145         return FALSE;
146 }
147  
148 void CPlayer::Pause()
149 {
150         CAutoLock lock(&m_csecInterface);
151         if (m_fOpen == OPEN_NONE)
152                 return;
153  
154         if (m_fOpen == OPEN_URL)
155                 return;
156  
157         if (m_Status == MAP_STATUS_PLAY) {
158                 UpdateStatus(MAP_STATUS_PAUSE);
159                 m_Output.Pause(TRUE);
160                 m_fPlay = FALSE;
161         }
162         else if (m_Status == MAP_STATUS_PAUSE) {
163                 if (m_Output.GetBufferingCount() == m_Output.GetBufferCount())
164                         m_Output.Pause(FALSE);
165                 else
166                         m_fPlay = TRUE;
167                 UpdateStatus(MAP_STATUS_PLAY);
168         }
169 }
170  
171 void CPlayer::Stop()
172 {
173         CAutoLock lock(&m_csecInterface);
174  
175         if (m_hThread) {
176                 m_fStop = TRUE;
177                 m_Receiver.Stop();
178                 m_Output.Reset();
179                 WaitForSingleObject(m_hThread, INFINITE);
180                 CloseHandle(m_hThread);
181                 m_hThread = NULL;
182         }
183  
184         m_nSeek = 0;
185         m_nWritten = 0;
186         m_fSuppress = FALSE;
187         m_fPlay = FALSE;
188         m_fStop = FALSE;
189         m_fSeek = FALSE;
190         Seek(0);
191 }
192  
193 BOOL CPlayer::Ff(long lSkip)
194 {
195         CAutoLock lock(&m_csecInterface);
196         if (m_fOpen == OPEN_NONE)
197                 return FALSE;
198  
199         LONG lTime = GetCurrent();
200         lTime += lSkip;
201         return Seek(lTime);
202 }
203  
204 BOOL CPlayer::Rew(long lSkip)
205 {
206         CAutoLock lock(&m_csecInterface);
207         if (m_fOpen == OPEN_NONE)
208                 return FALSE;
209  
210         LONG lTime = GetCurrent();
211         lTime -= lSkip;
212         return Seek(lTime);
213 }
214  
215 BOOL CPlayer::Seek(long lTime)
216 {
217         CAutoLock lock(&m_csecInterface);
218         CAutoLock lock2(&m_csecThread);
219         if (m_fOpen == OPEN_NONE)
220                 return FALSE;
221  
222         // 時間のチェック
223         if (lTime < 0)
224                 lTime = 0;
225         if (lTime >= int((double)m_nDuration / m_Info.nSamplingRate * 1000))
226                 return FALSE;
227  
228         BOOL fRet = FALSE;
229         if (m_fOpen == OPEN_PLUGIN)
230                 fRet = PlugInSeekFile(lTime);
231         else if (m_fOpen == OPEN_MPG_FILE)
232                 fRet = MpgSeekFile(lTime);
233         else if (m_fOpen == OPEN_OV_FILE)
234                 fRet = OvSeekFile(lTime);
235         else if (m_fOpen == OPEN_WAV_FILE)
236                 fRet = WavSeekFile(lTime);
237  
238         m_fFileBegin = m_nSeek == 0;
239         if (fRet) {
240                 m_nWritten = 0;
241                 m_fSuppress = FALSE;
242  
243                 SetThreadPriority(m_hThread, INITIAL_THREAD_PRIORITY);
244         }
245  
246         return fRet;
247 }
248  
249 void CPlayer::SetMessageWindow(HWND hwndMessage)
250 {
251         m_hwndMessage = hwndMessage;
252         m_Receiver.SetMessageWindow(hwndMessage);
253 }
254  
255 long CPlayer::GetCurrent()
256 {
257         CAutoLock lock(&m_csecInterface);
258         if (m_fOpen == OPEN_NONE)
259                 return 0;
260  
261         if (GetStatus() == MAP_STATUS_STOP)
262                 return (int)(((double)m_nSeek) * 1000 / m_Info.nSamplingRate);
263         else
264                 return (int)(((double)m_Output.GetCurrent() + m_nSeek) * 1000 / m_Info.nSamplingRate);
265 }
266  
267 long CPlayer::GetDuration()
268 {
269         if (m_fOpen == OPEN_NONE)
270                 return 0;
271  
272         return (int)((double)m_nDuration / m_Info.nSamplingRate * 1000);
273 }
274  
275 MAP_STATUS CPlayer::GetStatus()
276 {
277         return m_Status;
278 }
279  
280 void CPlayer::SetEqualizer(EQUALIZER* value)
281 {
282         m_Equalizer = *value;
283         m_Decoder.SetEqualizer(&m_Equalizer);
284  
285         m_fPreamp = value->fEnable;
286         m_nPreamp = value->preamp;
287         double dLevel = -((double)value->preamp - 31) * 20 / 31;
288         m_nPreampRate = (int)(pow(10, dLevel / 20) * PREAMP_FIXED_FLAT);
289  
290         PlugInSetEqualizer();
291 }
292  
293 void CPlayer::GetEqualizer(EQUALIZER* value)
294 {
295         *value = m_Equalizer;
296 }
297  
298 void CPlayer::SetEffect(int nEffect, EFFECT* value)
299 {
300         switch (nEffect) {
301         case EFFECT_REVERB:
302                 m_Reverb.SetParameter(value);
303                 break;
304         case EFFECT_ECHO:
305                 m_Echo.SetParameter(value);
306                 break;
307         case EFFECT_SURROUND:
308                 m_Surround.SetParameter(value);
309                 break;
310         case EFFECT_3DCHORUS:
311                 m_3DChorus.SetParameter(value);
312                 break;
313         }
314 }
315  
316 void CPlayer::GetEffect(int nEffect, EFFECT* value)
317 {
318         switch (nEffect) {
319         case EFFECT_REVERB:
320                 m_Reverb.GetParameter(value);
321                 break;
322         case EFFECT_ECHO:
323                 m_Echo.GetParameter(value);
324                 break;
325         case EFFECT_SURROUND:
326                 m_Surround.GetParameter(value);
327                 break;
328         case EFFECT_3DCHORUS:
329                 m_3DChorus.GetParameter(value);
330                 break;
331         }
332 }
333  
334 void CPlayer::SetBassBoostLevel(int nLevel)
335 {
336         m_BassBoost.SetLevel(nLevel);
337 }
338  
339 int CPlayer::GetBassBoostLevel()
340 {
341         return m_BassBoost.GetLevel();
342 }
343  
344 void CPlayer::GetFileInformation(MAP_INFORMATION* pInfo)
345 {
346         if (m_fOpen == OPEN_NONE)
347                 return;
348         pInfo->nBitRate = m_Info.nBitRate;
349         pInfo->nChannels = m_Info.nChannels;
350         pInfo->nLayer = m_Info.nLayer;
351         pInfo->nSamplingRate = m_Info.nSamplingRate;
352         pInfo->nVersion = m_Info.nVersion;
353         pInfo->nDuration = (int)((double)m_nDuration / m_Info.nSamplingRate * 1000);
354 }
355  
356 BOOL CPlayer::GetId3Tag(ID3TAGV1* pTag)
357 {
26 roytam 358         BOOL bRet;
14 roytam 359         if (m_fOpen == OPEN_MPG_FILE)
26 roytam 360                 bRet = MpgGetId3Tag(pTag);
14 roytam 361         else if (m_fOpen == OPEN_OV_FILE)
26 roytam 362                 bRet = OvGetId3Tag(pTag);
14 roytam 363         else if (m_fOpen == OPEN_PLUGIN)
26 roytam 364                 bRet = PlugInGetId3Tag(pTag);
14 roytam 365  
26 roytam 366         if (!bRet)
367                 bRet = ::GetId3Tag(m_szFile, pTag);
368  
369         return bRet;
14 roytam 370 }
371  
372 BOOL CPlayer::SetId3Tag(ID3TAGV1* pTag)
373 {
374         return FALSE; // not support
375 }
376  
377 BOOL CPlayer::GetStreamInfo(LPTSTR pszName, LPTSTR pszGenre, LPTSTR pszURL)
378 {
379         return m_Receiver.GetStreamInfo(pszName, pszGenre, pszURL);
380 }
381  
382 BOOL CPlayer::GetStreamTitle(LPTSTR pszTitle)
383 {
384         if (_tcslen(m_szOvdTitle)) {
385                 _tcscpy(pszTitle, m_szOvdTitle);
386                 return TRUE;
387         }
388  
389         return m_Receiver.GetStreamTitle(pszTitle);
390 }
391  
392 void CPlayer::GetOptions(MAP_OPTIONS* pOptions)
393 {
394         *pOptions = m_Options;
395 }
396  
397 BOOL CPlayer::SetOptions(MAP_OPTIONS* pOptions)
398 {
399         if (m_Status != MAP_STATUS_STOP)
400                 return FALSE;
401  
402         if (m_Options.nOutputPrebuffer < 0 || m_Options.nOutputPrebuffer > 100)
403                 return FALSE;
404  
405         if (pOptions->nOutputBufferLen == m_Options.nOutputBufferLen &&
406                 pOptions->fAlwaysOpenDevice == m_Options.fAlwaysOpenDevice &&
407                 pOptions->fFadeIn == m_Options.fFadeIn) {
408                 m_Options = *pOptions;
409                 return TRUE;
410         }
411  
412         m_Output.CloseAll();
413         if (!m_Output.SetOutputParam(pOptions->nOutputBufferLen,
414                                                         pOptions->fAlwaysOpenDevice, pOptions->fFadeIn))
415                 return FALSE;
416  
417         m_Options = *pOptions;
418         return TRUE;
419 }
420  
421 void CPlayer::GetStreamingOptions(MAP_STREAMING_OPTIONS* pOptions)
422 {
423         pOptions->nBuf = m_Receiver.GetBufferCount();
424         pOptions->nPreBuf = m_Receiver.GetPrebufferingCount();
425         pOptions->fUseProxy = m_Receiver.GetProxy(pOptions->szProxy);
426         m_Receiver.GetUserAgent(pOptions->szUserAgent);
427 }
428  
429 BOOL CPlayer::SetStreamingOptions(MAP_STREAMING_OPTIONS* pOptions)
430 {
431         if (!m_Receiver.SetBufferCount(pOptions->nBuf))
432                 return FALSE;
433  
434         int nPreBuf = pOptions->nPreBuf;
435         if (nPreBuf > pOptions->nBuf)
436                 nPreBuf = pOptions->nBuf;
437         m_Receiver.SetPrebufferingCount(nPreBuf);
438         m_Receiver.SetProxy(pOptions->fUseProxy, pOptions->szProxy);
439         m_Receiver.SetUserAgent(pOptions->szUserAgent);
440  
441         return TRUE;
442 }
443  
444 MAP_STREAMING_STATUS CPlayer::GetStreamingStatus()
445 {
446         return m_StreamingStatus;
447 }
448  
449 int CPlayer::GetStreamingBufferingCount()
450 {
451         if (m_StreamingStatus < MAP_STREAMING_CONNECTING)
452                 return 0;
453  
454         return m_Receiver.GetBufferingCount();
455 }
456  
457 // protected members
458  
459 void CPlayer::PostCallbackMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
460 {
461         PostMessage(m_hwndMessage, uMsg, wParam, lParam);
462 }
463  
464 void CPlayer::UpdateStatus(MAP_STATUS status, BOOL fError)
465 {
466         if (m_Status != status) {
467                 m_Status = status;
468                 PostCallbackMessage(MAP_MSG_STATUS, status, fError);
469         }
470 }
471  
472 void CPlayer::UpdatePeek()
473 {
474         PostCallbackMessage(MAP_MSG_PEEK, m_Output.m_nLPeek, m_Output.m_nRPeek);
475 }
476  
477 BOOL CPlayer::PreparePlayback()
478 {
479         if (m_fStop)
480                 return FALSE;
481  
482         CAutoLock lock(&m_csecInterface);
483  
484         int nBitsPerSample;
485         switch (m_fOpen) {
486         case OPEN_WAV_FILE:
487                 nBitsPerSample = m_pwfxDst->wBitsPerSample; break;
488         case OPEN_PLUGIN:
489                 nBitsPerSample = m_nPlugInBps; break;
490         default:
491                 nBitsPerSample = 16;
492         }
493  
494         if (!m_Output.Open(m_Info.nChannels, m_Info.nSamplingRate, nBitsPerSample))
495                 return FALSE;
496  
497         m_cbOutBuf = m_Output.GetBufferSize();
498         m_Output.Pause(TRUE);
499  
500         m_Decoder.Init();
501         m_BassBoost.Open(m_Info.nChannels, m_Info.nSamplingRate);
502         m_Echo.Open(m_Info.nChannels, m_Info.nSamplingRate);
503         m_Reverb.Open(m_Info.nChannels, m_Info.nSamplingRate);
504  
505         if (m_Info.nChannels == 2)
506                 m_3DChorus.Open(m_Info.nSamplingRate);
507  
508         m_fPlay = TRUE;
509         m_fStop = FALSE;
510         SetThreadPriority(m_hThread, INITIAL_THREAD_PRIORITY);
511  
512         return TRUE;
513 }
514  
515 BOOL CPlayer::UnpreparePlayback(BOOL fEos, BOOL fError)
516 {
517         if (fEos) {
518                 if (m_pOutHdr) {
519                         OutputBuffer(m_pOutHdr, m_cbOutBuf - m_cbOutBufLeft);
520                         m_pOutHdr = NULL;
521                         m_cbOutBufLeft = 0;
522                 }
523                 while (!m_Output.IsFlushed()) {
524                         if (m_fPlay && GetStatus() == MAP_STATUS_PLAY) {
525                                 m_Output.Pause(FALSE);
526                                 m_fPlay = FALSE;
527                         }
528                         Sleep(1);
529                         if (m_fSeek)
530                                 return FALSE;
531                         if (m_fStop)
532                                 break;
533                         UpdatePeek();
534                 }
535         }
536  
537         m_Output.Close();
538         m_Echo.Close();
539         m_Reverb.Close();
540         m_BassBoost.Close();
541         m_3DChorus.Close();
542         m_Decoder.Destroy();
543  
544         if (!m_Options.fAlwaysOpenDevice || fError)
545                 m_Output.CloseAll();
546  
547         if (m_fOpen == OPEN_URL) {
548                 m_Receiver.Disconnect();
549                 m_StreamingStatus = MAP_STREAMING_DISCONNECTED;
550         }
551  
552         m_pOutHdr = NULL;
553         m_cbOutBufLeft = 0;
554  
555         m_nSeek = 0;
556         m_fPlay = FALSE;
557         m_fStop = FALSE;
558         m_fSeek = FALSE;
559  
560         switch (m_fOpen) {
561         case OPEN_PLUGIN:
562                 PlugInStop(); break;
563         case OPEN_MPG_FILE:
564                 MpgStop(); break;
565         case OPEN_OV_FILE:
566                 OvStop(); break;
567         case OPEN_WAV_FILE:
568                 WavStop(); break;
569         case OPEN_URL:
570                 NetStop(); break;
571         }
572  
573         PostMessage(m_hwndMessage, MAP_MSG_PEEK, 0, 0);
574         UpdateStatus(MAP_STATUS_STOP, fError);
575         return TRUE;
576 }
577  
578 void CPlayer::OutputBuffer(WAVEHDR* pHdr, DWORD cbRecorded)
579 {
580         int nBitsPerSample;
581         switch (m_fOpen) {
582         case OPEN_WAV_FILE:
583                 nBitsPerSample = m_pwfxDst->wBitsPerSample; break;
584         case OPEN_PLUGIN:
585                 nBitsPerSample = m_nPlugInBps; break;
586         default:
587                 nBitsPerSample = 16;
588         }
589  
590         // 先頭の無音サンプルの除去
591         if (m_fOpen != OPEN_URL) {
592                 if (m_fFileBegin) {
593                         m_Output.SetFadeOff();
594                         if (m_Options.fSuppressZeroSamples) {
595                                 DWORD cb = m_Output.ScanZeroSamples(TRUE, (BYTE*)pHdr->lpData, cbRecorded);
596                                 if (cb == cbRecorded) {
597                                         pHdr->dwBytesRecorded = 0;
598                                         m_Output.OutputBuffer(pHdr);
599                                         m_nSeek += cb / (m_Info.nChannels * (nBitsPerSample / 8));
600 #ifdef _WIN32_WCE
601                                         Sleep(1);
602 #endif
603                                         return;
604                                 }
605                                 else {
606                                         cbRecorded -= cb;
607                                         memmove(pHdr->lpData, pHdr->lpData + cb, cbRecorded);
608                                         m_nSeek += cb / (m_Info.nChannels * (nBitsPerSample / 8));
609                                 }
610                         }
611                         m_fFileBegin = FALSE;
612                 }
613                 else {
614                         // ファイル末尾の無音の除去
615                         if (m_Options.fSuppressZeroSamples) {
616                                 if (m_fSuppress) {
617                                         pHdr->dwBytesRecorded = 0;
618                                         m_Output.OutputBuffer(pHdr);
619                                         return;
620                                 }
621  
622                                 if (m_nWritten + m_nSeek >= m_nDuration - (m_Info.nSamplingRate * 10)) { // 末[10秒に到達したか?
623                                         DWORD cb = m_Output.ScanZeroSamples(FALSE, (BYTE*)pHdr->lpData, cbRecorded);
624                                         if ((int)cb > m_Info.nChannels * m_Info.nSamplingRate * (nBitsPerSample / 8) / 100) { // 10ミリ秒以上無音があるか?
625                                                 cbRecorded -= cb;
626                                                 m_fSuppress = TRUE;
627                                         }
628                                 }
629                         }
630                 }
631         }
632  
633         pHdr->dwBufferLength = pHdr->dwBytesRecorded = cbRecorded;
634  
635         // エフェクトの処理
636         short* p = (short*)pHdr->lpData;
637         if (m_Info.nChannels == 2) {
638                 m_3DChorus.Process(nBitsPerSample, (LPBYTE)p, cbRecorded);
639                 m_Surround.Process(nBitsPerSample, p, cbRecorded);
640         }
641  
642         m_BassBoost.Process(nBitsPerSample, p, cbRecorded);
643         m_Echo.Process(nBitsPerSample, p, cbRecorded);
644         m_Reverb.Process(nBitsPerSample, p, cbRecorded);
645  
646         // ピ[クメ[タを更新
647         UpdatePeek();
648  
649         // 出力
650         m_Output.OutputBuffer(pHdr);
651         m_nWritten += pHdr->dwBytesRecorded / (nBitsPerSample / 8 * m_Info.nChannels);
652  
653         // 再生開始通知
654         if (m_fPlay && GetStatus() == MAP_STATUS_PLAY) {
655                 if ((int)m_Output.GetBufferingSamples() >=
656                         ((m_Info.nSamplingRate * m_Options.nOutputBufferLen) / 1000) * m_Options.nOutputPrebuffer / 100) {
657                         m_Output.Pause(FALSE);
658                         m_fPlay = FALSE;
659  
660                         ::SetThreadPriority(m_hThread, m_Options.nThreadPriority);
661                 }
662                 else if (m_Output.GetBufferingCount() == m_Output.GetBufferCount()) {
663                         m_Output.Pause(FALSE);
664                         m_fPlay = FALSE;
665  
666                         ::SetThreadPriority(m_hThread, m_Options.nThreadPriority);
667                 }
668         }
669 }
670  
671 void CPlayer::AudioDeviceClose()
672 {
673         if (m_Status != MAP_STATUS_STOP)
674                 Stop();
675  
676         m_Output.CloseAll();
677 }
678  
679 void CPlayer::GetBufferInfo(DWORD* pcbTotalAudio, DWORD* pcbBufferedAudio,
680                                                         DWORD* pcbTotalStream, DWORD* pcbBufferedStream)
681 {
682         m_Output.GetBufferInfo(pcbTotalAudio, pcbBufferedAudio);
683         m_Receiver.GetBufferInfo(pcbTotalStream, pcbBufferedStream);
684 }
685  
686 BOOL CPlayer::WaitForPrebuffering(int nBuffering)
687 {
688         if (!nBuffering)
689                 nBuffering = m_Receiver.GetPrebufferingCount();
690  
691         while (TRUE) {
692                 if (m_fStop)
693                         return FALSE;
694                 if (!m_Receiver.IsConnected())
695                         return m_Receiver.IsEos() ? TRUE : FALSE;
696  
697                 if (m_Receiver.GetBufferingCount() >= nBuffering)
698                         return TRUE;
699  
700                 Sleep(1);
701         }
702 }
703  
704 void CPlayer::Preamp(LPBYTE pbBuf, DWORD cbBuf)
705 {
706         if (m_fPreamp)
707                 m_Output.Preamp(pbBuf, cbBuf, m_nPreampRate);
708 }
709  
710 DWORD WINAPI CPlayer::PlayerThreadProc(LPVOID pParam)
711 {
712         CPlayer* pPlayer = (CPlayer*)pParam;
713  
714         if (pPlayer->m_fOpen == OPEN_URL)
715                 pPlayer->NetStreamingThread();
716         else
717                 pPlayer->FilePlayerThread();
718  
719         return 0;
720 }
721  
722 void CPlayer::FilePlayerThread()
723 {
724         int nRet = RET_ERROR;
725  
726         UpdateStatus(MAP_STATUS_WAIT);
727         if (!PreparePlayback()) {
728                 UnpreparePlayback(FALSE, TRUE);
729                 return;
730         }
731         UpdateStatus(MAP_STATUS_PLAY);
732  
733 retry:
734         switch (m_fOpen) {
735         case OPEN_PLUGIN:
736                 nRet = PlugInPlayerThread(); break;
737         case OPEN_MPG_FILE:
738                 nRet = MpgPlayerThread(); break;
739         case OPEN_OV_FILE:
740                 nRet = OvPlayerThread(); break;
741         case OPEN_WAV_FILE:
742                 nRet = WavPlayerThread(); break;
743         }
744  
745         switch (nRet) {
746         case RET_EOF:
747                 if (!UnpreparePlayback(TRUE))
748                         goto retry;
749                 break;
750         case RET_STOP:
751                 UnpreparePlayback();
752                 break;
753         case RET_ERROR:
754                 UnpreparePlayback(FALSE, TRUE);
755                 break;
756         }
757 }
26 roytam 758  
759 DWORD CPlayer::GetVolume(BOOL bSysVolume)
760 {
761         DWORD dwVolume = 0;
762         if (bSysVolume) {
763                 waveOutGetVolume(NULL, &dwVolume);
764                 return dwVolume;
765         }
766         else {
767                 return m_Output.GetVolume();
768         }
769 }
770  
771 void CPlayer::SetVolume(DWORD dwVolume, BOOL bSysVolume)
772 {
773         if (bSysVolume) {
774                 waveOutSetVolume(NULL, dwVolume);
775         }
776         else {
777                 m_Output.SetVolume(dwVolume);
778         }
779 }