]> git.saurik.com Git - wxWidgets.git/blame - contrib/samples/mmedia/mmbman.cpp
#undef CreateFont to fix cygwin compilation now that wxRichTextCtrl uses it
[wxWidgets.git] / contrib / samples / mmedia / mmbman.cpp
CommitLineData
e8482f24
GL
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
e8482f24
GL
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
be5a51fb 24// need because it includes almost all "standard" wxWidgets headers
e8482f24
GL
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"
c42b1de6 40#include "wx/mmedia/sndmsad.h"
e8482f24
GL
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
67class MMBoardSoundFile: public MMBoardFile {
68public:
69 MMBoardSoundFile(const wxString& filename);
70 ~MMBoardSoundFile();
8b523dc5 71
e8482f24 72 bool NeedWindow();
8b523dc5 73
e8482f24 74 void SetWindow(wxWindow *window);
8b523dc5 75
e8482f24
GL
76 void Play();
77 void Pause();
78 void Resume();
79 void Stop();
8b523dc5 80
e8482f24
GL
81 MMBoardTime GetPosition();
82 MMBoardTime GetLength();
83 void SetPosition(MMBoardTime btime);
8b523dc5 84
e8482f24
GL
85 bool IsStopped();
86 bool IsPaused();
8b523dc5 87
e8482f24
GL
88 wxString GetStringType();
89 wxString GetStringInformation();
8b523dc5 90
e8482f24
GL
91protected:
92 wxSoundFileStream *GetDecoder();
8b523dc5 93
e8482f24
GL
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
102class MMBoardVideoFile: public MMBoardFile {
103public:
104 MMBoardVideoFile(const wxString& filename);
105 ~MMBoardVideoFile();
8b523dc5 106
e8482f24 107 bool NeedWindow();
8b523dc5 108
e8482f24 109 void SetWindow(wxWindow *window);
8b523dc5 110
e8482f24
GL
111 void Play();
112 void Pause();
113 void Resume();
114 void Stop();
8b523dc5 115
e8482f24
GL
116 MMBoardTime GetPosition();
117 MMBoardTime GetLength();
118 void SetPosition(MMBoardTime btime);
8b523dc5 119
e8482f24
GL
120 bool IsStopped();
121 bool IsPaused();
8b523dc5 122
e8482f24
GL
123 wxString GetStringType();
124 wxString GetStringInformation();
8b523dc5 125
e8482f24
GL
126protected:
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
142MMBoardSoundFile::MMBoardSoundFile(const wxString& filename)
143 : MMBoardFile()
144{
145 m_input_stream = new wxFileInputStream(filename);
146 m_output_stream = MMBoardManager::OpenSoundStream();
8b523dc5 147
e8482f24 148 m_file_stream = GetDecoder();
8b523dc5 149
e8482f24
GL
150 if (!m_file_stream) {
151 SetError(MMBoard_UnknownFile);
152 return;
153 }
8b523dc5 154
e8482f24
GL
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
165MMBoardSoundFile::~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
173wxSoundFileStream *MMBoardSoundFile::GetDecoder()
174{
175 wxSoundFileStream *f_stream;
8b523dc5 176
e8482f24
GL
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;
8b523dc5 183
e8482f24
GL
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;
8b523dc5 190
e8482f24 191 m_file_type = MMBoard_UNKNOWNTYPE;
8b523dc5 192
e8482f24 193 // TODO: automate
8b523dc5 194
e8482f24
GL
195 return NULL;
196}
197
198MMBoardTime MMBoardSoundFile::GetLength()
199{
200 return m_length;
201}
202
203bool MMBoardSoundFile::IsStopped()
204{
205 return m_file_stream->IsStopped();
206}
207
208bool MMBoardSoundFile::IsPaused()
209{
210 return m_file_stream->IsPaused();
211}
212
213MMBoardTime MMBoardSoundFile::GetPosition()
214{
215 wxUint32 length, seconds;
216 MMBoardTime file_time;
8b523dc5 217
e8482f24
GL
218 file_time.seconds = file_time.minutes = file_time.hours = 0;
219 if (m_file_stream->IsStopped())
220 return file_time;
8b523dc5 221
e8482f24
GL
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;
8b523dc5 227
e8482f24
GL
228 return file_time;
229}
230
231void 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
242bool MMBoardSoundFile::NeedWindow()
243{
dea7e44a 244 return false;
e8482f24
GL
245}
246
2bbf230a 247void MMBoardSoundFile::SetWindow(wxWindow *WXUNUSED(window))
e8482f24
GL
248{
249}
250
251void MMBoardSoundFile::Play()
252{
253 m_file_stream->Play();
254}
255
256void MMBoardSoundFile::Pause()
257{
258 m_file_stream->Pause();
259}
260
261void MMBoardSoundFile::Resume()
262{
263 m_file_stream->Resume();
264}
265
266void MMBoardSoundFile::Stop()
267{
268 m_file_stream->Stop();
269}
270
271wxString MMBoardSoundFile::GetStringType()
272{
273 switch (m_file_type) {
274 case MMBoard_WAVE:
275 return wxString(wxT("WAVE file"));
2bbf230a
JS
276 #if 0
277 // break is not reachable after return
e8482f24 278 break;
2bbf230a 279 #endif
e8482f24
GL
280 case MMBoard_AIFF:
281 return wxString(wxT("AIFF file"));
2bbf230a
JS
282 #if 0
283 // break is not reachable after return
e8482f24 284 break;
2bbf230a
JS
285 #endif
286 #if 0
287 // default moved outside switch for those compilers
288 // which complain about lack of return in function
e8482f24
GL
289 default:
290 return wxString(wxT("Unknown file"));
291 break;
2bbf230a 292 #endif
e8482f24 293 }
2bbf230a 294 return wxString(wxT("Unknown file"));
e8482f24
GL
295}
296
297wxString MMBoardSoundFile::GetStringInformation()
298{
299 wxString info;
300 wxSoundFormatBase *format;
8b523dc5 301
e8482f24 302 format = &(m_file_stream->GetSoundFormat());
8b523dc5 303
e8482f24
GL
304 info = wxT("Data encoding: ");
305 switch (format->GetType()) {
306 case wxSOUND_PCM: {
307 wxSoundFormatPcm *pcm_format = (wxSoundFormatPcm *)format;
8b523dc5 308
dea7e44a 309 info += wxString::Format(wxT("PCM %s %s\n"),
e8482f24
GL
310 pcm_format->Signed() ? wxT("signed") : wxT("unsigned"),
311 pcm_format->GetOrder() == wxLITTLE_ENDIAN ? wxT("little endian") : wxT("big endian"));
dea7e44a
WS
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;
e8482f24 320 }
c42b1de6
GL
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 }
e8482f24
GL
331 case wxSOUND_ULAW: {
332 wxSoundFormatUlaw *ulaw_format = (wxSoundFormatUlaw *)format;
dea7e44a
WS
333 info += wxT("ULAW\n");
334 info += wxString::Format(wxT("Sampling rate: %d\n"), ulaw_format->GetSampleRate());
335 break;
e8482f24
GL
336 }
337 default:
338 info += wxT("Unknown");
dea7e44a 339 break;
e8482f24
GL
340 }
341 return info;
342}
343
344// ----------------------------------------------------------------------------
345
346
347// ----------------------------------------------------------------------------
348// MMBoardVideoFile
349
350MMBoardVideoFile::MMBoardVideoFile(const wxString& filename)
351{
352 m_output_window = NULL;
8b523dc5 353
69067986 354#if defined(__UNIX__) && !defined(__CYGWIN__)
e8482f24 355 m_video_driver = new wxVideoXANIM(filename);
69067986 356#elif defined(__WINDOWS__) && !defined(__MINGW32__) && !defined(__WATCOMC__) && !defined(__CYGWIN__)
2b3644c7
JS
357 // versions of Open Watcom and MinGW tested against this source does not
358 // deliver "digitalv.h" required in this feature
e8482f24
GL
359 m_video_driver = new wxVideoWindows(filename);
360#else
8b523dc5 361 wxUnusedVar(filename);
e8482f24
GL
362 m_video_driver = NULL;
363 SetError(MMBoard_UnknownFile);
364#endif
365}
366
367MMBoardVideoFile::~MMBoardVideoFile()
368{
369 if (m_video_driver)
370 delete m_video_driver;
371}
372
373bool MMBoardVideoFile::NeedWindow()
374{
dea7e44a 375 return true;
e8482f24
GL
376}
377
378void 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
391void MMBoardVideoFile::Play()
392{
393 m_video_driver->Play();
394}
395
396void MMBoardVideoFile::Pause()
397{
398 m_video_driver->Pause();
399}
400
401void MMBoardVideoFile::Resume()
402{
403 m_video_driver->Resume();
404}
405
406void MMBoardVideoFile::Stop()
407{
408 m_video_driver->Stop();
409}
410
411MMBoardTime MMBoardVideoFile::GetPosition()
412{
413 MMBoardTime btime;
414
415 btime.seconds = btime.minutes = btime.hours = 0;
416 return btime;
417}
418
419MMBoardTime MMBoardVideoFile::GetLength()
420{
421 MMBoardTime btime;
422 int frameTime;
423
424 frameTime = (int)( m_video_driver->GetNbFrames() / m_video_driver->GetFrameRate());
8b523dc5 425
e8482f24
GL
426 btime.seconds = frameTime % 60;
427 btime.minutes = (frameTime / 60) % 60;
428 btime.hours = frameTime / 3600;
429 return btime;
430}
431
2bbf230a 432void MMBoardVideoFile::SetPosition(MMBoardTime WXUNUSED(btime))
e8482f24
GL
433{
434}
435
436bool MMBoardVideoFile::IsStopped()
437{
438 return m_video_driver->IsStopped();
439}
440
441bool MMBoardVideoFile::IsPaused()
442{
443 return m_video_driver->IsPaused();
444}
445
446wxString MMBoardVideoFile::GetStringType()
447{
448 return wxString(wxT("Video XANIM"));
449}
450
451wxString MMBoardVideoFile::GetStringInformation()
452{
453 wxString info;
454
455 info = wxT("Video codec: ");
2bbf230a 456 info += m_video_driver->GetMovieCodec() + _T("\n");
e8482f24
GL
457 info += wxT("Audio codec: ");
458 info += m_video_driver->GetAudioCodec();
2bbf230a 459 info += wxString::Format(_T(" Sample rate: %d Channels: %d\n"), m_video_driver->GetSampleRate(),
e8482f24 460 m_video_driver->GetBPS());
2bbf230a 461 info += wxString::Format(_T(" Frame rate: %.01f"), m_video_driver->GetFrameRate());
e8482f24
GL
462 return info;
463}
464
465// ----------------------------------------------------------------------------
466
467// ----------------------------------------------------------------------------
468// MMBoardFile
469
470MMBoardFile::MMBoardFile()
471{
472 m_error = 0;
473}
474
475MMBoardFile::~MMBoardFile()
476{
477}
478
479//
480// ----------------------------------------------------------------------------
481
482// ----------------------------------------------------------------------------
483// MMBoardManager
484
485MMBoardFile *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
505DECLARE_APP(MMBoardApp)
506
507wxSoundStream *MMBoardManager::OpenSoundStream()
508{
69067986
MW
509#ifdef __WIN32__
510 if ((wxGetApp().m_caps & MM_SOUND_WIN) != 0)
511 return new wxSoundStreamWin();
512#elif __UNIX__
e8482f24
GL
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
2bbf230a 520 wxMessageBox(_T("You are trying to open a multimedia but you have not devices"), _T("Error"), wxOK | wxICON_ERROR, NULL);
e8482f24
GL
521
522 return NULL;
523}
524
525void MMBoardManager::UnrefSoundStream(wxSoundStream *stream)
526{
527 delete stream;
528}
529
530// ----------------------------------------------------------------------------
531