]> git.saurik.com Git - wxWidgets.git/blob - contrib/samples/mmedia/mmbman.cpp
fixed deadlock when calling wxPostEvent() from worker thread
[wxWidgets.git] / contrib / samples / mmedia / mmbman.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: mmbman.cpp
3 // Purpose: Multimedia Board manager
4 // Author: Guilhem Lavaux, <guilhem.lavaux@libertysurf.fr>
5 // Modified by:
6 // Created: 13/02/2000
7 // RCS-ID: $Id$
8 // Copyright: (c) 2000, Guilhem Lavaux
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ----------------------------------------------------------------------------
13 // headers
14 // ----------------------------------------------------------------------------
15
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 // for all others, include the necessary headers (this file is usually all you
24 // need because it includes almost all "standard" wxWidgets headers
25 #ifndef WX_PRECOMP
26 #include "wx/wx.h"
27 #endif
28
29 // Personal headers
30
31 #include "wx/stream.h"
32 #include "wx/wfstream.h"
33
34 #include "wx/mmedia/sndbase.h"
35 #include "wx/mmedia/sndfile.h"
36 #include "wx/mmedia/sndwav.h"
37 #include "wx/mmedia/sndaiff.h"
38 #include "wx/mmedia/sndpcm.h"
39 #include "wx/mmedia/sndulaw.h"
40 #include "wx/mmedia/sndmsad.h"
41
42 #ifdef __UNIX__
43 #include "wx/mmedia/sndoss.h"
44 #include "wx/mmedia/sndesd.h"
45 #endif
46
47 #ifdef __WIN32__
48 #include "wx/mmedia/sndwin.h"
49 #endif
50
51 #include "wx/mmedia/vidbase.h"
52 #ifdef __UNIX__
53 #include "wx/mmedia/vidxanm.h"
54 #endif
55
56 #ifdef __WIN32__
57 #include "wx/mmedia/vidwin.h"
58 #endif
59
60 #include "mmboard.h"
61 #include "mmbman.h"
62
63 // ----------------------------------------------------------------------------
64 // Private class definitions
65 // ----------------------------------------------------------------------------
66
67 class MMBoardSoundFile: public MMBoardFile {
68 public:
69 MMBoardSoundFile(const wxString& filename);
70 ~MMBoardSoundFile();
71
72 bool NeedWindow();
73
74 void SetWindow(wxWindow *window);
75
76 void Play();
77 void Pause();
78 void Resume();
79 void Stop();
80
81 MMBoardTime GetPosition();
82 MMBoardTime GetLength();
83 void SetPosition(MMBoardTime btime);
84
85 bool IsStopped();
86 bool IsPaused();
87
88 wxString GetStringType();
89 wxString GetStringInformation();
90
91 protected:
92 wxSoundFileStream *GetDecoder();
93
94 wxSoundStream *m_output_stream;
95 wxInputStream *m_input_stream;
96 wxSoundFileStream *m_file_stream;
97
98 MMBoardTime m_length;
99 wxUint8 m_file_type;
100 };
101
102 class MMBoardVideoFile: public MMBoardFile {
103 public:
104 MMBoardVideoFile(const wxString& filename);
105 ~MMBoardVideoFile();
106
107 bool NeedWindow();
108
109 void SetWindow(wxWindow *window);
110
111 void Play();
112 void Pause();
113 void Resume();
114 void Stop();
115
116 MMBoardTime GetPosition();
117 MMBoardTime GetLength();
118 void SetPosition(MMBoardTime btime);
119
120 bool IsStopped();
121 bool IsPaused();
122
123 wxString GetStringType();
124 wxString GetStringInformation();
125
126 protected:
127 wxWindow *m_output_window;
128 wxVideoBaseDriver *m_video_driver;
129 };
130
131 // ----------------------------------------------------------------------------
132 // Implementation
133 // ----------------------------------------------------------------------------
134
135 #define MMBoard_UNKNOWNTYPE 0
136 #define MMBoard_WAVE 1
137 #define MMBoard_AIFF 2
138
139 // ----------------------------------------------------------------------------
140 // MMBoardSoundFile
141
142 MMBoardSoundFile::MMBoardSoundFile(const wxString& filename)
143 : MMBoardFile()
144 {
145 m_input_stream = new wxFileInputStream(filename);
146 m_output_stream = MMBoardManager::OpenSoundStream();
147
148 m_file_stream = GetDecoder();
149
150 if (!m_file_stream) {
151 SetError(MMBoard_UnknownFile);
152 return;
153 }
154
155 // Compute length
156 wxUint32 length, seconds;
157
158 length = m_file_stream->GetLength();
159 seconds = m_file_stream->GetSoundFormat().GetTimeFromBytes(length);
160 m_length.seconds = seconds % 60;
161 m_length.minutes = (seconds / 60) % 60;
162 m_length.hours = seconds / 3600;
163 }
164
165 MMBoardSoundFile::~MMBoardSoundFile()
166 {
167 if (m_file_stream)
168 delete m_file_stream;
169 MMBoardManager::UnrefSoundStream(m_output_stream);
170 delete m_input_stream;
171 }
172
173 wxSoundFileStream *MMBoardSoundFile::GetDecoder()
174 {
175 wxSoundFileStream *f_stream;
176
177 // First, we try a Wave decoder
178 f_stream = new wxSoundWave(*m_input_stream, *m_output_stream);
179 m_file_type = MMBoard_WAVE;
180 if (f_stream->CanRead())
181 return f_stream;
182 delete f_stream;
183
184 // Then, a AIFF decoder
185 f_stream = new wxSoundAiff(*m_input_stream, *m_output_stream);
186 m_file_type = MMBoard_AIFF;
187 if (f_stream->CanRead())
188 return f_stream;
189 delete f_stream;
190
191 m_file_type = MMBoard_UNKNOWNTYPE;
192
193 // TODO: automate
194
195 return NULL;
196 }
197
198 MMBoardTime MMBoardSoundFile::GetLength()
199 {
200 return m_length;
201 }
202
203 bool MMBoardSoundFile::IsStopped()
204 {
205 return m_file_stream->IsStopped();
206 }
207
208 bool MMBoardSoundFile::IsPaused()
209 {
210 return m_file_stream->IsPaused();
211 }
212
213 MMBoardTime MMBoardSoundFile::GetPosition()
214 {
215 wxUint32 length, seconds;
216 MMBoardTime file_time;
217
218 file_time.seconds = file_time.minutes = file_time.hours = 0;
219 if (m_file_stream->IsStopped())
220 return file_time;
221
222 length = m_file_stream->GetPosition();
223 seconds = m_file_stream->GetSoundFormat().GetTimeFromBytes(length);
224 file_time.seconds = seconds % 60;
225 file_time.minutes = (seconds / 60) % 60;
226 file_time.hours = seconds / 3600;
227
228 return file_time;
229 }
230
231 void MMBoardSoundFile::SetPosition(MMBoardTime btime)
232 {
233 wxUint32 itime;
234
235 itime = btime.seconds + btime.minutes * 60 + btime.hours;
236
237 m_file_stream->SetPosition(
238 m_file_stream->GetSoundFormat().GetBytesFromTime(itime)
239 );
240 }
241
242 bool MMBoardSoundFile::NeedWindow()
243 {
244 return false;
245 }
246
247 void MMBoardSoundFile::SetWindow(wxWindow *WXUNUSED(window))
248 {
249 }
250
251 void MMBoardSoundFile::Play()
252 {
253 m_file_stream->Play();
254 }
255
256 void MMBoardSoundFile::Pause()
257 {
258 m_file_stream->Pause();
259 }
260
261 void MMBoardSoundFile::Resume()
262 {
263 m_file_stream->Resume();
264 }
265
266 void MMBoardSoundFile::Stop()
267 {
268 m_file_stream->Stop();
269 }
270
271 wxString MMBoardSoundFile::GetStringType()
272 {
273 switch (m_file_type) {
274 case MMBoard_WAVE:
275 return wxString(wxT("WAVE file"));
276 #if 0
277 // break is not reachable after return
278 break;
279 #endif
280 case MMBoard_AIFF:
281 return wxString(wxT("AIFF file"));
282 #if 0
283 // break is not reachable after return
284 break;
285 #endif
286 #if 0
287 // default moved outside switch for those compilers
288 // which complain about lack of return in function
289 default:
290 return wxString(wxT("Unknown file"));
291 break;
292 #endif
293 }
294 return wxString(wxT("Unknown file"));
295 }
296
297 wxString MMBoardSoundFile::GetStringInformation()
298 {
299 wxString info;
300 wxSoundFormatBase *format;
301
302 format = &(m_file_stream->GetSoundFormat());
303
304 info = wxT("Data encoding: ");
305 switch (format->GetType()) {
306 case wxSOUND_PCM: {
307 wxSoundFormatPcm *pcm_format = (wxSoundFormatPcm *)format;
308
309 info += wxString::Format(wxT("PCM %s %s\n"),
310 pcm_format->Signed() ? wxT("signed") : wxT("unsigned"),
311 pcm_format->GetOrder() == wxLITTLE_ENDIAN ? wxT("little endian") : wxT("big endian"));
312 info += wxString::Format(wxT("Sampling rate: %d\n")
313 wxT("Bits per sample: %d\n")
314 wxT("Number of channels: %d\n"),
315 pcm_format->GetSampleRate(),
316 pcm_format->GetBPS(),
317 pcm_format->GetChannels());
318
319 break;
320 }
321 case wxSOUND_MSADPCM: {
322 wxSoundFormatMSAdpcm *adpcm_format = (wxSoundFormatMSAdpcm *)format;
323
324 info += wxString::Format(wxT("Microsoft ADPCM\n"));
325 info += wxString::Format(wxT("Sampling Rate: %d\n")
326 wxT("Number of channels: %d\n"),
327 adpcm_format->GetSampleRate(),
328 adpcm_format->GetChannels());
329 break;
330 }
331 case wxSOUND_ULAW: {
332 wxSoundFormatUlaw *ulaw_format = (wxSoundFormatUlaw *)format;
333 info += wxT("ULAW\n");
334 info += wxString::Format(wxT("Sampling rate: %d\n"), ulaw_format->GetSampleRate());
335 break;
336 }
337 default:
338 info += wxT("Unknown");
339 break;
340 }
341 return info;
342 }
343
344 // ----------------------------------------------------------------------------
345
346
347 // ----------------------------------------------------------------------------
348 // MMBoardVideoFile
349
350 MMBoardVideoFile::MMBoardVideoFile(const wxString& filename)
351 {
352 m_output_window = NULL;
353
354 #if defined(__UNIX__) && !defined(__CYGWIN__)
355 m_video_driver = new wxVideoXANIM(filename);
356 #elif defined(__WINDOWS__) && !defined(__MINGW32__) && !defined(__WATCOMC__) && !defined(__CYGWIN__)
357 // versions of Open Watcom and MinGW tested against this source does not
358 // deliver "digitalv.h" required in this feature
359 m_video_driver = new wxVideoWindows(filename);
360 #else
361 wxUnusedVar(filename);
362 m_video_driver = NULL;
363 SetError(MMBoard_UnknownFile);
364 #endif
365 }
366
367 MMBoardVideoFile::~MMBoardVideoFile()
368 {
369 if (m_video_driver)
370 delete m_video_driver;
371 }
372
373 bool MMBoardVideoFile::NeedWindow()
374 {
375 return true;
376 }
377
378 void MMBoardVideoFile::SetWindow(wxWindow *window)
379 {
380 m_output_window = window;
381 m_video_driver->AttachOutput(*window);
382
383 wxSize size;
384 m_video_driver->GetSize(size);
385 window->SetSize(size);
386 // BAD BAD
387 // and we remove
388 // window->GetParent()->GetSizer()->Fit(window->GetParent());
389 }
390
391 void MMBoardVideoFile::Play()
392 {
393 m_video_driver->Play();
394 }
395
396 void MMBoardVideoFile::Pause()
397 {
398 m_video_driver->Pause();
399 }
400
401 void MMBoardVideoFile::Resume()
402 {
403 m_video_driver->Resume();
404 }
405
406 void MMBoardVideoFile::Stop()
407 {
408 m_video_driver->Stop();
409 }
410
411 MMBoardTime MMBoardVideoFile::GetPosition()
412 {
413 MMBoardTime btime;
414
415 btime.seconds = btime.minutes = btime.hours = 0;
416 return btime;
417 }
418
419 MMBoardTime MMBoardVideoFile::GetLength()
420 {
421 MMBoardTime btime;
422 int frameTime;
423
424 frameTime = (int)( m_video_driver->GetNbFrames() / m_video_driver->GetFrameRate());
425
426 btime.seconds = frameTime % 60;
427 btime.minutes = (frameTime / 60) % 60;
428 btime.hours = frameTime / 3600;
429 return btime;
430 }
431
432 void MMBoardVideoFile::SetPosition(MMBoardTime WXUNUSED(btime))
433 {
434 }
435
436 bool MMBoardVideoFile::IsStopped()
437 {
438 return m_video_driver->IsStopped();
439 }
440
441 bool MMBoardVideoFile::IsPaused()
442 {
443 return m_video_driver->IsPaused();
444 }
445
446 wxString MMBoardVideoFile::GetStringType()
447 {
448 return wxString(wxT("Video XANIM"));
449 }
450
451 wxString MMBoardVideoFile::GetStringInformation()
452 {
453 wxString info;
454
455 info = wxT("Video codec: ");
456 info += m_video_driver->GetMovieCodec() + _T("\n");
457 info += wxT("Audio codec: ");
458 info += m_video_driver->GetAudioCodec();
459 info += wxString::Format(_T(" Sample rate: %d Channels: %d\n"), m_video_driver->GetSampleRate(),
460 m_video_driver->GetBPS());
461 info += wxString::Format(_T(" Frame rate: %.01f"), m_video_driver->GetFrameRate());
462 return info;
463 }
464
465 // ----------------------------------------------------------------------------
466
467 // ----------------------------------------------------------------------------
468 // MMBoardFile
469
470 MMBoardFile::MMBoardFile()
471 {
472 m_error = 0;
473 }
474
475 MMBoardFile::~MMBoardFile()
476 {
477 }
478
479 //
480 // ----------------------------------------------------------------------------
481
482 // ----------------------------------------------------------------------------
483 // MMBoardManager
484
485 MMBoardFile *MMBoardManager::Open(const wxString& filename)
486 {
487 MMBoardFile *file;
488
489 // Test the audio codec
490 file = new MMBoardSoundFile(filename);
491 if (!file->GetError())
492 return file;
493 delete file;
494
495 // Test the video codec
496 file = new MMBoardVideoFile(filename);
497 if (!file->GetError())
498 return file;
499 delete file;
500
501 // Arrrgh, we just could not see what is that file ...
502 return NULL;
503 }
504
505 DECLARE_APP(MMBoardApp)
506
507 wxSoundStream *MMBoardManager::OpenSoundStream()
508 {
509 #ifdef __WIN32__
510 if ((wxGetApp().m_caps & MM_SOUND_WIN) != 0)
511 return new wxSoundStreamWin();
512 #elif __UNIX__
513 if ((wxGetApp().m_caps & MM_SOUND_ESD) != 0)
514 return new wxSoundStreamESD();
515
516 if ((wxGetApp().m_caps & MM_SOUND_OSS) != 0)
517 return new wxSoundStreamOSS();
518 #endif
519
520 wxMessageBox(_T("You are trying to open a multimedia but you have not devices"), _T("Error"), wxOK | wxICON_ERROR, NULL);
521
522 return NULL;
523 }
524
525 void MMBoardManager::UnrefSoundStream(wxSoundStream *stream)
526 {
527 delete stream;
528 }
529
530 // ----------------------------------------------------------------------------
531