#include "wx/wx.h"
#endif
-// Personnal headers
+// Personal headers
#include "wx/stream.h"
#include "wx/wfstream.h"
#include "sndwin.h"
#endif
+#include "vidbase.h"
+#ifdef __UNIX__
+#include "vidxanm.h"
+#endif
+
+#ifdef __WIN32__
+#include "vidwin.h"
+#endif
+
#include "mmboard.h"
#include "mmbman.h"
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();
+
+ bool IsStopped();
+ bool IsPaused();
+
+ wxString GetStringType();
+ wxString GetStringInformation();
+
+protected:
+ wxWindow *m_output_window;
+ wxInputStream *m_input_stream;
+ wxVideoBaseDriver *m_video_driver;
};
// ----------------------------------------------------------------------------
// Implementation
// ----------------------------------------------------------------------------
+#define MMBoard_UNKNOWNTYPE 0
+#define MMBoard_WAVE 1
+#define MMBoard_AIFF 2
// ----------------------------------------------------------------------------
// MMBoardSoundFile
m_file_stream = GetDecoder();
- if (!m_file_stream)
+ if (!m_file_stream) {
SetError(MMBoard_UnknownFile);
-
+ return;
+ }
+
// Compute length
wxUint32 length, seconds;
MMBoardSoundFile::~MMBoardSoundFile()
{
- delete m_file_stream;
+ if (m_file_stream)
+ delete m_file_stream;
MMBoardManager::UnrefSoundStream(m_output_stream);
delete m_input_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;
wxString MMBoardSoundFile::GetStringType()
{
- return wxString("WAVE file");
+ switch (m_file_type) {
+ case MMBoard_WAVE:
+ return wxString("WAVE file");
+ break;
+ case MMBoard_AIFF:
+ return wxString("AIFF file");
+ break;
+ default:
+ return wxString("Unknown file");
+ break;
+ }
}
wxString MMBoardSoundFile::GetStringInformation()
// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+// MMBoardVideoFile
+
+MMBoardVideoFile::MMBoardVideoFile(const wxString& filename)
+{
+ m_output_window = NULL;
+ m_input_stream = new wxFileInputStream(filename);
+
+#if defined(__UNIX__)
+ m_video_driver = new wxVideoXANIM(*m_input_stream);
+#elif defined(__WIN32__)
+ m_video_driver = new wxVideoWindows(m_input_stream);
+#else
+ m_video_driver = NULL;
+ SetError(MMBoard_UnknownFile);
+#endif
+}
+
+MMBoardVideoFile::~MMBoardVideoFile()
+{
+ if (m_video_driver)
+ delete m_video_driver;
+
+ delete m_input_stream;
+}
+
+bool MMBoardVideoFile::NeedWindow()
+{
+ return TRUE;
+}
+
+void MMBoardVideoFile::SetWindow(wxWindow *window)
+{
+ m_output_window = window;
+ m_video_driver->AttachOutput(*window);
+}
+
+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;
+
+ btime.seconds = btime.minutes = btime.hours = 1;
+ return btime;
+}
+
+bool MMBoardVideoFile::IsStopped()
+{
+ return FALSE;
+}
+
+bool MMBoardVideoFile::IsPaused()
+{
+ return FALSE;
+}
+
+wxString MMBoardVideoFile::GetStringType()
+{
+ return wxString("Video XANIM");
+}
+
+wxString MMBoardVideoFile::GetStringInformation()
+{
+ return wxString("No info");
+}
+
+// ----------------------------------------------------------------------------
+
// ----------------------------------------------------------------------------
// MMBoardFile
{
MMBoardFile *file;
+ // Test the audio codec
file = new MMBoardSoundFile(filename);
- if (file->GetError()) {
- delete file;
- return NULL;
- }
- return file;
+ 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)
void OnPause(wxCommandEvent& event);
void OnRefreshInfo(wxEvent& event);
+ void OpenVideoWindow();
+ void CloseVideoWindow();
+
private:
// any class wishing to process wxWindows events must use this macro
DECLARE_EVENT_TABLE()
wxSlider *m_positionSlider;
wxBitmapButton *m_playButton, *m_pauseButton, *m_stopButton, *m_ejectButton;
wxStaticText *m_fileType, *m_infoText;
+ wxWindow *m_video_window;
+
+ wxPanel *m_panel;
+ wxSizer *m_sizer;
wxTimer *m_refreshTimer;
+
};
// ----------------------------------------------------------------------------
// Misc variables
m_opened_file = NULL;
- wxPanel *panel = new wxPanel(this, -1);
+ m_panel = new wxPanel(this, -1);
// Initialize main slider
- m_positionSlider = new wxSlider( panel, MMBoard_PositionSlider, 0, 0, 60,
+ m_positionSlider = new wxSlider( m_panel, MMBoard_PositionSlider, 0, 0, 60,
wxDefaultPosition, wxSize(300, -1),
wxSL_HORIZONTAL | wxSL_AUTOTICKS);
m_positionSlider->SetPageSize(60); // 60 secs
// Initialize info panel
- wxPanel *infoPanel = new wxPanel( panel, -1);
+ wxPanel *infoPanel = new wxPanel( m_panel, -1);
infoPanel->SetBackgroundColour(*wxBLACK);
infoPanel->SetForegroundColour(*wxWHITE);
wxBitmap *eject_bmp = new wxBitmap(eject_xpm);
wxBitmap *pause_bmp = new wxBitmap(pause_xpm);
- m_playButton = new wxBitmapButton(panel, MMBoard_PlayButton, *play_bmp);
+ m_playButton = new wxBitmapButton(m_panel, MMBoard_PlayButton, *play_bmp);
m_playButton->Enable(FALSE);
- m_pauseButton = new wxBitmapButton(panel, MMBoard_PauseButton, *pause_bmp);
+ m_pauseButton = new wxBitmapButton(m_panel, MMBoard_PauseButton, *pause_bmp);
m_pauseButton->Enable(FALSE);
- m_stopButton = new wxBitmapButton(panel, MMBoard_StopButton, *stop_bmp);
+ m_stopButton = new wxBitmapButton(m_panel, MMBoard_StopButton, *stop_bmp);
m_stopButton->Enable(FALSE);
- m_ejectButton = new wxBitmapButton(panel, MMBoard_EjectButton, *eject_bmp);
+ m_ejectButton = new wxBitmapButton(m_panel, MMBoard_EjectButton, *eject_bmp);
m_ejectButton->Enable(FALSE);
buttonSizer->Add(m_playButton, 0, wxALL, 2);
buttonSizer->Add(m_ejectButton, 0, wxALL, 2);
// Top sizer
- wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
- sizer->Add(new wxStaticLine(panel, -1), 0, wxGROW | wxCENTRE, 0);
- sizer->Add(m_positionSlider, 0, wxCENTRE | wxGROW | wxALL, 2);
- sizer->Add(new wxStaticLine(panel, -1), 0, wxGROW | wxCENTRE, 0);
- sizer->Add(buttonSizer, 0, wxALL, 0);
- sizer->Add(new wxStaticLine(panel, -1), 0, wxGROW | wxCENTRE, 0);
- sizer->Add(infoPanel, 1, wxCENTRE | wxGROW, 0);
+ m_sizer = new wxBoxSizer(wxVERTICAL);
+ m_sizer->Add(new wxStaticLine(m_panel, -1), 0, wxGROW | wxCENTRE, 0);
+ m_sizer->Add(m_positionSlider, 0, wxCENTRE | wxGROW | wxALL, 2);
+ m_sizer->Add(new wxStaticLine(m_panel, -1), 0, wxGROW | wxCENTRE, 0);
+ m_sizer->Add(buttonSizer, 0, wxALL, 0);
+ m_sizer->Add(new wxStaticLine(m_panel, -1), 0, wxGROW | wxCENTRE, 0);
+ m_sizer->Add(infoPanel, 1, wxCENTRE | wxGROW, 0);
- panel->SetSizer(sizer);
- panel->SetAutoLayout(TRUE);
- sizer->Fit(this);
- sizer->SetSizeHints(this);
+ m_panel->SetSizer(m_sizer);
+ m_panel->SetAutoLayout(TRUE);
+ m_sizer->Fit(this);
+ m_sizer->SetSizeHints(this);
// Timer
m_refreshTimer = new wxTimer(this, MMBoard_RefreshInfo);
+
+ // Video window
+ m_video_window = NULL;
+
+ // Multimedia file
+ m_opened_file = NULL;
}
MMBoardFrame::~MMBoardFrame()
delete m_refreshTimer;
}
+void MMBoardFrame::OpenVideoWindow()
+{
+ if (m_video_window)
+ return;
+
+ m_video_window = new wxWindow(m_panel, -1, wxDefaultPosition, wxSize(400, 400));
+ m_video_window->SetBackgroundColour(*wxBLACK);
+ m_sizer->Prepend(m_video_window, 0, wxCENTRE, 0);
+
+ m_sizer->Fit(this);
+}
+
+void MMBoardFrame::CloseVideoWindow()
+{
+ if (!m_video_window)
+ return;
+
+ m_sizer->Remove(m_video_window);
+ delete m_video_window;
+ m_video_window = NULL;
+
+ m_sizer->Fit(this);
+}
+
// event handlers
void MMBoardFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
wxString selected_file;
+ if (m_opened_file) {
+ if (!m_opened_file->IsStopped()) {
+ wxCommandEvent event2;
+ OnStop(event2);
+ }
+ delete m_opened_file;
+ }
+
// select a file to be opened
selected_file = wxLoadFileSelector("multimedia", "*", NULL, this);
if (selected_file.IsNull())
// Enable a few buttons
m_playButton->Enable(TRUE);
m_ejectButton->Enable(TRUE);
+
+ if (m_opened_file->NeedWindow()) {
+ OpenVideoWindow();
+ m_opened_file->SetWindow(m_video_window);
+ } else
+ CloseVideoWindow();
}
void MMBoardFrame::UpdateInfoText()
+#include <stdio.h>
+
#define DEFINE_CONV(name, input_type, output_type, convert) \
static void Convert_##name##(const char *buf_in, char *buf_out, wxUint32 len) \
{\
while (len > 0) { \
src = *t_buf_in++; \
*t_buf_out++ = convert; \
- len--; \
+ len -= sizeof(input_type); \
} \
}
// m_input->SeekI(4, wxFromCurrent); // Pass an INT32
// m_input->SeekI(len-4, wxFromCurrent); // Pass the rest
m_input->SeekI(ssnd + 4, wxFromCurrent);
- FinishPreparation(len - 4);
+ FinishPreparation(len - 8);
end_headers = TRUE;
break;
}
// Sets the event handler: if it is non-null, all events are routed to it.
void SetEventHandler(wxSoundStream *handler) { m_handler = handler; }
- // Initializes the full duplex mode.
- virtual void SetDuplexMode(bool duplex) = 0;
-
wxSoundError GetError() const { return m_snderror; }
wxUint32 GetLastAccess() const { return m_lastcount; }
return m_sndio->StopProduction();
}
-void wxSoundStreamCodec::SetDuplexMode(bool duplex)
-{
- m_sndio->SetDuplexMode(duplex);
-}
-
wxUint32 wxSoundStreamCodec::GetBestSize() const
{
return m_sndio->GetBestSize();
bool StartProduction(int evt);
bool StopProduction();
- void SetDuplexMode(bool duplex);
wxUint32 GetBestSize() const;
protected:
bool StartProduction(int evt);
bool StopProduction();
- void SetDuplexMode(bool duplex) {}
-
// You should not call this.
void WakeUpEvt(int evt);
// Name: sndfile.cpp
// Purpose:
// Date: 08/11/1999
-// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
+// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999, 2000
// CVSID: $Id$
// --------------------------------------------------------------------------
#include <wx/wxprec.h>
return *this;
}
-void wxSoundFileStream::SetDuplexMode(bool duplex)
-{
-}
-
bool wxSoundFileStream::StartProduction(int evt)
{
m_sndio->SetEventHandler(this);
return m_length-m_bytes_left;
}
+wxUint32 wxSoundFileStream::SetPosition(wxUint32 new_position)
+{
+ if (!m_prepared && m_input != NULL && GetError() == wxSOUND_NOERR)
+ PrepareToPlay();
+
+ if (!m_prepared)
+ return 0;
+
+ if (new_position >= m_length) {
+ m_bytes_left = 0;
+ return m_length;
+ }
+
+ m_bytes_left = m_length-new_position;
+ return new_position;
+}
+
void wxSoundFileStream::OnSoundEvent(int evt)
{
wxUint32 len = m_codec.GetBestSize();
wxSoundFileStream(wxOutputStream& stream, wxSoundStream& io_sound);
~wxSoundFileStream();
+ // Usual sound file calls (Play, Stop, ...)
bool Play();
bool Record(unsigned long time);
bool Stop();
bool Pause();
bool Resume();
+ // Functions which return the current state
bool IsStopped() const { return m_state == wxSOUND_FILE_STOPPED; }
bool IsPaused() const { return m_state == wxSOUND_FILE_PAUSED; }
+ // A user should not call these two functions. Several things must be done before calling them.
+ // Users should use Play(), ...
bool StartProduction(int evt);
bool StopProduction();
+ // These three functions deals with the length, the position in the sound file.
+ // All the values are expressed in bytes. If you need the values expressed in terms of
+ // time, you have to use GetSoundFormat().GetTimeFromBytes(...)
wxUint32 GetLength();
wxUint32 GetPosition();
+ wxUint32 SetPosition(wxUint32 new_position);
+ // These two functions use the sound format specified by GetSoundFormat(). All samples
+ // must be encoded in that format.
wxSoundStream& Read(void *buffer, wxUint32 len);
wxSoundStream& Write(const void *buffer, wxUint32 len);
- void SetDuplexMode(bool duplex);
-
+ // This function set the sound format of the file. !! It must be used only when you are
+ // in output mode (concerning the file) !! If you are in input mode (concerning the file)
+ // You can't use this function to modify the format of the samples returned by Read() !
+ // For this action, you must use wxSoundRouterStream applied to wxSoundFileStream.
bool SetSoundFormat(const wxSoundFormatBase& format);
+ // You should use this function to test whether this file codec can read the stream you passed
+ // to it.
virtual bool CanRead() { return FALSE; }
protected:
bool StartProduction(int evt);
bool StopProduction();
- void SetDuplexMode(bool duplex) {}
bool QueueFilled() const;
// You should not call this.
wxSoundStream& Read(void *buffer, wxUint32 len);
bool SetSoundFormat(wxSoundFormatBase& base);
- void SetDuplexMode(bool on) {}
bool StartProduction(int evt);
bool StopProduction();
#endif
IMPLEMENT_ABSTRACT_CLASS(wxVideoBaseDriver, wxObject)
-IMPLEMENT_DYNAMIC_CLASS(wxVideoOutput, wxWindow)
-
-wxVideoOutput::wxVideoOutput()
- : wxWindow()
-{
- m_dyn_size = TRUE;
-}
-
-wxVideoOutput::wxVideoOutput(wxWindow *parent, const wxWindowID id, const wxPoint& position,
- const wxSize& size, const long style,
- const wxString& name)
- : wxWindow(parent, id, position, size, style, name)
-{
- m_dyn_size = TRUE;
-}
///
-wxVideoOutput::~wxVideoOutput()
-{
-}
-
wxVideoBaseDriver::wxVideoBaseDriver()
{
m_video_output = NULL;
{
}
-bool wxVideoBaseDriver::AttachOutput(wxVideoOutput& output)
+bool wxVideoBaseDriver::AttachOutput(wxWindow& output)
{
m_video_output = &output;
return TRUE;
wxFrame *wxVideoCreateFrame(wxVideoBaseDriver *vid_drv)
{
wxFrame *frame = new wxFrame(NULL, -1, "Video Output", wxDefaultPosition, wxSize(100, 100));
- wxVideoOutput *vid_out = new wxVideoOutput(frame, -1, wxPoint(0, 0), wxSize(300, 300));
+ wxWindow *vid_out = new wxWindow(frame, -1, wxPoint(0, 0), wxSize(300, 300));
- vid_out->DynamicSize(TRUE);
frame->Layout();
frame->Show(TRUE);
///
class wxVideoBaseDriver;
-class wxVideoOutput : public wxWindow {
- ///
- DECLARE_DYNAMIC_CLASS(wxVideoOutput)
-protected:
- bool m_dyn_size;
-public:
- ///
- wxVideoOutput();
- ///
- wxVideoOutput(wxWindow *parent, const wxWindowID id,
- const wxPoint& pos = wxDefaultPosition,
- const wxSize& size = wxDefaultSize, const long style = 0,
- const wxString& name = "video_output");
- ///
- virtual ~wxVideoOutput();
-
- ///
- bool DynamicSize() { return m_dyn_size; }
- ///
- void DynamicSize(bool dyn) { m_dyn_size = dyn; }
-};
///
class wxVideoBaseDriver : public wxObject {
///
DECLARE_ABSTRACT_CLASS(wxVideoBaseDriver)
protected:
- wxVideoOutput *m_video_output;
+ wxWindow *m_video_output;
public:
- friend class wxVideoOutput;
-
//
wxVideoBaseDriver();
//
//
virtual ~wxVideoBaseDriver();
-
//
virtual bool Play() = 0;
//
virtual void OnFinished() {}
//
- virtual bool AttachOutput(wxVideoOutput& output);
+ virtual bool AttachOutput(wxWindow& output);
//
virtual void DetachOutput();
};
#else
#include <wx/wx.h>
#endif
+
+// Pizza !
+#include <wx/gtk/win_gtk.h>
+
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#ifdef __WXGTK__
return FALSE;
}
-bool wxVideoXANIM::AttachOutput(wxVideoOutput& out)
+bool wxVideoXANIM::AttachOutput(wxWindow& out)
{
if (!wxVideoBaseDriver::AttachOutput(out))
return FALSE;
return FALSE;
// Check if we can change the size of the window dynamicly
- xanim_chg_size = m_video_output->DynamicSize();
+ xanim_chg_size = TRUE;
// Get current display
#ifdef __WXGTK__
m_internal->xanim_dpy = gdk_display;
// We absolutely need the window to be realized.
- gtk_widget_realize(m_video_output->m_wxwindow);
+ GtkPizza *pizza = GTK_PIZZA( m_video_output->m_wxwindow );
+ GdkWindow *window = pizza->bin_window;
+
m_internal->xanim_window =
- ((GdkWindowPrivate *)m_video_output->m_wxwindow->window)->xwindow;
+ ((GdkWindowPrivate *)window)->xwindow;
#endif
// Get the XANIM atom
m_internal->xanim_atom = XInternAtom(m_internal->xanim_dpy,
bool IsCapable(wxVideoType v_type);
- bool AttachOutput(wxVideoOutput& output);
+ bool AttachOutput(wxWindow& output);
void DetachOutput();
protected: