2000-03-05 19:03:21 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Name: mmbman.cpp
|
|
|
|
// Purpose: Multimedia Board manager
|
|
|
|
// Author: Guilhem Lavaux, <guilhem.lavaux@libertysurf.fr>
|
|
|
|
// Modified by:
|
|
|
|
// Created: 13/02/2000
|
|
|
|
// RCS-ID: $Id$
|
|
|
|
// Copyright: (c) 2000, Guilhem Lavaux
|
|
|
|
// Licence: wxWindows licence
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#ifdef __GNUG__
|
|
|
|
#pragma implementation "mmbman.cpp"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// headers
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// For compilers that support precompilation, includes "wx/wx.h".
|
|
|
|
#include "wx/wxprec.h"
|
|
|
|
|
|
|
|
#ifdef __BORLANDC__
|
|
|
|
#pragma hdrstop
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// for all others, include the necessary headers (this file is usually all you
|
|
|
|
// need because it includes almost all "standard" wxWindows headers
|
|
|
|
#ifndef WX_PRECOMP
|
|
|
|
#include "wx/wx.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Personal headers
|
|
|
|
|
|
|
|
#include "wx/stream.h"
|
|
|
|
#include "wx/wfstream.h"
|
|
|
|
|
|
|
|
#include "wx/mmedia/sndbase.h"
|
|
|
|
#include "wx/mmedia/sndfile.h"
|
|
|
|
#include "wx/mmedia/sndwav.h"
|
|
|
|
#include "wx/mmedia/sndaiff.h"
|
|
|
|
#include "wx/mmedia/sndpcm.h"
|
|
|
|
#include "wx/mmedia/sndulaw.h"
|
2000-06-04 08:38:36 +00:00
|
|
|
#include "wx/mmedia/sndmsad.h"
|
2000-03-05 19:03:21 +00:00
|
|
|
|
|
|
|
#ifdef __UNIX__
|
|
|
|
#include "wx/mmedia/sndoss.h"
|
|
|
|
#include "wx/mmedia/sndesd.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __WIN32__
|
|
|
|
#include "wx/mmedia/sndwin.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "wx/mmedia/vidbase.h"
|
|
|
|
#ifdef __UNIX__
|
|
|
|
#include "wx/mmedia/vidxanm.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __WIN32__
|
|
|
|
#include "wx/mmedia/vidwin.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "mmboard.h"
|
|
|
|
#include "mmbman.h"
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Private class definitions
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class MMBoardSoundFile: public MMBoardFile {
|
|
|
|
public:
|
|
|
|
MMBoardSoundFile(const wxString& filename);
|
|
|
|
~MMBoardSoundFile();
|
|
|
|
|
|
|
|
bool NeedWindow();
|
|
|
|
|
|
|
|
void SetWindow(wxWindow *window);
|
|
|
|
|
|
|
|
void Play();
|
|
|
|
void Pause();
|
|
|
|
void Resume();
|
|
|
|
void Stop();
|
|
|
|
|
|
|
|
MMBoardTime GetPosition();
|
|
|
|
MMBoardTime GetLength();
|
|
|
|
void SetPosition(MMBoardTime btime);
|
|
|
|
|
|
|
|
bool IsStopped();
|
|
|
|
bool IsPaused();
|
|
|
|
|
|
|
|
wxString GetStringType();
|
|
|
|
wxString GetStringInformation();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
wxSoundFileStream *GetDecoder();
|
|
|
|
|
|
|
|
wxSoundStream *m_output_stream;
|
|
|
|
wxInputStream *m_input_stream;
|
|
|
|
wxSoundFileStream *m_file_stream;
|
|
|
|
|
|
|
|
MMBoardTime m_length;
|
|
|
|
wxUint8 m_file_type;
|
|
|
|
};
|
|
|
|
|
|
|
|
class MMBoardVideoFile: public MMBoardFile {
|
|
|
|
public:
|
|
|
|
MMBoardVideoFile(const wxString& filename);
|
|
|
|
~MMBoardVideoFile();
|
|
|
|
|
|
|
|
bool NeedWindow();
|
|
|
|
|
|
|
|
void SetWindow(wxWindow *window);
|
|
|
|
|
|
|
|
void Play();
|
|
|
|
void Pause();
|
|
|
|
void Resume();
|
|
|
|
void Stop();
|
|
|
|
|
|
|
|
MMBoardTime GetPosition();
|
|
|
|
MMBoardTime GetLength();
|
|
|
|
void SetPosition(MMBoardTime btime);
|
|
|
|
|
|
|
|
bool IsStopped();
|
|
|
|
bool IsPaused();
|
|
|
|
|
|
|
|
wxString GetStringType();
|
|
|
|
wxString GetStringInformation();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
wxWindow *m_output_window;
|
|
|
|
wxVideoBaseDriver *m_video_driver;
|
|
|
|
};
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Implementation
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#define MMBoard_UNKNOWNTYPE 0
|
|
|
|
#define MMBoard_WAVE 1
|
|
|
|
#define MMBoard_AIFF 2
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// MMBoardSoundFile
|
|
|
|
|
|
|
|
MMBoardSoundFile::MMBoardSoundFile(const wxString& filename)
|
|
|
|
: MMBoardFile()
|
|
|
|
{
|
|
|
|
m_input_stream = new wxFileInputStream(filename);
|
|
|
|
m_output_stream = MMBoardManager::OpenSoundStream();
|
|
|
|
|
|
|
|
m_file_stream = GetDecoder();
|
|
|
|
|
|
|
|
if (!m_file_stream) {
|
|
|
|
SetError(MMBoard_UnknownFile);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Compute length
|
|
|
|
wxUint32 length, seconds;
|
|
|
|
|
|
|
|
length = m_file_stream->GetLength();
|
|
|
|
seconds = m_file_stream->GetSoundFormat().GetTimeFromBytes(length);
|
|
|
|
m_length.seconds = seconds % 60;
|
|
|
|
m_length.minutes = (seconds / 60) % 60;
|
|
|
|
m_length.hours = seconds / 3600;
|
|
|
|
}
|
|
|
|
|
|
|
|
MMBoardSoundFile::~MMBoardSoundFile()
|
|
|
|
{
|
|
|
|
if (m_file_stream)
|
|
|
|
delete m_file_stream;
|
|
|
|
MMBoardManager::UnrefSoundStream(m_output_stream);
|
|
|
|
delete m_input_stream;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxSoundFileStream *MMBoardSoundFile::GetDecoder()
|
|
|
|
{
|
|
|
|
wxSoundFileStream *f_stream;
|
|
|
|
|
|
|
|
// First, we try a Wave decoder
|
|
|
|
f_stream = new wxSoundWave(*m_input_stream, *m_output_stream);
|
|
|
|
m_file_type = MMBoard_WAVE;
|
|
|
|
if (f_stream->CanRead())
|
|
|
|
return f_stream;
|
|
|
|
delete f_stream;
|
|
|
|
|
|
|
|
// Then, a AIFF decoder
|
|
|
|
f_stream = new wxSoundAiff(*m_input_stream, *m_output_stream);
|
|
|
|
m_file_type = MMBoard_AIFF;
|
|
|
|
if (f_stream->CanRead())
|
|
|
|
return f_stream;
|
|
|
|
delete f_stream;
|
|
|
|
|
|
|
|
m_file_type = MMBoard_UNKNOWNTYPE;
|
|
|
|
|
|
|
|
// TODO: automate
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
MMBoardTime MMBoardSoundFile::GetLength()
|
|
|
|
{
|
|
|
|
return m_length;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MMBoardSoundFile::IsStopped()
|
|
|
|
{
|
|
|
|
return m_file_stream->IsStopped();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MMBoardSoundFile::IsPaused()
|
|
|
|
{
|
|
|
|
return m_file_stream->IsPaused();
|
|
|
|
}
|
|
|
|
|
|
|
|
MMBoardTime MMBoardSoundFile::GetPosition()
|
|
|
|
{
|
|
|
|
wxUint32 length, seconds;
|
|
|
|
MMBoardTime file_time;
|
|
|
|
|
|
|
|
file_time.seconds = file_time.minutes = file_time.hours = 0;
|
|
|
|
if (m_file_stream->IsStopped())
|
|
|
|
return file_time;
|
|
|
|
|
|
|
|
length = m_file_stream->GetPosition();
|
|
|
|
seconds = m_file_stream->GetSoundFormat().GetTimeFromBytes(length);
|
|
|
|
file_time.seconds = seconds % 60;
|
|
|
|
file_time.minutes = (seconds / 60) % 60;
|
|
|
|
file_time.hours = seconds / 3600;
|
|
|
|
|
|
|
|
return file_time;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MMBoardSoundFile::SetPosition(MMBoardTime btime)
|
|
|
|
{
|
|
|
|
wxUint32 itime;
|
|
|
|
|
|
|
|
itime = btime.seconds + btime.minutes * 60 + btime.hours;
|
|
|
|
|
|
|
|
m_file_stream->SetPosition(
|
|
|
|
m_file_stream->GetSoundFormat().GetBytesFromTime(itime)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MMBoardSoundFile::NeedWindow()
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2003-09-11 09:55:21 +00:00
|
|
|
void MMBoardSoundFile::SetWindow(wxWindow *WXUNUSED(window))
|
2000-03-05 19:03:21 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void MMBoardSoundFile::Play()
|
|
|
|
{
|
|
|
|
m_file_stream->Play();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MMBoardSoundFile::Pause()
|
|
|
|
{
|
|
|
|
m_file_stream->Pause();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MMBoardSoundFile::Resume()
|
|
|
|
{
|
|
|
|
m_file_stream->Resume();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MMBoardSoundFile::Stop()
|
|
|
|
{
|
|
|
|
m_file_stream->Stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString MMBoardSoundFile::GetStringType()
|
|
|
|
{
|
|
|
|
switch (m_file_type) {
|
|
|
|
case MMBoard_WAVE:
|
|
|
|
return wxString(wxT("WAVE file"));
|
2003-09-11 09:55:21 +00:00
|
|
|
#if 0
|
|
|
|
// break is not reachable after return
|
2000-03-05 19:03:21 +00:00
|
|
|
break;
|
2003-09-11 09:55:21 +00:00
|
|
|
#endif
|
2000-03-05 19:03:21 +00:00
|
|
|
case MMBoard_AIFF:
|
|
|
|
return wxString(wxT("AIFF file"));
|
2003-09-11 09:55:21 +00:00
|
|
|
#if 0
|
|
|
|
// break is not reachable after return
|
2000-03-05 19:03:21 +00:00
|
|
|
break;
|
2003-09-11 09:55:21 +00:00
|
|
|
#endif
|
|
|
|
#if 0
|
|
|
|
// default moved outside switch for those compilers
|
|
|
|
// which complain about lack of return in function
|
2000-03-05 19:03:21 +00:00
|
|
|
default:
|
|
|
|
return wxString(wxT("Unknown file"));
|
|
|
|
break;
|
2003-09-11 09:55:21 +00:00
|
|
|
#endif
|
2000-03-05 19:03:21 +00:00
|
|
|
}
|
2003-09-11 09:55:21 +00:00
|
|
|
return wxString(wxT("Unknown file"));
|
2000-03-05 19:03:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
wxString MMBoardSoundFile::GetStringInformation()
|
|
|
|
{
|
|
|
|
wxString info;
|
|
|
|
wxSoundFormatBase *format;
|
|
|
|
|
|
|
|
format = &(m_file_stream->GetSoundFormat());
|
|
|
|
|
|
|
|
info = wxT("Data encoding: ");
|
|
|
|
switch (format->GetType()) {
|
|
|
|
case wxSOUND_PCM: {
|
|
|
|
wxSoundFormatPcm *pcm_format = (wxSoundFormatPcm *)format;
|
|
|
|
|
|
|
|
info += wxString::Format(wxT("PCM %s %s\n"),
|
|
|
|
pcm_format->Signed() ? wxT("signed") : wxT("unsigned"),
|
|
|
|
pcm_format->GetOrder() == wxLITTLE_ENDIAN ? wxT("little endian") : wxT("big endian"));
|
|
|
|
info += wxString::Format(wxT("Sampling rate: %d\n")
|
|
|
|
wxT("Bits per sample: %d\n")
|
|
|
|
wxT("Number of channels: %d\n"),
|
|
|
|
pcm_format->GetSampleRate(),
|
|
|
|
pcm_format->GetBPS(),
|
|
|
|
pcm_format->GetChannels());
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2000-06-04 08:38:36 +00:00
|
|
|
case wxSOUND_MSADPCM: {
|
|
|
|
wxSoundFormatMSAdpcm *adpcm_format = (wxSoundFormatMSAdpcm *)format;
|
|
|
|
|
|
|
|
info += wxString::Format(wxT("Microsoft ADPCM\n"));
|
|
|
|
info += wxString::Format(wxT("Sampling Rate: %d\n")
|
|
|
|
wxT("Number of channels: %d\n"),
|
|
|
|
adpcm_format->GetSampleRate(),
|
|
|
|
adpcm_format->GetChannels());
|
|
|
|
break;
|
|
|
|
}
|
2000-03-05 19:03:21 +00:00
|
|
|
case wxSOUND_ULAW: {
|
|
|
|
wxSoundFormatUlaw *ulaw_format = (wxSoundFormatUlaw *)format;
|
|
|
|
info += wxT("ULAW\n");
|
|
|
|
info += wxString::Format(wxT("Sampling rate: %d\n"), ulaw_format->GetSampleRate());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
info += wxT("Unknown");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return info;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// MMBoardVideoFile
|
|
|
|
|
|
|
|
MMBoardVideoFile::MMBoardVideoFile(const wxString& filename)
|
|
|
|
{
|
|
|
|
m_output_window = NULL;
|
|
|
|
|
|
|
|
#if defined(__UNIX__)
|
|
|
|
m_video_driver = new wxVideoXANIM(filename);
|
|
|
|
#elif defined(__WIN32__)
|
|
|
|
m_video_driver = new wxVideoWindows(filename);
|
|
|
|
#else
|
|
|
|
m_video_driver = NULL;
|
|
|
|
SetError(MMBoard_UnknownFile);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
MMBoardVideoFile::~MMBoardVideoFile()
|
|
|
|
{
|
|
|
|
if (m_video_driver)
|
|
|
|
delete m_video_driver;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MMBoardVideoFile::NeedWindow()
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MMBoardVideoFile::SetWindow(wxWindow *window)
|
|
|
|
{
|
|
|
|
m_output_window = window;
|
|
|
|
m_video_driver->AttachOutput(*window);
|
|
|
|
|
|
|
|
wxSize size;
|
|
|
|
m_video_driver->GetSize(size);
|
|
|
|
window->SetSize(size);
|
|
|
|
// BAD BAD
|
|
|
|
// and we remove
|
|
|
|
// window->GetParent()->GetSizer()->Fit(window->GetParent());
|
|
|
|
}
|
|
|
|
|
|
|
|
void MMBoardVideoFile::Play()
|
|
|
|
{
|
|
|
|
m_video_driver->Play();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MMBoardVideoFile::Pause()
|
|
|
|
{
|
|
|
|
m_video_driver->Pause();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MMBoardVideoFile::Resume()
|
|
|
|
{
|
|
|
|
m_video_driver->Resume();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MMBoardVideoFile::Stop()
|
|
|
|
{
|
|
|
|
m_video_driver->Stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
MMBoardTime MMBoardVideoFile::GetPosition()
|
|
|
|
{
|
|
|
|
MMBoardTime btime;
|
|
|
|
|
|
|
|
btime.seconds = btime.minutes = btime.hours = 0;
|
|
|
|
return btime;
|
|
|
|
}
|
|
|
|
|
|
|
|
MMBoardTime MMBoardVideoFile::GetLength()
|
|
|
|
{
|
|
|
|
MMBoardTime btime;
|
|
|
|
int frameTime;
|
|
|
|
|
|
|
|
frameTime = (int)( m_video_driver->GetNbFrames() / m_video_driver->GetFrameRate());
|
|
|
|
|
|
|
|
btime.seconds = frameTime % 60;
|
|
|
|
btime.minutes = (frameTime / 60) % 60;
|
|
|
|
btime.hours = frameTime / 3600;
|
|
|
|
return btime;
|
|
|
|
}
|
|
|
|
|
2003-09-11 09:55:21 +00:00
|
|
|
void MMBoardVideoFile::SetPosition(MMBoardTime WXUNUSED(btime))
|
2000-03-05 19:03:21 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MMBoardVideoFile::IsStopped()
|
|
|
|
{
|
|
|
|
return m_video_driver->IsStopped();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MMBoardVideoFile::IsPaused()
|
|
|
|
{
|
|
|
|
return m_video_driver->IsPaused();
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString MMBoardVideoFile::GetStringType()
|
|
|
|
{
|
|
|
|
return wxString(wxT("Video XANIM"));
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString MMBoardVideoFile::GetStringInformation()
|
|
|
|
{
|
|
|
|
wxString info;
|
|
|
|
|
|
|
|
info = wxT("Video codec: ");
|
2003-09-11 09:55:21 +00:00
|
|
|
info += m_video_driver->GetMovieCodec() + _T("\n");
|
2000-03-05 19:03:21 +00:00
|
|
|
info += wxT("Audio codec: ");
|
|
|
|
info += m_video_driver->GetAudioCodec();
|
2003-09-11 09:55:21 +00:00
|
|
|
info += wxString::Format(_T(" Sample rate: %d Channels: %d\n"), m_video_driver->GetSampleRate(),
|
2000-03-05 19:03:21 +00:00
|
|
|
m_video_driver->GetBPS());
|
2003-09-11 09:55:21 +00:00
|
|
|
info += wxString::Format(_T(" Frame rate: %.01f"), m_video_driver->GetFrameRate());
|
2000-03-05 19:03:21 +00:00
|
|
|
return info;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// MMBoardFile
|
|
|
|
|
|
|
|
MMBoardFile::MMBoardFile()
|
|
|
|
{
|
|
|
|
m_error = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
MMBoardFile::~MMBoardFile()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// MMBoardManager
|
|
|
|
|
|
|
|
MMBoardFile *MMBoardManager::Open(const wxString& filename)
|
|
|
|
{
|
|
|
|
MMBoardFile *file;
|
|
|
|
|
|
|
|
// Test the audio codec
|
|
|
|
file = new MMBoardSoundFile(filename);
|
|
|
|
if (!file->GetError())
|
|
|
|
return file;
|
|
|
|
delete file;
|
|
|
|
|
|
|
|
// Test the video codec
|
|
|
|
file = new MMBoardVideoFile(filename);
|
|
|
|
if (!file->GetError())
|
|
|
|
return file;
|
|
|
|
delete file;
|
|
|
|
|
|
|
|
// Arrrgh, we just could not see what is that file ...
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
DECLARE_APP(MMBoardApp)
|
|
|
|
|
|
|
|
wxSoundStream *MMBoardManager::OpenSoundStream()
|
|
|
|
{
|
|
|
|
#ifdef __UNIX__
|
|
|
|
if ((wxGetApp().m_caps & MM_SOUND_ESD) != 0)
|
|
|
|
return new wxSoundStreamESD();
|
|
|
|
|
|
|
|
if ((wxGetApp().m_caps & MM_SOUND_OSS) != 0)
|
|
|
|
return new wxSoundStreamOSS();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __WIN32__
|
|
|
|
if ((wxGetApp().m_caps & MM_SOUND_WIN) != 0)
|
|
|
|
return new wxSoundStreamWin();
|
|
|
|
#endif
|
|
|
|
|
2003-09-11 09:55:21 +00:00
|
|
|
wxMessageBox(_T("You are trying to open a multimedia but you have not devices"), _T("Error"), wxOK | wxICON_ERROR, NULL);
|
2000-03-05 19:03:21 +00:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MMBoardManager::UnrefSoundStream(wxSoundStream *stream)
|
|
|
|
{
|
|
|
|
delete stream;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|