Removed all wxMMedia2 files

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6462 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Guilhem Lavaux
2000-03-05 19:05:13 +00:00
parent e8482f24cf
commit 5dffa63b2f
75 changed files with 0 additions and 11257 deletions

View File

@@ -1,4 +0,0 @@
all:
cd lib; make
cd sample; make
cd board; make

View File

@@ -1,48 +0,0 @@
--------------------------------------------------------------------------
| wxMultimedia (c) 1998, 1999, 2000 Guilhem Lavaux
| wxWindows license
--------------------------------------------------------------------------
This is the wxMultimedia package. It intends to be a portable way to access
some multimedia component on variable system. For the moment, I implemented
sound, video and CD access.
Sound features:
* low level/OSS style access to the sound card. You can open/setup the
parameters of the sound card then write/read directly to/from it.
* mid level codecs: compressors and sound codec are supported. For the
moment there is a support for G711/G721/G723 and MULAW formats (as well
PCM).
* high level format: WAV file format is supported in read/write and AIFF
format in read only
Sound bugs:
* it seems there are still some bugs in the recording code on Windows
on Cygwin B20.1 (to be verified)
* wave files created with wxSoundWave have some problem with Windows Media
Player (not windows recorder)
Video features:
* high level video file playing: on Unix you can play (through xanim) video
files directly into your application
* MPEG video file to be supported through SMPEG as soon as I have some free
time
Video bugs:
* AVI file works on Windows
CD features:
* standard access to the CDAUDIO interface
CD bugs:
----------------
| INSTALLATION |
----------------
You need to move the three files included in this directory:
- utilsunx.cpp => src/unix
- process.cpp => src/common
- process.h => include/wx
- utilsexc.cpp => src/msw

View File

@@ -1,38 +0,0 @@
#
# File: makefile.unx
# Author: Julian Smart
# Created: 1998
# Updated:
# Copyright: (c) 1998 Julian Smart
#
# "%W% %G%"
#
# Makefile for minimal example (UNIX).
top_srcdir = @top_srcdir@
top_builddir = ../../..
program_dir = utils/wxMMedia2/board
PROGRAM=mmboard
OBJECTS=mmboard.o mmbman.o
EXTRA_CPPFLAGS= -I$(top_srcdir)/utils/wxMMedia2/lib
EXTRA_LIBS= ../lib/libwxmmedia2.a -lesd
# the comment at the end of the next line is needed because otherwise autoconf
# would remove this line completely - it contains a built-in hack to remove
# any VPATH assignment not containing ':'
VPATH = @PATH_IFS@$(top_srcdir)/utils/wxMMedia2/board # ':' for autoconf
include ../../../src/make.env
.SUFFIXES: .o .cpp .c
.cpp.o:
$(CC) -c $(CPPFLAGS) $(EXTRA_CPPFLAGS) -o $@ $<
all: $(PROGRAM)
mmboard: $(OBJECTS)
$(CC) $(LDFLAGS) -o mmboard $(OBJECTS) $(EXTRA_LIBS) $(LDLIBS) $(top_builddir)/lib/@WX_TARGET_LIBRARY@

View File

@@ -1,24 +0,0 @@
/* XPM */
static char * eject_xpm[] = {
"15 16 5 1",
" c None",
". c #949594",
"+ c #000000",
"@ c #FFFFFF",
"# c #8E8E8E",
" . ",
" .+@ ",
" .+++@ ",
" .+++++@ ",
" .+++++++@ ",
" .+++++++++@ ",
" .+++++++++++@ ",
".+############@",
".@@@@@@@@@@@@@@",
" ",
"...............",
".++++++++++++#@",
".++++++++++++#@",
".++++++++++++#@",
".+############@",
".@@@@@@@@@@@@@@"};

View File

@@ -1,20 +0,0 @@
#
# File: makefile.vc
# Author: Julian Smart
# Created: 1999
# Updated:
# Copyright: (c) Julian Smart
#
# Makefile : Builds sample (VC++, WIN32)
# Use FINAL=1 argument to nmake to build final version with no debug info.
# Set WXDIR for your system
WXDIR = $(WXWIN)
EXTRAINC= -I..\lib
EXTRALIBS= $(WXDIR)\lib\mmedia2.lib
PROGRAM=mmboard
OBJECTS = $(PROGRAM).obj mmbman.obj
!include $(WXDIR)\src\makeprog.vc

View File

@@ -1,512 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// 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 "sndbase.h"
#include "sndfile.h"
#include "sndwav.h"
#include "sndaiff.h"
#include "sndpcm.h"
#include "sndulaw.h"
#ifdef __UNIX__
#include "sndoss.h"
#include "sndesd.h"
#endif
#ifdef __WIN32__
#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"
// ----------------------------------------------------------------------------
// 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;
}
void MMBoardSoundFile::SetWindow(wxWindow *window)
{
}
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"));
break;
case MMBoard_AIFF:
return wxString(wxT("AIFF file"));
break;
default:
return wxString(wxT("Unknown file"));
break;
}
}
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;
}
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;
}
void MMBoardVideoFile::SetPosition(MMBoardTime btime)
{
}
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: ");
info += m_video_driver->GetMovieCodec() + "\n";
info += wxT("Audio codec: ");
info += m_video_driver->GetAudioCodec();
info += wxString::Format(" Sample rate: %d Channels: %d\n", m_video_driver->GetSampleRate(),
m_video_driver->GetBPS());
info += wxString::Format(" Frame rate: %.01f", m_video_driver->GetFrameRate());
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
wxMessageBox("You are trying to open a multimedia but you have not devices", "Error", wxOK | wxICON_ERROR, NULL);
return NULL;
}
void MMBoardManager::UnrefSoundStream(wxSoundStream *stream)
{
delete stream;
}
// ----------------------------------------------------------------------------

View File

@@ -1,84 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: mmbman.h
// 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
/////////////////////////////////////////////////////////////////////////////
#ifndef _MMBMAN_APP_H_
#define _MMBMAN_APP_H_
#ifdef __GNUG__
#pragma interface "mmbman.cpp"
#endif
#include "wx/stream.h"
#include "sndbase.h"
// -------------------------------------------------------------------------
// Base structure definitions
// -------------------------------------------------------------------------
typedef struct {
wxUint8 seconds, minutes, hours;
} MMBoardTime;
// -------------------------------------------------------------------------
// Constants
// -------------------------------------------------------------------------
#define MMBoard_NoError 0
#define MMBoard_UnknownFile 1
// -------------------------------------------------------------------------
// Interface definition: MMBoardFile
// -------------------------------------------------------------------------
class MMBoardFile {
public:
MMBoardFile();
virtual ~MMBoardFile();
virtual bool NeedWindow() = 0;
virtual void SetWindow(wxWindow *window) = 0;
virtual void Play() = 0;
virtual void Pause() = 0;
virtual void Resume() = 0;
virtual void Stop() = 0;
virtual MMBoardTime GetPosition() = 0;
virtual MMBoardTime GetLength() = 0;
virtual void SetPosition(MMBoardTime btime) = 0;
virtual bool IsStopped() = 0;
virtual bool IsPaused() = 0;
virtual wxString GetStringType() = 0;
virtual wxString GetStringInformation() = 0;
void SetError(wxUint8 error) { m_error = error; }
wxUint8 GetError() const { return m_error; }
protected:
wxUint8 m_error;
};
// -------------------------------------------------------------------------
// Main manager
// -------------------------------------------------------------------------
class MMBoardManager {
public:
static MMBoardFile *Open(const wxString& filename);
static wxSoundStream *OpenSoundStream();
static void UnrefSoundStream(wxSoundStream *stream);
};
#endif

View File

@@ -1,570 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: mmboard.cpp
// Purpose: Multimedia Library sample
// Author: Guilhem Lavaux (created from minimal by J. Smart)
// Modified by:
// Created: 13/02/2000
// RCS-ID: $Id$
// Copyright: (c) Guilhem Lavaux
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "mmboard.cpp"
#endif
// 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
// ----------------------------------------------------------------------------
// ressources
// ----------------------------------------------------------------------------
// the application icon
#if defined(__WXGTK__) || defined(__WXMOTIF__)
#include "mondrian.xpm"
#endif
// include multimedia classes
#include "sndbase.h"
#ifdef __WIN32__
#include "sndwin.h"
#endif
#ifdef __UNIX__
#include "sndoss.h"
#include "sndesd.h"
#endif
#include "wx/statline.h"
#include "wx/stattext.h"
// include personnal classes
#include "mmboard.h"
#include "mmbman.h"
#include "play.xpm"
#include "stop.xpm"
#include "eject.xpm"
#include "pause.xpm"
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
// Main Multimedia Board frame
class MMBoardFrame : public wxFrame
{
public:
// ctor(s)
MMBoardFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
// dtor
~MMBoardFrame();
// event handlers
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void OnOpen(wxCommandEvent& event);
void OnPlay(wxCommandEvent& event);
void OnStop(wxCommandEvent& event);
void OnPause(wxCommandEvent& event);
void OnEject(wxCommandEvent& event);
void OnRefreshInfo(wxEvent& event);
void OnSetPosition(wxCommandEvent& event);
void OpenVideoWindow();
void CloseVideoWindow();
private:
// any class wishing to process wxWindows events must use this macro
DECLARE_EVENT_TABLE()
private:
void UpdateMMedInfo();
void UpdateInfoText();
MMBoardFile *m_opened_file;
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;
};
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
// IDs for the controls and the menu commands
enum
{
// menu items
MMBoard_Quit = 1,
MMBoard_Open,
MMBoard_About,
MMBoard_PositionSlider,
MMBoard_PlayButton,
MMBoard_PauseButton,
MMBoard_ResumeButton,
MMBoard_StopButton,
MMBoard_EjectButton,
MMBoard_RefreshInfo
};
// ----------------------------------------------------------------------------
// event tables and other macros for wxWindows
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(MMBoardFrame, wxFrame)
EVT_MENU(MMBoard_Quit, MMBoardFrame::OnQuit)
EVT_MENU(MMBoard_About, MMBoardFrame::OnAbout)
EVT_MENU(MMBoard_Open, MMBoardFrame::OnOpen)
EVT_BUTTON(MMBoard_PlayButton, MMBoardFrame::OnPlay)
EVT_BUTTON(MMBoard_StopButton, MMBoardFrame::OnStop)
EVT_BUTTON(MMBoard_PauseButton, MMBoardFrame::OnPause)
EVT_BUTTON(MMBoard_EjectButton, MMBoardFrame::OnEject)
EVT_SLIDER(MMBoard_PositionSlider, MMBoardFrame::OnSetPosition)
EVT_CUSTOM(wxEVT_TIMER, MMBoard_RefreshInfo, MMBoardFrame::OnRefreshInfo)
END_EVENT_TABLE()
// ---------------------------------------------------------------------------
// Main board application launcher
// ---------------------------------------------------------------------------
IMPLEMENT_APP(MMBoardApp)
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// the application class
// ----------------------------------------------------------------------------
bool MMBoardApp::OnInit()
{
// create the main application window
MMBoardFrame *frame = new MMBoardFrame("Multimedia Board",
wxPoint(50, 50), wxSize(450, 340));
// and show it (the frames, unlike simple controls, are not shown when
// created initially)
frame->Show(TRUE);
m_caps = TestMultimediaCaps();
if (!m_caps) {
wxMessageBox("Your system has no multimedia capabilities. We are exiting now.", "Major error !", wxOK | wxICON_ERROR, NULL);
return FALSE;
}
wxString msg;
msg.Printf("Detected : %s%s%s", (m_caps & MM_SOUND_OSS) ? "OSS " : "",
(m_caps & MM_SOUND_ESD) ? "ESD " : "",
(m_caps & MM_SOUND_WIN) ? "WIN" : "");
wxMessageBox(msg, "Good !", wxOK | wxICON_INFORMATION, NULL);
// success: wxApp::OnRun() will be called which will enter the main message
// loop and the application will run. If we returned FALSE here, the
// application would exit immediately.
return TRUE;
}
wxUint8 MMBoardApp::TestMultimediaCaps()
{
wxSoundStream *dev;
wxUint8 caps;
caps = 0;
#ifdef __UNIX__
// We now test the ESD support
dev = new wxSoundStreamESD();
if (dev->GetError() == wxSOUND_NOERROR)
caps |= MM_SOUND_ESD;
delete dev;
// We test the OSS (Open Sound System) support.
// WARNING: There is a conflict between ESD and ALSA
dev = new wxSoundStreamOSS();
if (dev->GetError() == wxSOUND_NOERROR)
caps |= MM_SOUND_OSS;
delete dev;
#endif
#ifdef __WIN32__
// We test the Windows sound support.
dev = new wxSoundStreamWin();
if (dev->GetError() == wxSOUND_NOERR)
caps |= MM_SOUND_WIN;
delete dev;
#endif
return caps;
}
// ----------------------------------------------------------------------------
// main frame
// ----------------------------------------------------------------------------
// frame constructor
MMBoardFrame::MMBoardFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame((wxFrame *)NULL, -1, title, pos, size)
{
#ifdef __WXMAC__
// we need this in order to allow the about menu relocation, since ABOUT is
// not the default id of the about menu
wxApp::s_macAboutMenuItemId = MMBoard_About;
#endif
// set the frame icon
SetIcon(wxICON(mondrian));
// create a menu bar
wxMenu *menuFile = new wxMenu(wxT(""), wxMENU_TEAROFF);
// the "About" item should be in the help menu
wxMenu *helpMenu = new wxMenu;
helpMenu->Append(MMBoard_About, wxT("&About...\tCtrl-A"), wxT("Show about dialog"));
menuFile->Append(MMBoard_Open, wxT("&Open\tAlt-O"), wxT("Open file"));
menuFile->AppendSeparator();
menuFile->Append(MMBoard_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
// now append the freshly created menu to the menu bar...
wxMenuBar *menuBar = new wxMenuBar();
menuBar->Append(menuFile, wxT("&File"));
menuBar->Append(helpMenu, wxT("&Help"));
// ... and attach this menu bar to the frame
SetMenuBar(menuBar);
#if wxUSE_STATUSBAR
// create a status bar just for fun (by default with 1 pane only)
CreateStatusBar(3);
SetStatusText(wxT("Welcome to wxWindows!"));
#endif // wxUSE_STATUSBAR
// Misc variables
m_opened_file = NULL;
m_panel = new wxPanel(this, -1);
// Initialize main slider
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
m_positionSlider->Enable(FALSE);
// Initialize info panel
wxPanel *infoPanel = new wxPanel( m_panel, -1);
infoPanel->SetBackgroundColour(*wxBLACK);
infoPanel->SetForegroundColour(*wxWHITE);
wxBoxSizer *infoSizer = new wxBoxSizer(wxVERTICAL);
m_fileType = new wxStaticText(infoPanel, -1, wxT(""));
wxStaticLine *line = new wxStaticLine(infoPanel, -1);
m_infoText = new wxStaticText(infoPanel, -1, "");
UpdateInfoText();
infoSizer->Add(m_fileType, 0, wxGROW | wxALL, 1);
infoSizer->Add(line, 0, wxGROW | wxCENTRE, 20);
infoSizer->Add(m_infoText, 0, wxGROW | wxALL, 1);
infoPanel->SetSizer(infoSizer);
infoPanel->SetAutoLayout(TRUE);
// Bitmap button panel
wxBoxSizer *buttonSizer = new wxBoxSizer(wxHORIZONTAL);
wxBitmap *play_bmp = new wxBitmap(play_back_xpm);
wxBitmap *stop_bmp = new wxBitmap(stop_back_xpm);
wxBitmap *eject_bmp = new wxBitmap(eject_xpm);
wxBitmap *pause_bmp = new wxBitmap(pause_xpm);
m_playButton = new wxBitmapButton(m_panel, MMBoard_PlayButton, *play_bmp);
m_playButton->Enable(FALSE);
m_pauseButton = new wxBitmapButton(m_panel, MMBoard_PauseButton, *pause_bmp);
m_pauseButton->Enable(FALSE);
m_stopButton = new wxBitmapButton(m_panel, MMBoard_StopButton, *stop_bmp);
m_stopButton->Enable(FALSE);
m_ejectButton = new wxBitmapButton(m_panel, MMBoard_EjectButton, *eject_bmp);
m_ejectButton->Enable(FALSE);
buttonSizer->Add(m_playButton, 0, wxALL, 2);
buttonSizer->Add(m_pauseButton, 0, wxALL, 2);
buttonSizer->Add(m_stopButton, 0, wxALL, 2);
buttonSizer->Add(m_ejectButton, 0, wxALL, 2);
// Top sizer
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);
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()
{
if (m_opened_file)
delete m_opened_file;
delete m_refreshTimer;
}
void MMBoardFrame::OpenVideoWindow()
{
if (m_video_window)
return;
m_video_window = new wxWindow(m_panel, -1, wxDefaultPosition, wxSize(200, 200));
m_video_window->SetBackgroundColour(*wxBLACK);
m_sizer->Prepend(m_video_window, 2, wxGROW | wxSHRINK | wxCENTRE, 1);
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))
{
// TRUE is to force the frame to close
Close(TRUE);
}
void MMBoardFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxString msg;
msg.Printf( wxT("wxWindows Multimedia board v1.0a, wxMMedia v2.0a:\n")
wxT("an example of the capabilities of the wxWindows multimedia classes.\n")
wxT("Copyright 1999, 2000, Guilhem Lavaux.\n"));
wxMessageBox(msg, "About MMBoard", wxOK | wxICON_INFORMATION, this);
}
void MMBoardFrame::OnOpen(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())
return;
m_opened_file = MMBoardManager::Open(selected_file);
// Change the range values of the slider.
MMBoardTime length;
length = m_opened_file->GetLength();
m_positionSlider->SetRange(0, length.hours * 3600 + length.minutes * 60 + length.seconds);
// Update misc info
UpdateMMedInfo();
SetStatusText(selected_file, 2);
// Update info text
UpdateInfoText();
// Enable a few buttons
m_playButton->Enable(TRUE);
m_ejectButton->Enable(TRUE);
m_positionSlider->Enable(TRUE);
if (m_opened_file->NeedWindow()) {
OpenVideoWindow();
m_opened_file->SetWindow(m_video_window);
} else
CloseVideoWindow();
}
void MMBoardFrame::UpdateInfoText()
{
wxString infotext1, infotext2;
if (m_opened_file) {
infotext1 = wxT("File type:\n\t");
infotext1 += m_opened_file->GetStringType() + wxT("\n");
infotext2 = wxT("File informations:\n\n");
infotext2 += m_opened_file->GetStringInformation();
} else {
infotext1 = wxT("File type: \n\tNo file opened");
infotext2 = wxT("File informations:\nNo information\n\n\n\n\n");
}
m_fileType->SetLabel(infotext1);
m_infoText->SetLabel(infotext2);
}
void MMBoardFrame::UpdateMMedInfo()
{
wxString temp_string;
MMBoardTime current, length;
if (m_opened_file) {
current = m_opened_file->GetPosition();
length = m_opened_file->GetLength();
} else {
current.hours = current.minutes = current.seconds = 0;
length = current;
}
// We refresh the status bar
temp_string.Printf(wxT("%02d:%02d / %02d:%02d"), current.hours * 60 + current.minutes,
current.seconds, length.hours * 60 + length.minutes, length.seconds);
SetStatusText(temp_string, 1);
// We set the slider position
m_positionSlider->SetValue(current.hours * 3600 + current.minutes * 60 + current.seconds);
}
// ----------------------------------------------------------------------------
// Playing management, refreshers, ...
void MMBoardFrame::OnRefreshInfo(wxEvent& WXUNUSED(event))
{
UpdateMMedInfo();
if (m_opened_file->IsStopped()) {
m_refreshTimer->Stop();
m_playButton->Enable(TRUE);
m_stopButton->Enable(FALSE);
m_pauseButton->Enable(FALSE);
}
}
void MMBoardFrame::OnPlay(wxCommandEvent& WXUNUSED(event))
{
m_stopButton->Enable(TRUE);
m_pauseButton->Enable(TRUE);
m_playButton->Enable(FALSE);
if (m_opened_file->IsPaused()) {
m_opened_file->Resume();
return;
}
m_refreshTimer->Start(1000, FALSE);
m_opened_file->Play();
m_stopButton->Enable(TRUE);
m_pauseButton->Enable(TRUE);
m_playButton->Enable(FALSE);
}
void MMBoardFrame::OnStop(wxCommandEvent& WXUNUSED(event))
{
m_opened_file->Stop();
m_refreshTimer->Stop();
m_stopButton->Enable(FALSE);
m_playButton->Enable(TRUE);
UpdateMMedInfo();
}
void MMBoardFrame::OnPause(wxCommandEvent& WXUNUSED(event))
{
m_opened_file->Pause();
m_playButton->Enable(TRUE);
m_pauseButton->Enable(FALSE);
}
void MMBoardFrame::OnEject(wxCommandEvent& WXUNUSED(event))
{
m_opened_file->Stop();
delete m_opened_file;
m_opened_file = NULL;
m_playButton->Enable(FALSE);
m_pauseButton->Enable(FALSE);
m_stopButton->Enable(FALSE);
m_ejectButton->Enable(FALSE);
m_positionSlider->Enable(FALSE);
UpdateInfoText();
UpdateMMedInfo();
}
void MMBoardFrame::OnSetPosition(wxCommandEvent& WXUNUSED(event))
{
wxUint32 itime;
MMBoardTime btime;
itime = m_positionSlider->GetValue();
btime.seconds = itime % 60;
btime.minutes = (itime / 60) % 60;
btime.hours = itime / 3600;
m_opened_file->SetPosition(btime);
UpdateMMedInfo();
}

View File

@@ -1,7 +0,0 @@
NAME Minimal
DESCRIPTION 'Minimal wxWindows application'
EXETYPE WINDOWS
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE
HEAPSIZE 4048
STACKSIZE 16000

View File

@@ -1,57 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: mmboard.h
// Purpose: Multimedia Board header
// Author: Guilhem Lavaux, <guilhem.lavaux@libertysurf.fr>
// Modified by:
// Created: 13/02/2000
// RCS-ID: $Id$
// Copyright: (c) 2000, Guilhem Lavaux
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _MMBOARD_APP_H_
#define _MMBOARD_APP_H_
#ifdef __GNUG__
#pragma interface "mmboard.cpp"
#endif
// 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
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
// --------------------------------------------------------------------------
// constants
// --------------------------------------------------------------------------
#define MM_SOUND_OSS 0x01
#define MM_SOUND_ESD 0x02
#define MM_SOUND_WIN 0x04
// --------------------------------------------------------------------------
// Class definitions
// --------------------------------------------------------------------------
// Define a new application type, each program should derive a class from wxApp
class MMBoardApp : public wxApp
{
public:
wxUint8 m_caps;
// override base class virtuals
// ----------------------------
virtual bool OnInit();
wxUint8 TestMultimediaCaps();
};
#endif

View File

@@ -1,6 +0,0 @@
mondrian ICON "mondrian.ico"
#include "wx/msw/wx.rc"
#define MINIMAL_QUIT 1
#define MINIMAL_ABOUT 102

View File

@@ -1,6 +0,0 @@
ICON 1 PRELOAD "mondros2.ico"
#include "H:\DEV\WX2\wxWindows\include\wx\os2\wx.rc"
#define MINIMAL_QUIT 1
#define MINIMAL_ABOUT 102

Binary file not shown.

Before

Width:  |  Height:  |  Size: 766 B

View File

@@ -1,44 +0,0 @@
/* XPM */
static char *mondrian_xpm[] = {
/* columns rows colors chars-per-pixel */
"32 32 6 1",
" c Black",
". c Blue",
"X c #00bf00",
"o c Red",
"O c Yellow",
"+ c Gray100",
/* pixels */
" ",
" oooooo +++++++++++++++++++++++ ",
" oooooo +++++++++++++++++++++++ ",
" oooooo +++++++++++++++++++++++ ",
" oooooo +++++++++++++++++++++++ ",
" oooooo +++++++++++++++++++++++ ",
" oooooo +++++++++++++++++++++++ ",
" oooooo +++++++++++++++++++++++ ",
" ",
" ++++++ ++++++++++++++++++ .... ",
" ++++++ ++++++++++++++++++ .... ",
" ++++++ ++++++++++++++++++ .... ",
" ++++++ ++++++++++++++++++ .... ",
" ++++++ ++++++++++++++++++ .... ",
" ++++++ ++++++++++++++++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++ ",
" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
" "
};

Binary file not shown.

View File

@@ -1,23 +0,0 @@
/* XPM */
static char * pause_xpm[] = {
"13 15 5 1",
" c None",
". c #949594",
"+ c #000000",
"@ c #8E8E8E",
"# c #FFFFFF",
"...... ......",
".+++@# .+++@#",
".+++@# .+++@#",
".+++@# .+++@#",
".+++@# .+++@#",
".+++@# .+++@#",
".+++@# .+++@#",
".+++@# .+++@#",
".+++@# .+++@#",
".+++@# .+++@#",
".+++@# .+++@#",
".+++@# .+++@#",
".+++@# .+++@#",
".+@@@# .+@@@#",
".##### .#####"};

View File

@@ -1,23 +0,0 @@
/* XPM */
static char * play_back_xpm[] = {
"13 15 5 1",
" c None",
". c #949594",
"+ c #000000",
"@ c #8E8E8E",
"# c #FFFFFF",
"...... ",
".+++++. ",
".++++++. ",
".+++++++. ",
".++++++++. ",
".+++++++++. ",
".++++++++++. ",
".++++++++++@#",
".+++++++++@# ",
".++++++++@# ",
".+++++++@# ",
".++++++@# ",
".+++++@# ",
".+@@@@# ",
".##### "};

View File

@@ -1,23 +0,0 @@
/* XPM */
static char * stop_back_xpm[] = {
"13 15 5 1",
" c None",
". c #949594",
"+ c #000000",
"@ c #8E8E8E",
"# c #FFFFFF",
".............",
".++++++++++@#",
".++++++++++@#",
".++++++++++@#",
".++++++++++@#",
".++++++++++@#",
".++++++++++@#",
".++++++++++@#",
".++++++++++@#",
".++++++++++@#",
".++++++++++@#",
".++++++++++@#",
".++++++++++@#",
".+@@@@@@@@@@#",
".############"};

View File

@@ -1,26 +0,0 @@
#
# File: Makefile
# Author: Guilhem Lavaux
# Created: 1998
# Updated:
# Copyright: (c) 1998 Julian Smart
#
# "%W% %G%"
#
# Makefile for wxMultiMedia (UNIX).
top_srcdir = @top_srcdir@/..
top_builddir = ../../..
VPATH= $(top_srcdir)/utils/wxMMedia2/lib
LIBTARGET=libwxmmedia2
OBJECTS=sndbase.o sndcodec.o sndpcm.o sndcpcm.o sndulaw.o sndfile.o sndoss.o\
sndesd.o sndaiff.o sndwav.o sndg72x.o \
g711.o g721.o g723_24.o g723_40.o g72x.o \
cdbase.o cdunix.o \
vidbase.o vidxanm.o
include $(top_builddir)/src/makelib.env

View File

@@ -1,55 +0,0 @@
// ---------------------------------------------------------------------------
// Name: cdbase.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1999
// Copyright: (C) 1997, 1998, 1999 Guilhem Lavaux
// License: wxWindows license
// ---------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation
#endif
#include "wx/wxprec.h"
#include "cdbase.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
IMPLEMENT_ABSTRACT_CLASS(wxCDAudio, wxObject)
wxCDtime wxCDAudio::CDtoc::GetTrackTime(wxUint8 track) const
{
if (track > total_time.track) {
wxCDtime dummy_time = {0, 0, 0, 0};
return dummy_time;
}
return tracks_time[track];
}
wxCDtime wxCDAudio::CDtoc::GetTrackPos(wxUint8 track) const
{
if (track > total_time.track) {
wxCDtime dummy_time = {0, 0, 0, 0};
return dummy_time;
}
return tracks_pos[track];
}
bool wxCDAudio::Play(const wxCDtime& beg_play)
{
return Play(beg_play, GetToc().GetTotalTime());
}
bool wxCDAudio::Play(wxUint8 beg_track, wxUint8 end_track)
{
wxCDtime beg_play = GetToc().GetTrackPos(beg_track);
wxCDtime end_play;
if (end_track)
end_play = GetToc().GetTrackPos(end_track);
else
end_play = GetToc().GetTotalTime();
return Play(beg_play, end_play);
}

View File

@@ -1,76 +0,0 @@
// -*- c++ -*-
// /////////////////////////////////////////////////////////////////////////////
// Name: cdbase.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
#ifndef __CDA_base_H__
#define __CDA_base_H__
#ifdef __GNUG__
#pragma interface
#endif
#include "wx/wxprec.h"
#include "wx/object.h"
typedef struct wxCDtime {
wxUint8 track;
wxUint8 hour, min, sec;
} wxCDtime;
class WXDLLEXPORT wxCDAudio : public wxObject {
DECLARE_ABSTRACT_CLASS(wxCDAudio)
public:
typedef enum { PLAYING, PAUSED, STOPPED } CDstatus;
// Table of contents manager
class CDtoc {
protected:
wxCDtime *tracks_time, *tracks_pos;
wxCDtime total_time;
public:
//
CDtoc(wxCDtime& tot_tm, wxCDtime *trks_tm, wxCDtime *trks_pos)
{ tracks_time = trks_tm; total_time = tot_tm; tracks_pos = trks_pos; }
// Returns the length of the specified track
// track: track to get length
wxCDtime GetTrackTime(wxUint8 track) const;
// Returns the position of the specified track
// track: track to get position
wxCDtime GetTrackPos(wxUint8 track) const;
// Returns the total time
inline wxCDtime GetTotalTime() const { return total_time; }
};
public:
//
wxCDAudio() : wxObject() {}
//
virtual ~wxCDAudio() {}
// Play audio at the specified position
virtual bool Play(const wxCDtime& beg_play, const wxCDtime& end_play) = 0;
// Play audio from the specified to the end of the CD audio
bool Play(const wxCDtime& beg_play);
//
bool Play(wxUint8 beg_track, wxUint8 end_track = 0);
// Pause the audio playing
virtual bool Pause() = 0;
// Resume a paused audio playing
virtual bool Resume() = 0;
// Get the current CD status
virtual CDstatus GetStatus() = 0;
// Get the current playing time
virtual wxCDtime GetTime() = 0;
// Returns the table of contents
virtual const CDtoc& GetToc() = 0;
// CD ok
virtual bool Ok() const = 0;
};
#endif

View File

@@ -1,201 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
// Name: cdlinux.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// CVS Id: $Id$
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "cdunix.h"
#endif
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#ifdef __linux__
#include <linux/cdrom.h>
#else
// For Solaris
#include <sys/cdio.h>
#endif
#ifdef WX_PRECOMP
#include "wx/wxprec.h"
#else
#include "wx/wx.h"
#endif
#include "cdbase.h"
#include "cdunix.h"
IMPLEMENT_DYNAMIC_CLASS(wxCDAudioLinux, wxCDAudio)
wxCDAudioLinux::wxCDAudioLinux()
: wxCDAudio(), m_fd(-1)
{
OpenDevice("/dev/cdrom");
}
wxCDAudioLinux::wxCDAudioLinux(const char *dev_name)
: wxCDAudio(), m_fd(-1)
{
OpenDevice(dev_name);
}
wxCDAudioLinux::~wxCDAudioLinux()
{
if (m_fd != -1) {
close(m_fd);
wxDELETE(m_trksize);
wxDELETE(m_trkpos);
}
}
void wxCDAudioLinux::OpenDevice(const char *dev_name)
{
struct cdrom_tocentry entry, old_entry;
struct cdrom_tochdr diskinf;
struct cdrom_msf0 *msf = &entry.cdte_addr.msf,
*old_msf = &old_entry.cdte_addr.msf;
wxCDtime *the_track;
wxCDtime tot_tm;
wxUint8 nb_tracks, i;
int hour, minute, second;
if (m_fd != -1)
return;
m_fd = open(dev_name, O_RDONLY);
if (m_fd == -1) {
m_toc = NULL;
return;
}
m_status = STOPPED;
ioctl(m_fd, CDROMREADTOCHDR, &diskinf);
nb_tracks = diskinf.cdth_trk1-diskinf.cdth_trk0+1;
m_trksize = new wxCDtime[nb_tracks+1];
m_trkpos = new wxCDtime[nb_tracks+1];
old_msf->minute = 0;
old_msf->second = 0;
for (i=diskinf.cdth_trk0;i<=diskinf.cdth_trk1;i++) {
entry.cdte_track = i;
entry.cdte_format = CDROM_MSF;
ioctl(m_fd, CDROMREADTOCENTRY, &entry);
minute = msf->minute - old_msf->minute;
second = msf->second - old_msf->second;
if (second < 0) {
minute--;
second += 60;
}
hour = minute / 60;
minute %= 60;
the_track = &m_trksize[i-diskinf.cdth_trk0];
the_track->track = i-diskinf.cdth_trk0;
the_track->hour = hour;
the_track->min = minute;
the_track->sec = second;
the_track = &m_trkpos[i-diskinf.cdth_trk0];
the_track->track = i-diskinf.cdth_trk0;
the_track->hour = old_msf->minute / 60;
the_track->min = old_msf->minute % 60;
the_track->sec = old_msf->second;
old_entry = entry;
}
entry.cdte_track = CDROM_LEADOUT;
entry.cdte_format = CDROM_MSF;
ioctl(m_fd, CDROMREADTOCENTRY, &entry);
tot_tm.track = nb_tracks;
tot_tm.hour = msf->minute / 60;
tot_tm.min = msf->minute % 60;
tot_tm.sec = msf->second % 60;
m_trksize[nb_tracks].track = nb_tracks;
minute = msf->minute - old_msf->minute;
second = msf->second - old_msf->second;
if (second < 0) {
minute--;
second += 60;
}
hour = minute / 60;
minute %= 60;
m_trksize[nb_tracks].hour = hour;
m_trksize[nb_tracks].min = minute;
m_trksize[nb_tracks].sec = second;
m_trkpos[nb_tracks].track = nb_tracks;
m_trkpos[nb_tracks].hour = old_msf->minute / 60;
m_trkpos[nb_tracks].min = old_msf->minute % 60;
m_trkpos[nb_tracks].sec = old_msf->second;
m_toc = new CDtoc(tot_tm, m_trksize, m_trkpos);
}
bool wxCDAudioLinux::Play(const wxCDtime& beg_time, const wxCDtime& end_time)
{
struct cdrom_msf track_msf;
track_msf.cdmsf_min0 = beg_time.hour * 60 + beg_time.min;
track_msf.cdmsf_sec0 = beg_time.sec;
track_msf.cdmsf_frame0 = 0;
track_msf.cdmsf_min1 = end_time.hour * 60 + end_time.min;
track_msf.cdmsf_sec1 = end_time.sec;
track_msf.cdmsf_frame1 = 0;
return (ioctl(m_fd, CDROMPLAYMSF, &track_msf) != -1);
}
bool wxCDAudioLinux::Pause()
{
return (ioctl(m_fd, CDROMPAUSE, 0) != -1);
}
bool wxCDAudioLinux::Resume()
{
return (ioctl(m_fd, CDROMRESUME, 0) != -1);
}
wxCDAudio::CDstatus wxCDAudioLinux::GetStatus()
{
struct cdrom_subchnl subchnl;
ioctl(m_fd, CDROMSUBCHNL, &subchnl);
switch (subchnl.cdsc_audiostatus) {
case CDROM_AUDIO_PLAY: return PLAYING;
case CDROM_AUDIO_PAUSED: return PAUSED;
case CDROM_AUDIO_COMPLETED: return STOPPED;
}
return STOPPED;
}
wxCDtime wxCDAudioLinux::GetTime()
{
wxCDtime cdtime;
struct cdrom_subchnl subchnl;
ioctl(m_fd, CDROMSUBCHNL, &subchnl);
cdtime.track = subchnl.cdsc_trk;
cdtime.min = subchnl.cdsc_reladdr.msf.minute;
cdtime.hour = cdtime.min / 60;
cdtime.min %= 60;
cdtime.sec = subchnl.cdsc_reladdr.msf.second;
return cdtime;
}
wxCDAudio::CDtoc& wxCDAudioLinux::GetToc()
{
return *m_toc;
}

View File

@@ -1,60 +0,0 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: cdunix.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
#ifndef __CDUNIXH__
#define __CDUNIXH__
#ifdef __GNUG__
#pragma interface
#endif
#ifdef WX_PRECOMP
#include "wx/wxprec.h"
#else
#include "wx/wx.h"
#endif
#include "cdbase.h"
///
class WXDLLEXPORT wxCDAudioLinux : public wxCDAudio {
DECLARE_DYNAMIC_CLASS(wxCDAudioLinux)
protected:
wxCDtime m_time;
CDstatus m_status;
CDtoc *m_toc;
int m_fd;
wxCDtime *m_trksize, *m_trkpos;
public:
///
wxCDAudioLinux();
///
wxCDAudioLinux(const char *dev_name);
///
virtual ~wxCDAudioLinux();
///
virtual bool Play(const wxCDtime& beg_time, const wxCDtime& end_time);
///
virtual bool Pause();
///
virtual bool Resume();
///
virtual CDstatus GetStatus();
///
virtual wxCDtime GetTime();
///
virtual CDtoc& GetToc();
///
virtual inline bool Ok() const { return (m_fd != -1); }
protected:
///
void OpenDevice(const char *dev_name);
};
#endif

View File

@@ -1,202 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
// Name: cdwin.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "cdwin.h"
#endif
#include <windows.h>
#include <stdio.h>
#include <mmsystem.h>
#include "wx/wxprec.h"
#define WXMMEDIA_INTERNAL
#include "cdbase.h"
#include "cdwin.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
wxCDAudioWin::wxCDAudioWin(void)
: wxCDAudio(), m_trksize(NULL), m_trkpos(NULL), m_ok(TRUE), m_toc(NULL)
{
MCI_OPEN_PARMS open_struct;
MCI_SET_PARMS set_struct;
DWORD ret;
m_internal = new CDAW_Internal;
open_struct.lpstrDeviceType = "cdaudio";
ret = mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE,
(DWORD)&open_struct);
if (ret) {
m_ok = FALSE;
return;
}
m_internal->dev_id = open_struct.wDeviceID;
set_struct.dwTimeFormat = MCI_FORMAT_MSF;
ret = mciSendCommand(m_internal->dev_id, MCI_SET, MCI_SET_TIME_FORMAT,
(DWORD)(LPVOID)&set_struct);
PrepareToc();
set_struct.dwTimeFormat = MCI_FORMAT_TMSF;
ret = mciSendCommand(m_internal->dev_id, MCI_SET, MCI_SET_TIME_FORMAT,
(DWORD)(LPVOID)&set_struct);
}
wxCDAudioWin::~wxCDAudioWin(void)
{
if (m_ok) {
mciSendCommand(m_internal->dev_id, MCI_CLOSE, 0, NULL);
delete m_toc;
delete[] m_trksize;
delete[] m_trkpos;
}
delete m_internal;
}
void wxCDAudioWin::PrepareToc(void)
{
MCI_STATUS_PARMS status_struct;
wxUint16 i, nb_m_trksize;
wxCDtime total_time, *trk;
DWORD ret, tmem;
if (!m_ok)
return;
status_struct.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
ret = mciSendCommand(m_internal->dev_id, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)&status_struct);
nb_m_trksize = status_struct.dwReturn;
m_trksize = new wxCDtime[nb_m_trksize+1];
m_trkpos = new wxCDtime[nb_m_trksize+1];
status_struct.dwItem = MCI_STATUS_LENGTH;
ret = mciSendCommand(m_internal->dev_id, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)&status_struct);
total_time.track = nb_m_trksize;
tmem = status_struct.dwReturn;
total_time.min = MCI_MSF_MINUTE(tmem);
total_time.sec = MCI_MSF_SECOND(tmem);
total_time.hour = total_time.min / 60;
total_time.min %= 60;
for (i=1;i<=nb_m_trksize;i++) {
status_struct.dwItem = MCI_STATUS_POSITION;
status_struct.dwTrack = i;
ret = mciSendCommand(m_internal->dev_id, MCI_STATUS,
MCI_STATUS_ITEM | MCI_TRACK,
(DWORD)(LPVOID)&status_struct);
tmem = status_struct.dwReturn;
trk = &m_trkpos[i];
trk->track = i;
trk->min = MCI_MSF_MINUTE(tmem);
trk->sec = MCI_MSF_SECOND(tmem);
trk->hour = trk->min / 60;
trk->min %= 60;
status_struct.dwItem = MCI_STATUS_LENGTH;
status_struct.dwTrack = i;
ret = mciSendCommand(m_internal->dev_id, MCI_STATUS,
MCI_STATUS_ITEM | MCI_TRACK,
(DWORD)(LPVOID)&status_struct);
tmem = status_struct.dwReturn;
trk = &m_trksize[i];
trk->track = i;
trk->min = MCI_MSF_MINUTE(tmem);
trk->sec = MCI_MSF_SECOND(tmem);
trk->hour = trk->min / 60;
trk->min %= 60;
}
m_toc = new CDtoc(total_time, m_trksize, m_trkpos);
}
bool wxCDAudioWin::Play(const wxCDtime& beg_time, const wxCDtime& end_time)
{
DWORD tmsf;
MCI_PLAY_PARMS play_struct;
if (!m_ok)
return FALSE;
tmsf = MCI_MAKE_TMSF(beg_time.track, beg_time.min,
beg_time.sec, 0);
play_struct.dwFrom = tmsf;
tmsf = MCI_MAKE_TMSF(end_time.track, end_time.min,
end_time.sec, 0);
play_struct.dwTo = tmsf;
mciSendCommand(m_internal->dev_id, MCI_PLAY, 0, (DWORD)&play_struct);
return TRUE;
}
bool wxCDAudioWin::Pause(void)
{
if (!m_ok)
return FALSE;
return (mciSendCommand(m_internal->dev_id, MCI_PAUSE, 0, 0) == 0);
}
bool wxCDAudioWin::Resume(void)
{
if (!m_ok)
return FALSE;
return (mciSendCommand(m_internal->dev_id, MCI_RESUME, 0, 0) == 0);
}
wxCDAudio::CDstatus wxCDAudioWin::GetStatus(void)
{
MCI_STATUS_PARMS status_struct;
if (!m_ok)
return STOPPED;
status_struct.dwItem = MCI_STATUS_MODE;
mciSendCommand(m_internal->dev_id, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)&status_struct);
switch (status_struct.dwReturn) {
case MCI_MODE_PAUSE:
return PAUSED;
case MCI_MODE_PLAY:
return PLAYING;
}
return STOPPED;
}
wxCDtime wxCDAudioWin::GetTime(void)
{
MCI_STATUS_PARMS status_struct;
wxCDtime cd_time = {-1, -1, -1, -1};
if (!m_ok)
return cd_time;
status_struct.dwItem = MCI_STATUS_TIME_FORMAT;
mciSendCommand(m_internal->dev_id, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)&status_struct);
cd_time.track = MCI_TMSF_TRACK(status_struct.dwReturn);
cd_time.min = MCI_TMSF_MINUTE(status_struct.dwReturn);
cd_time.sec = MCI_TMSF_SECOND(status_struct.dwReturn);
cd_time.hour = cd_time.min / 60;
cd_time.min %= 60;
return cd_time;
}
const wxCDAudio::CDtoc& wxCDAudioWin::GetToc(void)
{
return *m_toc;
}

View File

@@ -1,62 +0,0 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: cdwin.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
#ifndef __CDA_win_H__
#define __CDA_win_H__
#ifdef __GNUG__
#pragma interface
#endif
#include "wx/wxprec.h"
#include "cdbase.h"
#ifdef WXMMEDIA_INTERNAL
#include <windows.h>
#include <mmsystem.h>
typedef struct CDAW_Internal {
MCIDEVICEID dev_id;
} CDAW_Internal;
#endif
///
class WXDLLEXPORT wxCDAudioWin : public wxCDAudio {
DECLARE_DYNAMIC_CLASS(wxCDAudioWin)
protected:
struct CDAW_Internal *m_internal;
wxCDtime *m_trksize, *m_trkpos;
CDtoc *m_toc;
bool m_ok;
public:
///
wxCDAudioWin(void);
///
wxCDAudioWin(const char *dev_name);
///
virtual ~wxCDAudioWin(void);
///
virtual bool Play(const wxCDtime& beg_time, const wxCDtime& end_time);
///
virtual bool Pause(void);
///
virtual bool Resume(void);
///
virtual CDstatus GetStatus(void);
///
virtual wxCDtime GetTime(void);
///
virtual const CDtoc& GetToc(void);
///
virtual inline bool Ok(void) const { return m_ok; }
protected:
void PrepareToc();
};
#endif

View File

@@ -1,39 +0,0 @@
#define DEFINE_CONV(name, input_type, output_type, convert) \
static void Convert_##name##(const void *buf_in, void *buf_out, wxUint32 len) \
{\
register input_type src; \
register const input_type *t_buf_in = (input_type *)buf_in; \
register output_type *t_buf_out = (output_type *)buf_out; \
\
while (len > 0) { \
src = *t_buf_in++; \
*t_buf_out++ = convert; \
len -= sizeof(input_type); \
} \
}
// TODO: define converters for all other formats (32, 24)
DEFINE_CONV(8_8_sign, wxUint8, wxUint8, (src ^ 0x80))
DEFINE_CONV(8_16, wxUint8, wxUint16, (((wxUint16)src) << 8))
DEFINE_CONV(8_16_swap, wxUint8, wxUint16, (src))
DEFINE_CONV(8_16_sign, wxUint8, wxUint16, (((wxUint16)(src ^ 0x80)) << 8))
DEFINE_CONV(8_16_sign_swap, wxUint8, wxUint16, (src ^ 0x80))
DEFINE_CONV(16_8, wxUint16, wxUint8, (wxUint8)(src >> 8))
DEFINE_CONV(16_8_sign, wxUint16, wxUint8, (wxUint8)((src >> 8) ^ 0x80))
DEFINE_CONV(16_swap_8, wxUint16, wxUint8, (wxUint8)(src & 0xff))
DEFINE_CONV(16_swap_8_sign, wxUint16, wxUint8, (wxUint8)((src & 0xff) ^ 0x80))
//DEFINE_CONV(24_8, wxUint32, wxUint8, (wxUint8)(src >> 16))
//DEFINE_CONV(24_8_sig, wxUint32, wxUint8, (wxUint8)((src >> 16) ^ 0x80))
//DEFINE_CONV(32_8, wxUint32, wxUint8, (wxUint8)(src >> 24))
DEFINE_CONV(16_sign, wxUint16, wxUint16, (src ^ 0x8000))
DEFINE_CONV(16_swap, wxUint16, wxUint16, (((src & 0xff) << 8) | ((src >> 8) & 0xff)))
// Problem.
DEFINE_CONV(16_swap_16_sign, wxUint16, wxUint16, ((((src & 0xff) << 8) | ((src >> 8) & 0xff)) ^ 0x80))
// DEFINE_CONV(16_sign_16_swap, wxUint16, wxUint16, ((((src & 0xff) << 8) | ((src >> 8) & 0xff)) ^ 0x8000))
DEFINE_CONV(16_swap_16_sign_swap, wxUint16, wxUint16, (src ^ 0x80))

View File

@@ -1,285 +0,0 @@
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use. Users may copy or modify this source code without
* charge.
*
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#include <wx/wxprec.h>
/*
* g711.c
*
* u-law, A-law and linear PCM conversions.
*/
#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
#define QUANT_MASK (0xf) /* Quantization field mask. */
#define NSEGS (8) /* Number of A-law segments. */
#define SEG_SHIFT (4) /* Left shift for segment number. */
#define SEG_MASK (0x70) /* Segment field mask. */
static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,
0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
/* copy from CCITT G.711 specifications */
unsigned char _u2a[128] = { /* u- to A-law conversions */
1, 1, 2, 2, 3, 3, 4, 4,
5, 5, 6, 6, 7, 7, 8, 8,
9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24,
25, 27, 29, 31, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44,
46, 48, 49, 50, 51, 52, 53, 54,
55, 56, 57, 58, 59, 60, 61, 62,
64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79,
81, 82, 83, 84, 85, 86, 87, 88,
89, 90, 91, 92, 93, 94, 95, 96,
97, 98, 99, 100, 101, 102, 103, 104,
105, 106, 107, 108, 109, 110, 111, 112,
113, 114, 115, 116, 117, 118, 119, 120,
121, 122, 123, 124, 125, 126, 127, 128};
unsigned char _a2u[128] = { /* A- to u-law conversions */
1, 3, 5, 7, 9, 11, 13, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
32, 32, 33, 33, 34, 34, 35, 35,
36, 37, 38, 39, 40, 41, 42, 43,
44, 45, 46, 47, 48, 48, 49, 49,
50, 51, 52, 53, 54, 55, 56, 57,
58, 59, 60, 61, 62, 63, 64, 64,
65, 66, 67, 68, 69, 70, 71, 72,
73, 74, 75, 76, 77, 78, 79, 79,
80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99, 100, 101, 102, 103,
104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 122, 123, 124, 125, 126, 127};
static int
search(
int val,
short *table,
int size)
{
int i;
for (i = 0; i < size; i++) {
if (val <= *table++)
return (i);
}
return (size);
}
/*
* linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
*
* linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
*
* Linear Input Code Compressed Code
* ------------------------ ---------------
* 0000000wxyza 000wxyz
* 0000001wxyza 001wxyz
* 000001wxyzab 010wxyz
* 00001wxyzabc 011wxyz
* 0001wxyzabcd 100wxyz
* 001wxyzabcde 101wxyz
* 01wxyzabcdef 110wxyz
* 1wxyzabcdefg 111wxyz
*
* For further information see John C. Bellamy's Digital Telephony, 1982,
* John Wiley & Sons, pps 98-111 and 472-476.
*/
unsigned char
linear2alaw(
int pcm_val) /* 2's complement (16-bit range) */
{
int mask;
int seg;
unsigned char aval;
if (pcm_val >= 0) {
mask = 0xD5; /* sign (7th) bit = 1 */
} else {
mask = 0x55; /* sign bit = 0 */
pcm_val = -pcm_val - 8;
}
/* Convert the scaled magnitude to segment number. */
seg = search(pcm_val, seg_end, 8);
/* Combine the sign, segment, and quantization bits. */
if (seg >= 8) /* out of range, return maximum value. */
return (0x7F ^ mask);
else {
aval = seg << SEG_SHIFT;
if (seg < 2)
aval |= (pcm_val >> 4) & QUANT_MASK;
else
aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
return (aval ^ mask);
}
}
/*
* alaw2linear() - Convert an A-law value to 16-bit linear PCM
*
*/
int
alaw2linear(
unsigned char a_val)
{
int t;
int seg;
a_val ^= 0x55;
t = (a_val & QUANT_MASK) << 4;
seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
switch (seg) {
case 0:
t += 8;
break;
case 1:
t += 0x108;
break;
default:
t += 0x108;
t <<= seg - 1;
}
return ((a_val & SIGN_BIT) ? t : -t);
}
#define BIAS (0x84) /* Bias for linear code. */
/*
* linear2ulaw() - Convert a linear PCM value to u-law
*
* In order to simplify the encoding process, the original linear magnitude
* is biased by adding 33 which shifts the encoding range from (0 - 8158) to
* (33 - 8191). The result can be seen in the following encoding table:
*
* Biased Linear Input Code Compressed Code
* ------------------------ ---------------
* 00000001wxyza 000wxyz
* 0000001wxyzab 001wxyz
* 000001wxyzabc 010wxyz
* 00001wxyzabcd 011wxyz
* 0001wxyzabcde 100wxyz
* 001wxyzabcdef 101wxyz
* 01wxyzabcdefg 110wxyz
* 1wxyzabcdefgh 111wxyz
*
* Each biased linear code has a leading 1 which identifies the segment
* number. The value of the segment number is equal to 7 minus the number
* of leading 0's. The quantization interval is directly available as the
* four bits wxyz. * The trailing bits (a - h) are ignored.
*
* Ordinarily the complement of the resulting code word is used for
* transmission, and so the code word is complemented before it is returned.
*
* For further information see John C. Bellamy's Digital Telephony, 1982,
* John Wiley & Sons, pps 98-111 and 472-476.
*/
unsigned char
linear2ulaw(
int pcm_val) /* 2's complement (16-bit range) */
{
int mask;
int seg;
unsigned char uval;
/* Get the sign and the magnitude of the value. */
if (pcm_val < 0) {
pcm_val = BIAS - pcm_val;
mask = 0x7F;
} else {
pcm_val += BIAS;
mask = 0xFF;
}
/* Convert the scaled magnitude to segment number. */
seg = search(pcm_val, seg_end, 8);
/*
* Combine the sign, segment, quantization bits;
* and complement the code word.
*/
if (seg >= 8) /* out of range, return maximum value. */
return (0x7F ^ mask);
else {
uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
return (uval ^ mask);
}
}
/*
* ulaw2linear() - Convert a u-law value to 16-bit linear PCM
*
* First, a biased linear code is derived from the code word. An unbiased
* output can then be obtained by subtracting 33 from the biased code.
*
* Note that this function expects to be passed the complement of the
* original code word. This is in keeping with ISDN conventions.
*/
int
ulaw2linear(
unsigned char u_val)
{
int t;
/* Complement to obtain normal u-law value. */
u_val = ~u_val;
/*
* Extract and bias the quantization bits. Then
* shift up by the segment number and subtract out the bias.
*/
t = ((u_val & QUANT_MASK) << 3) + BIAS;
t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
}
/* A-law to u-law conversion */
unsigned char
alaw2ulaw(
unsigned char aval)
{
aval &= 0xff;
return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
(0x7F ^ _a2u[aval ^ 0x55]));
}
/* u-law to A-law conversion */
unsigned char
ulaw2alaw(
unsigned char uval)
{
uval &= 0xff;
return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
(0x55 ^ (_u2a[0x7F ^ uval] - 1)));
}

View File

@@ -1,175 +0,0 @@
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use. Users may copy or modify this source code without
* charge.
*
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#include <wx/wxprec.h>
/*
* g721.c
*
* Description:
*
* g721_encoder(), g721_decoder()
*
* These routines comprise an implementation of the CCITT G.721 ADPCM
* coding algorithm. Essentially, this implementation is identical to
* the bit level description except for a few deviations which
* take advantage of work station attributes, such as hardware 2's
* complement arithmetic and large memory. Specifically, certain time
* consuming operations such as multiplications are replaced
* with lookup tables and software 2's complement operations are
* replaced with hardware 2's complement.
*
* The deviation from the bit level specification (lookup tables)
* preserves the bit level performance specifications.
*
* As outlined in the G.721 Recommendation, the algorithm is broken
* down into modules. Each section of code below is preceded by
* the name of the module which it is implementing.
*
*/
#include "g72x.h"
static short qtab_721[7] = {-124, 80, 178, 246, 300, 349, 400};
/*
* Maps G.721 code word to reconstructed scale factor normalized log
* magnitude values.
*/
static short _dqlntab[16] = {-2048, 4, 135, 213, 273, 323, 373, 425,
425, 373, 323, 273, 213, 135, 4, -2048};
/* Maps G.721 code word to log of scale factor multiplier. */
static short _witab[16] = {-12, 18, 41, 64, 112, 198, 355, 1122,
1122, 355, 198, 112, 64, 41, 18, -12};
/*
* Maps G.721 code words to a set of values whose long and short
* term averages are computed and then compared to give an indication
* how stationary (steady state) the signal is.
*/
static short _fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00,
0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0};
/*
* g721_encoder()
*
* Encodes the input vale of linear PCM, A-law or u-law data sl and returns
* the resulting code. -1 is returned for unknown input coding value.
*/
int
g721_encoder(
int sl,
int in_coding,
struct g72x_state *state_ptr)
{
short sezi, se, sez; /* ACCUM */
short d; /* SUBTA */
short sr; /* ADDB */
short y; /* MIX */
short dqsez; /* ADDC */
short dq, i;
switch (in_coding) { /* linearize input sample to 14-bit PCM */
case AUDIO_ENCODING_ALAW:
sl = alaw2linear(sl) >> 2;
break;
case AUDIO_ENCODING_ULAW:
sl = ulaw2linear(sl) >> 2;
break;
case AUDIO_ENCODING_LINEAR:
sl = ((short)sl) >> 2; /* 14-bit dynamic range */
break;
default:
return (-1);
}
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
se = (sezi + predictor_pole(state_ptr)) >> 1; /* estimated signal */
d = sl - se; /* estimation difference */
/* quantize the prediction difference */
y = step_size(state_ptr); /* quantizer step size */
i = quantize(d, y, qtab_721, 7); /* i = ADPCM code */
dq = reconstruct(i & 8, _dqlntab[i], y); /* quantized est diff */
sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconst. signal */
dqsez = sr + sez - se; /* pole prediction diff. */
update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
return (i);
}
/*
* g721_decoder()
*
* Description:
*
* Decodes a 4-bit code of G.721 encoded data of i and
* returns the resulting linear PCM, A-law or u-law value.
* return -1 for unknown out_coding value.
*/
int
g721_decoder(
int i,
int out_coding,
struct g72x_state *state_ptr)
{
short sezi, sei, sez, se; /* ACCUM */
short y; /* MIX */
short sr; /* ADDB */
short dq;
short dqsez;
i &= 0x0f; /* mask to get proper bits */
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
y = step_size(state_ptr); /* dynamic quantizer step size */
dq = reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */
sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq; /* reconst. signal */
dqsez = sr - se + sez; /* pole prediction diff. */
update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
switch (out_coding) {
case AUDIO_ENCODING_ALAW:
return (tandem_adjust_alaw(sr, se, y, i, 8, qtab_721));
case AUDIO_ENCODING_ULAW:
return (tandem_adjust_ulaw(sr, se, y, i, 8, qtab_721));
case AUDIO_ENCODING_LINEAR:
return (sr << 2); /* sr was 14-bit dynamic range */
default:
return (-1);
}
}

View File

@@ -1,159 +0,0 @@
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use. Users may copy or modify this source code without
* charge.
*
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* g723_24.c
*
* Description:
*
* g723_24_encoder(), g723_24_decoder()
*
* These routines comprise an implementation of the CCITT G.723 24 Kbps
* ADPCM coding algorithm. Essentially, this implementation is identical to
* the bit level description except for a few deviations which take advantage
* of workstation attributes, such as hardware 2's complement arithmetic.
*
*/
#include <wx/wxprec.h>
#include "g72x.h"
/*
* Maps G.723_24 code word to reconstructed scale factor normalized log
* magnitude values.
*/
static short _dqlntab[8] = {-2048, 135, 273, 373, 373, 273, 135, -2048};
/* Maps G.723_24 code word to log of scale factor multiplier. */
static short _witab[8] = {-128, 960, 4384, 18624, 18624, 4384, 960, -128};
/*
* Maps G.723_24 code words to a set of values whose long and short
* term averages are computed and then compared to give an indication
* how stationary (steady state) the signal is.
*/
static short _fitab[8] = {0, 0x200, 0x400, 0xE00, 0xE00, 0x400, 0x200, 0};
static short qtab_723_24[3] = {8, 218, 331};
/*
* g723_24_encoder()
*
* Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code.
* Returns -1 if invalid input coding value.
*/
int
g723_24_encoder(
int sl,
int in_coding,
struct g72x_state *state_ptr)
{
short sei, sezi, se, sez; /* ACCUM */
short d; /* SUBTA */
short y; /* MIX */
short sr; /* ADDB */
short dqsez; /* ADDC */
short dq, i;
switch (in_coding) { /* linearize input sample to 14-bit PCM */
case AUDIO_ENCODING_ALAW:
sl = alaw2linear(sl) >> 2;
break;
case AUDIO_ENCODING_ULAW:
sl = ulaw2linear(sl) >> 2;
break;
case AUDIO_ENCODING_LINEAR:
sl = ((short)sl) >> 2; /* sl of 14-bit dynamic range */
break;
default:
return (-1);
}
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
d = sl - se; /* d = estimation diff. */
/* quantize prediction difference d */
y = step_size(state_ptr); /* quantizer step size */
i = quantize(d, y, qtab_723_24, 3); /* i = ADPCM code */
dq = reconstruct(i & 4, _dqlntab[i], y); /* quantized diff. */
sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconstructed signal */
dqsez = sr + sez - se; /* pole prediction diff. */
update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
return (i);
}
/*
* g723_24_decoder()
*
* Decodes a 3-bit CCITT G.723_24 ADPCM code and returns
* the resulting 16-bit linear PCM, A-law or u-law sample value.
* -1 is returned if the output coding is unknown.
*/
int
g723_24_decoder(
int i,
int out_coding,
struct g72x_state *state_ptr)
{
short sezi, sei, sez, se; /* ACCUM */
short y; /* MIX */
short sr; /* ADDB */
short dq;
short dqsez;
i &= 0x07; /* mask to get proper bits */
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
y = step_size(state_ptr); /* adaptive quantizer step size */
dq = reconstruct(i & 0x04, _dqlntab[i], y); /* unquantize pred diff */
sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); /* reconst. signal */
dqsez = sr - se + sez; /* pole prediction diff. */
update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
switch (out_coding) {
case AUDIO_ENCODING_ALAW:
return (tandem_adjust_alaw(sr, se, y, i, 4, qtab_723_24));
case AUDIO_ENCODING_ULAW:
return (tandem_adjust_ulaw(sr, se, y, i, 4, qtab_723_24));
case AUDIO_ENCODING_LINEAR:
return (sr << 2); /* sr was of 14-bit dynamic range */
default:
return (-1);
}
}

View File

@@ -1,179 +0,0 @@
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use. Users may copy or modify this source code without
* charge.
*
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* g723_40.c
*
* Description:
*
* g723_40_encoder(), g723_40_decoder()
*
* These routines comprise an implementation of the CCITT G.723 40Kbps
* ADPCM coding algorithm. Essentially, this implementation is identical to
* the bit level description except for a few deviations which
* take advantage of workstation attributes, such as hardware 2's
* complement arithmetic.
*
* The deviation from the bit level specification (lookup tables),
* preserves the bit level performance specifications.
*
* As outlined in the G.723 Recommendation, the algorithm is broken
* down into modules. Each section of code below is preceded by
* the name of the module which it is implementing.
*
*/
#include <wx/wxprec.h>
#include "g72x.h"
/*
* Maps G.723_40 code word to ructeconstructed scale factor normalized log
* magnitude values.
*/
static short _dqlntab[32] = {-2048, -66, 28, 104, 169, 224, 274, 318,
358, 395, 429, 459, 488, 514, 539, 566,
566, 539, 514, 488, 459, 429, 395, 358,
318, 274, 224, 169, 104, 28, -66, -2048};
/* Maps G.723_40 code word to log of scale factor multiplier. */
static short _witab[32] = {448, 448, 768, 1248, 1280, 1312, 1856, 3200,
4512, 5728, 7008, 8960, 11456, 14080, 16928, 22272,
22272, 16928, 14080, 11456, 8960, 7008, 5728, 4512,
3200, 1856, 1312, 1280, 1248, 768, 448, 448};
/*
* Maps G.723_40 code words to a set of values whose long and short
* term averages are computed and then compared to give an indication
* how stationary (steady state) the signal is.
*/
static short _fitab[32] = {0, 0, 0, 0, 0, 0x200, 0x200, 0x200,
0x200, 0x200, 0x400, 0x600, 0x800, 0xA00, 0xC00, 0xC00,
0xC00, 0xC00, 0xA00, 0x800, 0x600, 0x400, 0x200, 0x200,
0x200, 0x200, 0x200, 0, 0, 0, 0, 0};
static short qtab_723_40[15] = {-122, -16, 68, 139, 198, 250, 298, 339,
378, 413, 445, 475, 502, 528, 553};
/*
* g723_40_encoder()
*
* Encodes a 16-bit linear PCM, A-law or u-law input sample and retuens
* the resulting 5-bit CCITT G.723 40Kbps code.
* Returns -1 if the input coding value is invalid.
*/
int
g723_40_encoder(
int sl,
int in_coding,
struct g72x_state *state_ptr)
{
short sei, sezi, se, sez; /* ACCUM */
short d; /* SUBTA */
short y; /* MIX */
short sr; /* ADDB */
short dqsez; /* ADDC */
short dq, i;
switch (in_coding) { /* linearize input sample to 14-bit PCM */
case AUDIO_ENCODING_ALAW:
sl = alaw2linear(sl) >> 2;
break;
case AUDIO_ENCODING_ULAW:
sl = ulaw2linear(sl) >> 2;
break;
case AUDIO_ENCODING_LINEAR:
sl = ((short) sl) >> 2; /* sl of 14-bit dynamic range */
break;
default:
return (-1);
}
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
d = sl - se; /* d = estimation difference */
/* quantize prediction difference */
y = step_size(state_ptr); /* adaptive quantizer step size */
i = quantize(d, y, qtab_723_40, 15); /* i = ADPCM code */
dq = reconstruct(i & 0x10, _dqlntab[i], y); /* quantized diff */
sr = (dq < 0) ? se - (dq & 0x7FFF) : se + dq; /* reconstructed signal */
dqsez = sr + sez - se; /* dqsez = pole prediction diff. */
update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
return (i);
}
/*
* g723_40_decoder()
*
* Decodes a 5-bit CCITT G.723 40Kbps code and returns
* the resulting 16-bit linear PCM, A-law or u-law sample value.
* -1 is returned if the output coding is unknown.
*/
int
g723_40_decoder(
int i,
int out_coding,
struct g72x_state *state_ptr)
{
short sezi, sei, sez, se; /* ACCUM */
short y; /* MIX */
short sr; /* ADDB */
short dq;
short dqsez;
i &= 0x1f; /* mask to get proper bits */
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
y = step_size(state_ptr); /* adaptive quantizer step size */
dq = reconstruct(i & 0x10, _dqlntab[i], y); /* estimation diff. */
sr = (dq < 0) ? (se - (dq & 0x7FFF)) : (se + dq); /* reconst. signal */
dqsez = sr - se + sez; /* pole prediction diff. */
update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
switch (out_coding) {
case AUDIO_ENCODING_ALAW:
return (tandem_adjust_alaw(sr, se, y, i, 0x10, qtab_723_40));
case AUDIO_ENCODING_ULAW:
return (tandem_adjust_ulaw(sr, se, y, i, 0x10, qtab_723_40));
case AUDIO_ENCODING_LINEAR:
return (sr << 2); /* sr was of 14-bit dynamic range */
default:
return (-1);
}
}

View File

@@ -1,608 +0,0 @@
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use. Users may copy or modify this source code without
* charge.
*
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* g72x.c
*
* Common routines for G.721 and G.723 conversions.
*/
#include <stdlib.h>
#include "g72x.h"
static short power2[15] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80,
0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000};
/*
* quan()
*
* quantizes the input val against the table of size short integers.
* It returns i if table[i - 1] <= val < table[i].
*
* Using linear search for simple coding.
*/
static int
quan(
int val,
short *table,
int size)
{
int i;
for (i = 0; i < size; i++)
if (val < *table++)
break;
return (i);
}
static char quan2_tab[65536];
static short base2_tab[65536];
static int init_tabs_done = 0;
inline char quan2 (unsigned short val)
{
return quan2_tab[val];
}
inline short base2 (unsigned short val)
{
return base2_tab[val];
}
static void init_quan2_tab (void)
{
long i;
for (i = 0; i < 65536; i++) {
quan2_tab[i] = quan (i, power2, 15);
};
}
static void init_base2_tab (void)
{
long i;
short exp;
for (i = 0; i < 65536; i++) {
exp = quan2 (short (i));
base2_tab[i] = short ((exp << 6) + ((i << 6) >> exp));
};
}
static void init_tabs (void)
{
if (init_tabs_done) return;
init_quan2_tab();
init_base2_tab();
init_tabs_done = 1;
}
/*
* fmult()
*
* returns the integer product of the 14-bit integer "an" and
* "floating point" representation (4-bit exponent, 6-bit mantessa) "srn".
*/
static int
fmult(
int an,
int srn)
{
short anmag, anexp, anmant;
short wanexp, wanmant;
short retval;
anmag = (an > 0) ? an : ((-an) & 0x1FFF);
anexp = quan2(anmag) - 6;
anmant = (anmag == 0) ? 32 :
(anexp >= 0) ? anmag >> anexp : anmag << -anexp;
wanexp = anexp + ((srn >> 6) & 0xF) - 13;
wanmant = (anmant * (srn & 077) + 0x30) >> 4;
retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) :
(wanmant >> -wanexp);
return (((an ^ srn) < 0) ? -retval : retval);
}
/*
* g72x_init_state()
*
* This routine initializes and/or resets the g72x_state structure
* pointed to by 'state_ptr'.
* All the initial state values are specified in the CCITT G.721 document.
*/
void
g72x_init_state(
struct g72x_state *state_ptr)
{
int cnta;
init_tabs ();
state_ptr->yl = 34816;
state_ptr->yu = 544;
state_ptr->dms = 0;
state_ptr->dml = 0;
state_ptr->ap = 0;
for (cnta = 0; cnta < 2; cnta++) {
state_ptr->a[cnta] = 0;
state_ptr->pk[cnta] = 0;
state_ptr->sr[cnta] = 32;
}
for (cnta = 0; cnta < 6; cnta++) {
state_ptr->b[cnta] = 0;
state_ptr->dq[cnta] = 32;
}
state_ptr->td = 0;
}
/*
* predictor_zero()
*
* computes the estimated signal from 6-zero predictor.
*
*/
int
predictor_zero(
struct g72x_state *state_ptr)
{
int i;
int sezi;
sezi = fmult(state_ptr->b[0] >> 2, state_ptr->dq[0]);
for (i = 1; i < 6; i++) /* ACCUM */
sezi += fmult(state_ptr->b[i] >> 2, state_ptr->dq[i]);
return (sezi);
}
/*
* predictor_pole()
*
* computes the estimated signal from 2-pole predictor.
*
*/
int
predictor_pole(
struct g72x_state *state_ptr)
{
return (fmult(state_ptr->a[1] >> 2, state_ptr->sr[1]) +
fmult(state_ptr->a[0] >> 2, state_ptr->sr[0]));
}
/*
* step_size()
*
* computes the quantization step size of the adaptive quantizer.
*
*/
int
step_size(
struct g72x_state *state_ptr)
{
int y;
int dif;
int al;
if (state_ptr->ap >= 256)
return (state_ptr->yu);
else {
y = state_ptr->yl >> 6;
dif = state_ptr->yu - y;
al = state_ptr->ap >> 2;
if (dif > 0)
y += (dif * al) >> 6;
else if (dif < 0)
y += (dif * al + 0x3F) >> 6;
return (y);
}
}
/*
* quantize()
*
* Given a raw sample, 'd', of the difference signal and a
* quantization step size scale factor, 'y', this routine returns the
* ADPCM codeword to which that sample gets quantized. The step
* size scale factor division operation is done in the log base 2 domain
* as a subtraction.
*/
int
quantize(
int d, /* Raw difference signal sample */
int y, /* Step size multiplier */
short *table, /* quantization table */
int size) /* table size of short integers */
{
short dqm; /* Magnitude of 'd' */
short exp; /* Integer part of base 2 log of 'd' */
short mant; /* Fractional part of base 2 log */
short dl; /* Log of magnitude of 'd' */
short dln; /* Step size scale factor normalized log */
int i;
/*
* LOG
*
* Compute base 2 log of 'd', and store in 'dl'.
*/
dqm = abs(d);
exp = quan2(dqm >> 1);
mant = ((dqm << 7) >> exp) & 0x7F; /* Fractional portion. */
dl = (exp << 7) + mant;
/*
* SUBTB
*
* "Divide" by step size multiplier.
*/
dln = dl - (y >> 2);
/*
* QUAN
*
* Obtain codword i for 'd'.
*/
i = quan(dln, table, size);
if (d < 0) /* take 1's complement of i */
return ((size << 1) + 1 - i);
else if (i == 0) /* take 1's complement of 0 */
return ((size << 1) + 1); /* new in 1988 */
else
return (i);
}
/*
* reconstruct()
*
* Returns reconstructed difference signal 'dq' obtained from
* codeword 'i' and quantization step size scale factor 'y'.
* Multiplication is performed in log base 2 domain as addition.
*/
int
reconstruct(
int sign, /* 0 for non-negative value */
int dqln, /* G.72x codeword */
int y) /* Step size multiplier */
{
short dql; /* Log of 'dq' magnitude */
short dex; /* Integer part of log */
short dqt;
short dq; /* Reconstructed difference signal sample */
dql = dqln + (y >> 2); /* ADDA */
if (dql < 0) {
return ((sign) ? -0x8000 : 0);
} else { /* ANTILOG */
dex = (dql >> 7) & 15;
dqt = 128 + (dql & 127);
dq = (dqt << 7) >> (14 - dex);
return ((sign) ? (dq - 0x8000) : dq);
}
}
/*
* update()
*
* updates the state variables for each output code
*/
void
update(
int code_size, /* distinguish 723_40 with others */
int y, /* quantizer step size */
int wi, /* scale factor multiplier */
int fi, /* for long/short term energies */
int dq, /* quantized prediction difference */
int sr, /* reconstructed signal */
int dqsez, /* difference from 2-pole predictor */
struct g72x_state *state_ptr) /* coder state pointer */
{
int cnt;
short mag; /* Adaptive predictor, FLOAT A */
short a2p; /* LIMC */
short a1ul; /* UPA1 */
short pks1; /* UPA2 */
short fa1;
char tr; /* tone/transition detector */
short ylint, thr2, dqthr;
short ylfrac, thr1;
short pk0;
pk0 = (dqsez < 0) ? 1 : 0; /* needed in updating predictor poles */
mag = dq & 0x7FFF; /* prediction difference magnitude */
/* TRANS */
ylint = short (state_ptr->yl >> 15); /* exponent part of yl */
ylfrac = (state_ptr->yl >> 10) & 0x1F; /* fractional part of yl */
thr1 = (32 + ylfrac) << ylint; /* threshold */
thr2 = (ylint > 9) ? 31 << 10 : thr1; /* limit thr2 to 31 << 10 */
dqthr = (thr2 + (thr2 >> 1)) >> 1; /* dqthr = 0.75 * thr2 */
if (state_ptr->td == 0) /* signal supposed voice */
tr = 0;
else if (mag <= dqthr) /* supposed data, but small mag */
tr = 0; /* treated as voice */
else /* signal is data (modem) */
tr = 1;
/*
* Quantizer scale factor adaptation.
*/
/* FUNCTW & FILTD & DELAY */
/* update non-steady state step size multiplier */
state_ptr->yu = y + ((wi - y) >> 5);
/* LIMB */
if (state_ptr->yu < 544) /* 544 <= yu <= 5120 */
state_ptr->yu = 544;
else if (state_ptr->yu > 5120)
state_ptr->yu = 5120;
/* FILTE & DELAY */
/* update steady state step size multiplier */
state_ptr->yl += state_ptr->yu + ((-state_ptr->yl) >> 6);
/*
* Adaptive predictor coefficients.
*/
if (tr == 1) { /* reset a's and b's for modem signal */
state_ptr->a[0] = 0;
state_ptr->a[1] = 0;
state_ptr->b[0] = 0;
state_ptr->b[1] = 0;
state_ptr->b[2] = 0;
state_ptr->b[3] = 0;
state_ptr->b[4] = 0;
state_ptr->b[5] = 0;
a2p = 0; /* eliminate Compiler Warnings */
} else { /* update a's and b's */
pks1 = pk0 ^ state_ptr->pk[0]; /* UPA2 */
/* update predictor pole a[1] */
a2p = state_ptr->a[1] - (state_ptr->a[1] >> 7);
if (dqsez != 0) {
fa1 = (pks1) ? state_ptr->a[0] : -state_ptr->a[0];
if (fa1 < -8191) /* a2p = function of fa1 */
a2p -= 0x100;
else if (fa1 > 8191)
a2p += 0xFF;
else
a2p += fa1 >> 5;
if (pk0 ^ state_ptr->pk[1])
/* LIMC */
if (a2p <= -12160)
a2p = -12288;
else if (a2p >= 12416)
a2p = 12288;
else
a2p -= 0x80;
else if (a2p <= -12416)
a2p = -12288;
else if (a2p >= 12160)
a2p = 12288;
else
a2p += 0x80;
}
/* TRIGB & DELAY */
state_ptr->a[1] = a2p;
/* UPA1 */
/* update predictor pole a[0] */
state_ptr->a[0] -= state_ptr->a[0] >> 8;
if (dqsez != 0)
if (pks1 == 0)
state_ptr->a[0] += 192;
else
state_ptr->a[0] -= 192;
/* LIMD */
a1ul = 15360 - a2p;
if (state_ptr->a[0] < -a1ul)
state_ptr->a[0] = -a1ul;
else if (state_ptr->a[0] > a1ul)
state_ptr->a[0] = a1ul;
/* UPB : update predictor zeros b[6] */
for (cnt = 0; cnt < 6; cnt++) {
if (code_size == 5) /* for 40Kbps G.723 */
state_ptr->b[cnt] -= state_ptr->b[cnt] >> 9;
else /* for G.721 and 24Kbps G.723 */
state_ptr->b[cnt] -= state_ptr->b[cnt] >> 8;
if (dq & 0x7FFF) { /* XOR */
if ((dq ^ state_ptr->dq[cnt]) >= 0)
state_ptr->b[cnt] += 128;
else
state_ptr->b[cnt] -= 128;
}
}
}
for (cnt = 5; cnt > 0; cnt--)
state_ptr->dq[cnt] = state_ptr->dq[cnt-1];
/* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */
if (mag == 0) {
state_ptr->dq[0] = (dq >= 0) ? 0x20 : 0xFC20;
} else {
state_ptr->dq[0] = (dq >= 0) ?
base2 (mag) : base2 (mag) - 0x400;
}
state_ptr->sr[1] = state_ptr->sr[0];
/* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */
if (sr == 0) {
state_ptr->sr[0] = 0x20;
} else if (sr > 0) {
state_ptr->sr[0] = base2(sr);
} else if (sr > -32768) {
mag = -sr;
state_ptr->sr[0] = base2(mag) - 0x400;
} else
state_ptr->sr[0] = short (0xFC20);
/* DELAY A */
state_ptr->pk[1] = state_ptr->pk[0];
state_ptr->pk[0] = pk0;
/* TONE */
if (tr == 1) /* this sample has been treated as data */
state_ptr->td = 0; /* next one will be treated as voice */
else if (a2p < -11776) /* small sample-to-sample correlation */
state_ptr->td = 1; /* signal may be data */
else /* signal is voice */
state_ptr->td = 0;
/*
* Adaptation speed control.
*/
state_ptr->dms += (fi - state_ptr->dms) >> 5; /* FILTA */
state_ptr->dml += (((fi << 2) - state_ptr->dml) >> 7); /* FILTB */
if (tr == 1)
state_ptr->ap = 256;
else if (y < 1536) /* SUBTC */
state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
else if (state_ptr->td == 1)
state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
else if (abs((state_ptr->dms << 2) - state_ptr->dml) >=
(state_ptr->dml >> 3))
state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
else
state_ptr->ap += (-state_ptr->ap) >> 4;
}
/*
* tandem_adjust(sr, se, y, i, sign)
*
* At the end of ADPCM decoding, it simulates an encoder which may be receiving
* the output of this decoder as a tandem process. If the output of the
* simulated encoder differs from the input to this decoder, the decoder output
* is adjusted by one level of A-law or u-law codes.
*
* Input:
* sr decoder output linear PCM sample,
* se predictor estimate sample,
* y quantizer step size,
* i decoder input code,
* sign sign bit of code i
*
* Return:
* adjusted A-law or u-law compressed sample.
*/
int
tandem_adjust_alaw(
int sr, /* decoder output linear PCM sample */
int se, /* predictor estimate sample */
int y, /* quantizer step size */
int i, /* decoder input code */
int sign,
short *qtab)
{
unsigned char sp; /* A-law compressed 8-bit code */
short dx; /* prediction error */
char id; /* quantized prediction error */
int sd; /* adjusted A-law decoded sample value */
int im; /* biased magnitude of i */
int imx; /* biased magnitude of id */
if (sr <= -32768)
sr = -1;
sp = linear2alaw((sr >> 1) << 3); /* short to A-law compression */
dx = (alaw2linear(sp) >> 2) - se; /* 16-bit prediction error */
id = quantize(dx, y, qtab, sign - 1);
if (id == i) { /* no adjustment on sp */
return (sp);
} else { /* sp adjustment needed */
/* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */
im = i ^ sign; /* 2's complement to biased unsigned */
imx = id ^ sign;
if (imx > im) { /* sp adjusted to next lower value */
if (sp & 0x80) {
sd = (sp == 0xD5) ? 0x55 :
((sp ^ 0x55) - 1) ^ 0x55;
} else {
sd = (sp == 0x2A) ? 0x2A :
((sp ^ 0x55) + 1) ^ 0x55;
}
} else { /* sp adjusted to next higher value */
if (sp & 0x80)
sd = (sp == 0xAA) ? 0xAA :
((sp ^ 0x55) + 1) ^ 0x55;
else
sd = (sp == 0x55) ? 0xD5 :
((sp ^ 0x55) - 1) ^ 0x55;
}
return (sd);
}
}
int
tandem_adjust_ulaw(
int sr, /* decoder output linear PCM sample */
int se, /* predictor estimate sample */
int y, /* quantizer step size */
int i, /* decoder input code */
int sign,
short *qtab)
{
unsigned char sp; /* u-law compressed 8-bit code */
short dx; /* prediction error */
char id; /* quantized prediction error */
int sd; /* adjusted u-law decoded sample value */
int im; /* biased magnitude of i */
int imx; /* biased magnitude of id */
if (sr <= -32768)
sr = 0;
sp = linear2ulaw(sr << 2); /* short to u-law compression */
dx = (ulaw2linear(sp) >> 2) - se; /* 16-bit prediction error */
id = quantize(dx, y, qtab, sign - 1);
if (id == i) {
return (sp);
} else {
/* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */
im = i ^ sign; /* 2's complement to biased unsigned */
imx = id ^ sign;
if (imx > im) { /* sp adjusted to next lower value */
if (sp & 0x80)
sd = (sp == 0xFF) ? 0x7E : sp + 1;
else
sd = (sp == 0) ? 0 : sp - 1;
} else { /* sp adjusted to next higher value */
if (sp & 0x80)
sd = (sp == 0x80) ? 0x80 : sp - 1;
else
sd = (sp == 0x7F) ? 0xFE : sp + 1;
}
return (sd);
}
}

View File

@@ -1,123 +0,0 @@
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use. Users may copy or modify this source code without
* charge.
*
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* g72x.h
*
* Header file for CCITT conversion routines.
*
*/
#ifndef _G72X_H
#define _G72X_H
#define AUDIO_ENCODING_ULAW (1) /* ISDN u-law */
#define AUDIO_ENCODING_ALAW (2) /* ISDN A-law */
#define AUDIO_ENCODING_LINEAR (3) /* PCM 2's-complement (0-center) */
/*
* The following is the definition of the state structure
* used by the G.721/G.723 encoder and decoder to preserve their internal
* state between successive calls. The meanings of the majority
* of the state structure fields are explained in detail in the
* CCITT Recommendation G.721. The field names are essentially indentical
* to variable names in the bit level description of the coding algorithm
* included in this Recommendation.
*/
struct g72x_state {
long yl; /* Locked or steady state step size multiplier. */
short yu; /* Unlocked or non-steady state step size multiplier. */
short dms; /* Short term energy estimate. */
short dml; /* Long term energy estimate. */
short ap; /* Linear weighting coefficient of 'yl' and 'yu'. */
short a[2]; /* Coefficients of pole portion of prediction filter. */
short b[6]; /* Coefficients of zero portion of prediction filter. */
short pk[2]; /*
* Signs of previous two samples of a partially
* reconstructed signal.
*/
short dq[6]; /*
* Previous 6 samples of the quantized difference
* signal represented in an internal floating point
* format.
*/
short sr[2]; /*
* Previous 2 samples of the quantized difference
* signal represented in an internal floating point
* format.
*/
char td; /* delayed tone detect, new in 1988 version */
};
/* External function definitions. */
extern unsigned char linear2alaw (int pcm_val); /* 2's complement (16-bit range) */
extern int alaw2linear (unsigned char a_val);
extern unsigned char linear2ulaw (int pcm_val); /* 2's complement (16-bit range) */
extern int ulaw2linear (unsigned char u_val);
extern int predictor_zero (struct g72x_state *state_ptr);
extern int predictor_pole (struct g72x_state *state_ptr);
extern int step_size (struct g72x_state *state_ptr);
extern int quantize (int d, int y, short *table, int size);
extern int reconstruct (int sign, int dqln, int y);
extern void update
( int code_size, int y, int wi, int fi, int dq
, int sr, int dqsez, struct g72x_state *state_ptr);
int tandem_adjust_alaw
(int sr, int se, int y, int i, int sign, short *qtab);
int tandem_adjust_ulaw
(int sr, int se, int y, int i, int sign, short *qtab);
extern void g72x_init_state (struct g72x_state *);
extern int g721_encoder(
int sample,
int in_coding,
struct g72x_state *state_ptr);
extern int g721_decoder(
int code,
int out_coding,
struct g72x_state *state_ptr);
extern int g723_24_encoder(
int sample,
int in_coding,
struct g72x_state *state_ptr);
extern int g723_24_decoder(
int code,
int out_coding,
struct g72x_state *state_ptr);
extern int g723_40_encoder(
int sample,
int in_coding,
struct g72x_state *state_ptr);
extern int g723_40_decoder(
int code,
int out_coding,
struct g72x_state *state_ptr);
#endif /* !_G72X_H */

View File

@@ -1,30 +0,0 @@
#
# File: Makefile
# Author: Guilhem Lavaux
# Created: 1998
# Updated:
# Copyright: (c) 1998 Julian Smart
#
# "%W% %G%"
#
# Makefile for wxMultiMedia (UNIX).
# updated mcf
WXWIN=../../..
top_srcdir = ../../..
top_builddir = ../../..
VPATH= $(top_srcdir)/utils/wxMMedia2/lib
LIBTARGET=libwxmmedia2
OBJECTS=sndbase.o sndcodec.o sndpcm.o sndcpcm.o sndulaw.o sndfile.o \
sndaiff.o sndwav.o sndwin.o \
g711.o g721.o g723_24.o g723_40.o g72x.o \
sndg72x.o cdbase.o \
vidbase.o
# include $(top_builddir)/src/makelib.env
include $(top_builddir)/src/makelib.g95

View File

@@ -1,112 +0,0 @@
#
# File: makefile.nt
# Author: Julian Smart
# Created: 1993
# Updated:
# Copyright: (c) 1993, AIAI, University of Edinburgh
#
# "%W% %G%"
#
# Makefile : Builds GLCanvas class library (MS VC++).
# Use FINAL=1 argument to nmake to build final version with no debugging
# info
# Set WXDIR for your system
WXDIR = $(WXWIN)
MMDIR = $(WXDIR)\utils\wxMMedia2
THISDIR = $(MMDIR)\lib
EXTRALIBS=$(WXDIR)\lib\mmedia2.lib
LIBTARGET=$(WXDIR)\lib\mmedia2.lib
OBJECTS = cdbase.obj cdwin.obj g711.obj g721.obj g723_24.obj sndg72x.obj \
g723_40.obj g72x.obj sndbase.obj sndcodec.obj sndpcm.obj \
sndcpcm.obj sndulaw.obj sndfile.obj sndwav.obj sndaiff.obj sndwin.obj \
vidbase.obj vidwin.obj
!include $(WXDIR)\src\makelib.vc
cdbase.obj: cdbase.h cdbase.$(SRCSUFF)
$(cc) @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
cdwin.obj: cdwin.h cdwin.$(SRCSUFF)
$(cc) @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
g711.obj: g72x.h g711.$(SRCSUFF)
$(cc) @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
g721.obj: g72x.h g721.$(SRCSUFF)
$(cc) @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
g723_24.obj: g72x.h g723_24.$(SRCSUFF)
$(cc) @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
g723_40.obj: g72x.h g723_40.$(SRCSUFF)
$(cc) @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
sndbase.obj: sndbase.h sndbase.$(SRCSUFF)
$(cc) @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
sndcodec.obj: sndcodec.h sndcodec.$(SRCSUFF)
$(cc) @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
sndpcm.obj: sndpcm.h sndpcm.$(SRCSUFF)
$(cc) @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
sndcpcm.obj: sndcpcm.h converter.def sndcpcm.$(SRCSUFF)
$(cc) @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
sndulaw.obj: sndulaw.h g72x.h sndulaw.$(SRCSUFF)
$(cc) @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
sndfile.obj: sndfile.h sndfile.$(SRCSUFF)
$(cc) @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
sndwav.obj: sndwav.h sndwav.$(SRCSUFF)
$(cc) @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
sndaiff.obj: sndaiff.h sndaiff.$(SRCSUFF)
$(cc) @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
sndwin.obj: sndwin.h sndwin.$(SRCSUFF)
$(cc) @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
vidbase.obj: vidbase.h vidbase.$(SRCSUFF)
$(cc) @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
vidwin.obj: vidwin.h vidwin.$(SRCSUFF)
$(cc) @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<

View File

@@ -1,198 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndaiff.cpp
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "sndaiff.cpp"
#endif
#include <wx/wxprec.h>
#include <wx/stream.h>
#include <wx/datstrm.h>
#include <wx/filefn.h>
#include "sndbase.h"
#include "sndcodec.h"
#include "sndfile.h"
#include "sndpcm.h"
#include "sndaiff.h"
#define BUILD_SIGNATURE(a,b,c,d) (((wxUint32)a) | (((wxUint32)b) << 8) | (((wxUint32)c) << 16) | (((wxUint32)d) << 24))
#define FORM_SIGNATURE BUILD_SIGNATURE('F','O','R','M')
#define AIFF_SIGNATURE BUILD_SIGNATURE('A','I','F','F')
#define AIFC_SIGNATURE BUILD_SIGNATURE('A','I','F','C')
#define COMM_SIGNATURE BUILD_SIGNATURE('C','O','M','M')
#define SSND_SIGNATURE BUILD_SIGNATURE('S','S','N','D')
wxSoundAiff::wxSoundAiff(wxInputStream& stream, wxSoundStream& io_sound)
: wxSoundFileStream(stream, io_sound)
{
m_base_offset = wxInvalidOffset;
}
wxSoundAiff::wxSoundAiff(wxOutputStream& stream, wxSoundStream& io_sound)
: wxSoundFileStream(stream, io_sound)
{
m_base_offset = wxInvalidOffset;
}
wxSoundAiff::~wxSoundAiff()
{
}
wxString wxSoundAiff::GetCodecName() const
{
return "wxSoundAiff codec";
}
bool wxSoundAiff::CanRead()
{
wxUint32 signature1, signature2, len;
if (m_input->Read(&signature1, 4).LastRead() != 4)
return FALSE;
if (wxUINT32_SWAP_ON_BE(signature1) != FORM_SIGNATURE) {
m_input->Ungetch(&signature1, 4);
return FALSE;
}
m_input->Read(&len, 4);
if (m_input->LastRead() != 4) {
m_input->Ungetch(&len, m_input->LastRead());
m_input->Ungetch(&signature1, 4);
return FALSE;
}
if (m_input->Read(&signature2, 4).LastRead() != 4) {
m_input->Ungetch(&signature2, m_input->LastRead());
m_input->Ungetch(&len, 4);
m_input->Ungetch(&signature1, 4);
return FALSE;
}
m_input->Ungetch(&signature2, 4);
m_input->Ungetch(&len, 4);
m_input->Ungetch(&signature1, 4);
if (
wxUINT32_SWAP_ON_BE(signature2) != AIFF_SIGNATURE &&
wxUINT32_SWAP_ON_BE(signature2) != AIFC_SIGNATURE)
return FALSE;
return TRUE;
}
#define FAIL_WITH(condition, err) if (condition) { m_snderror = err; return FALSE; }
bool wxSoundAiff::PrepareToPlay()
{
wxDataInputStream data(*m_input);
wxUint32 signature, len, ssnd;
bool end_headers;
if (!m_input) {
m_snderror = wxSOUND_INVSTRM;
return FALSE;
}
m_snderror = wxSOUND_NOERROR;
data.BigEndianOrdered(TRUE);
FAIL_WITH(m_input->Read(&signature, 4).LastRead() != 4, wxSOUND_INVSTRM);
FAIL_WITH(wxUINT32_SWAP_ON_BE(signature) != FORM_SIGNATURE, wxSOUND_INVSTRM);
// "FORM"
len = data.Read32();
FAIL_WITH(m_input->LastRead() != 4, wxSOUND_INVSTRM);
// dummy len
FAIL_WITH(m_input->Read(&signature, 4).LastRead() != 4, wxSOUND_INVSTRM);
FAIL_WITH(
wxUINT32_SWAP_ON_BE(signature) != AIFF_SIGNATURE &&
wxUINT32_SWAP_ON_BE(signature) != AIFC_SIGNATURE, wxSOUND_INVSTRM);
// "AIFF" / "AIFC"
end_headers = FALSE;
while (!end_headers) {
FAIL_WITH(m_input->Read(&signature, 4).LastRead() != 4, wxSOUND_INVSTRM);
len = data.Read32();
FAIL_WITH(m_input->LastRead() != 4, wxSOUND_INVSTRM);
switch (wxUINT32_SWAP_ON_BE(signature)) {
case COMM_SIGNATURE: { // "COMM"
wxUint16 channels, bps;
wxUint32 num_samples;
double srate;
wxSoundFormatPcm sndformat;
// Get sound data informations
data >> channels >> num_samples >> bps >> srate;
// Convert them in a wxSoundFormat object
sndformat.SetSampleRate((wxUint32) srate);
sndformat.SetBPS(bps);
sndformat.SetChannels(channels);
sndformat.Signed(FALSE);
sndformat.SetOrder(wxBIG_ENDIAN);
if (!SetSoundFormat(sndformat))
return FALSE;
// We pass all data left
m_input->SeekI(len-18, wxFromCurrent);
break;
}
case SSND_SIGNATURE: { // "SSND"
data >> ssnd;
// m_input->SeekI(4, wxFromCurrent); // Pass an INT32
// m_input->SeekI(len-4, wxFromCurrent); // Pass the rest
m_input->SeekI(ssnd + 4, wxFromCurrent);
m_base_offset = m_input->TellI();
// len-8 bytes of samples
FinishPreparation(len - 8);
end_headers = TRUE;
break;
}
default:
m_input->SeekI(len, wxFromCurrent);
break;
}
}
return TRUE;
}
bool wxSoundAiff::PrepareToRecord(wxUint32 time)
{
// TODO
return FALSE;
}
bool wxSoundAiff::FinishRecording()
{
// TODO
return FALSE;
}
bool wxSoundAiff::RepositionStream(wxUint32 position)
{
// If the stream is not seekable "TellI() returns wxInvalidOffset" we cannot reposition stream
if (m_base_offset == wxInvalidOffset)
return FALSE;
m_input->SeekI(m_base_offset, wxFromStart);
return TRUE;
}
wxUint32 wxSoundAiff::GetData(void *buffer, wxUint32 len)
{
return m_input->Read(buffer, len).LastRead();
}
wxUint32 wxSoundAiff::PutData(const void *buffer, wxUint32 len)
{
return m_output->Write(buffer, len).LastWrite();
}

View File

@@ -1,45 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndaiff.h
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifndef _WX_SNDAIFF_H
#define _WX_SNDAIFF_H
#ifdef __GNUG__
#pragma interface "sndaiff.h"
#endif
#include <wx/stream.h>
#include "sndbase.h"
#include "sndcodec.h"
#include "sndfile.h"
//
// AIFF codec
//
class wxSoundAiff: public wxSoundFileStream {
public:
wxSoundAiff(wxInputStream& stream, wxSoundStream& io_sound);
wxSoundAiff(wxOutputStream& stream, wxSoundStream& io_sound);
~wxSoundAiff();
bool CanRead();
wxString GetCodecName() const;
protected:
bool PrepareToPlay();
bool PrepareToRecord(wxUint32 time);
bool FinishRecording();
bool RepositionStream(wxUint32 position);
wxUint32 GetData(void *buffer, wxUint32 len);
wxUint32 PutData(const void *buffer, wxUint32 len);
protected:
off_t m_base_offset;
};
#endif

View File

@@ -1,134 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndbase.cpp
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999, 2000
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "sndbase.cpp"
#endif
#include <wx/wxprec.h>
#include "sndbase.h"
// ---------------------------------------------------------------------------
// wxSoundFormatBase
// ---------------------------------------------------------------------------
wxSoundFormatBase::wxSoundFormatBase()
{
}
wxSoundFormatBase::~wxSoundFormatBase()
{
}
wxSoundFormatBase *wxSoundFormatBase::Clone() const
{
return NULL;
}
bool wxSoundFormatBase::operator!=(const wxSoundFormatBase& frmt2) const
{
return (GetType() != frmt2.GetType());
}
// ---------------------------------------------------------------------------
// wxSoundStream
// ---------------------------------------------------------------------------
wxSoundStream::wxSoundStream()
{
int i;
// Reset all variables to their neutral value.
m_sndformat = NULL;
m_handler = NULL;
m_snderror = wxSOUND_NOERROR;
m_lastcount = 0;
for (i=0;i<2;i++)
m_callback[i] = NULL;
}
wxSoundStream::~wxSoundStream()
{
if (m_sndformat)
delete m_sndformat;
}
// --------------------------------------------------------------------------
// SetSoundFormat(const wxSoundFormatBase& format) is one of the most
// important function of the wxSoundStream class. It prepares the stream to
// receive or send the data in a strict format. Normally, the sound stream
// should be ready to accept any format it is asked to manage but in certain
// cases, it really cannot: in that case it returns FALSE. To have more
// details in the functionnalities of SetSoundFormat see
// wxSoundRouterStream::SetSoundFormat()
// --------------------------------------------------------------------------
bool wxSoundStream::SetSoundFormat(const wxSoundFormatBase& format)
{
// delete the previous prepared format
if (m_sndformat)
delete m_sndformat;
// create a new one by cloning the format passed in parameter
m_sndformat = format.Clone();
return TRUE;
}
// --------------------------------------------------------------------------
// Register(int evt, ...) registers the callback for a specified async event.
// Warning ! Only one callback by event is supported. It means that if you
// call twice this function the previous registered callback is absolutely
// ignored.
// --------------------------------------------------------------------------
void wxSoundStream::SetCallback(int evt, wxSoundCallback cbk, void *cdata)
{
int c;
switch (evt) {
case wxSOUND_INPUT:
c = 0;
break;
case wxSOUND_OUTPUT:
c = 1;
break;
default:
return;
}
m_callback[c] = cbk;
m_cdata[c] = cdata;
}
// --------------------------------------------------------------------------
// OnSoundEvent(int evt) is called either when the driver is ready to receive
// a new block to play or when the driver has a new recorded buffer. You
// must be careful here and try not to spend a lot of time: this is a
// real-time call. In the case, an "event handler" was specified previously,
// it called him before everything.
// --------------------------------------------------------------------------
void wxSoundStream::OnSoundEvent(int evt)
{
int c;
if (m_handler) {
m_handler->OnSoundEvent(evt);
return;
}
switch (evt) {
case wxSOUND_INPUT:
c = 0;
break;
case wxSOUND_OUTPUT:
c = 1;
break;
default:
return;
}
if (m_callback[c])
m_callback[c](this, evt, m_cdata[c]);
}

View File

@@ -1,168 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndbase.h
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifndef _WX_SNDBASE_H
#define _WX_SNDBASE_H
#ifdef __GNUG__
#pragma interface "sndbase.h"
#endif
#include <wx/defs.h>
// ------------------------------------------------------------------------
// DEFINITIONS
// ---------------------
// Sound streaming mode:
// - wxSOUND_INPUT: simple recording mode
// - wxSOUND_OUTPUT: simple playing mode
// - wxSOUND_DUPLEX: full duplex record/play at the same time
// ---------------------
enum {
wxSOUND_INPUT = 1,
wxSOUND_OUTPUT = 2,
wxSOUND_DUPLEX = wxSOUND_INPUT | wxSOUND_OUTPUT,
};
// ---------------------
// wxSoundFormatType: it specifies the format family of the sound data
// which will be passed to the stream.
// ---------------------
typedef enum {
wxSOUND_NOFORMAT,
wxSOUND_PCM,
wxSOUND_ULAW,
wxSOUND_G72X,
wxSOUND_MSADPCM
} wxSoundFormatType;
// ---------------------
// wxSoundError:
// - wxSOUND_NOERR: No error occured
// - wxSOUND_IOERR: an input/output error occured, it may concern either
// a driver or a file
// - wxSOUND_INVFRMT: the sound format passed to the function is invalid.
// Generally, it means that you passed out of range values
// to the codec stream or you don't pass the right sound
// format object to the right sound codec stream.
// - wxSOUND_INVDEV: Invalid device. Generally, it means that the sound stream
// didn't manage to open the device driver due to an invalid// parameter or to the fact that sound is not supported on
// this computer.
// - wxSOUND_NOEXACT: No exact matching sound codec has been found for
// this sound format. It means that the sound driver didn't
// manage to setup the sound card with the specified
// values.
// - wxSOUND_NOCODEC: No matching codec has been found. Generally, it
// may happen when you call
// wxSoundRouterStream::SetSoundFormat().
// - wxSOUND_MEMERR: Not enough memory.
// ---------------------
typedef enum {
wxSOUND_NOERROR,
wxSOUND_IOERROR,
wxSOUND_INVFRMT,
wxSOUND_INVDEV,
wxSOUND_NOEXACT,
wxSOUND_INVSTRM,
wxSOUND_NOCODEC,
wxSOUND_MEMERROR
} wxSoundError;
class WXDLLEXPORT wxSoundStream;
// ---------------------
// wxSoundCallback(stream, evt, cdata): C callback for sound event.
// - stream: current wxSoundStream
// - evt: the sound event which has occured, it may be wxSOUND_INPUT,
// wxSOUND_OUTPUT or wxSOUND_DUPLEX
// - cdata: User callback data
// ---------------------
typedef void (*wxSoundCallback)(wxSoundStream *stream, int evt,
void *cdata);
//
// Base class for sound format specification
//
class WXDLLEXPORT wxSoundFormatBase {
public:
wxSoundFormatBase();
virtual ~wxSoundFormatBase();
// It returns a "standard" format type.
virtual wxSoundFormatType GetType() const { return wxSOUND_NOFORMAT; }
// It clones the current format.
virtual wxSoundFormatBase *Clone() const;
virtual wxUint32 GetTimeFromBytes(wxUint32 bytes) const = 0;
virtual wxUint32 GetBytesFromTime(wxUint32 time) const = 0;
virtual bool operator !=(const wxSoundFormatBase& frmt2) const;
};
//
// Base class for sound streams
//
class wxSoundStream {
public:
wxSoundStream();
virtual ~wxSoundStream();
// Reads "len" bytes from the sound stream.
virtual wxSoundStream& Read(void *buffer, wxUint32 len) = 0;
// Writes "len" byte to the sound stream.
virtual wxSoundStream& Write(const void *buffer, wxUint32 len) = 0;
// Returns the best size for IO calls
virtual wxUint32 GetBestSize() const { return 1024; }
// SetSoundFormat returns TRUE when the format can be handled.
virtual bool SetSoundFormat(const wxSoundFormatBase& format);
// GetSoundFormat returns the current sound format.
wxSoundFormatBase& GetSoundFormat() const { return *m_sndformat; }
// Register a callback for a specified async event.
void SetCallback(int evt, wxSoundCallback cbk, void *cdata);
// Starts the async notifier. After this call, the stream begins either
// recording or playing or the two at the same time.
virtual bool StartProduction(int evt) = 0;
// Stops the async notifier.
virtual bool StopProduction() = 0;
// Sets the event handler: if it is non-null, all events are routed to it.
void SetEventHandler(wxSoundStream *handler) { m_handler = handler; }
wxSoundError GetError() const { return m_snderror; }
wxUint32 GetLastAccess() const { return m_lastcount; }
// This is only useful for device (I think).
virtual bool QueueFilled() const { return TRUE; }
protected:
// Current sound format
wxSoundFormatBase *m_sndformat;
// Last error
wxSoundError m_snderror;
// Last access
wxUint32 m_lastcount;
// Event handler
wxSoundStream *m_handler;
wxSoundCallback m_callback[2];
void *m_cdata[2];
protected:
// Handles event
virtual void OnSoundEvent(int evt);
};
#endif

View File

@@ -1,38 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndcodec.cpp
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "sndcodec.cpp"
#endif
#include <wx/wxprec.h>
#include "sndbase.h"
#include "sndcodec.h"
wxSoundStreamCodec::wxSoundStreamCodec(wxSoundStream& snd_io)
: m_sndio(&snd_io)
{
}
wxSoundStreamCodec::~wxSoundStreamCodec()
{
}
bool wxSoundStreamCodec::StartProduction(int evt)
{
return m_sndio->StartProduction(evt);
}
bool wxSoundStreamCodec::StopProduction()
{
return m_sndio->StopProduction();
}
wxUint32 wxSoundStreamCodec::GetBestSize() const
{
return m_sndio->GetBestSize();
}

View File

@@ -1,31 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndcodec.h
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifndef _WX_SNDCODEC_H
#define _WX_SNDCODEC_H
#ifdef __GNUG__
#pragma interface "sndcodec.h"
#endif
#include "sndbase.h"
class wxSoundStreamCodec: public wxSoundStream {
public:
wxSoundStreamCodec(wxSoundStream& snd_io);
~wxSoundStreamCodec();
bool StartProduction(int evt);
bool StopProduction();
wxUint32 GetBestSize() const;
protected:
wxSoundStream *m_sndio;
};
#endif

View File

@@ -1,389 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndcpcm.cpp
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999, 2000
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "sndcpcm.cpp"
#endif
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/debug.h>
#include <wx/log.h>
#endif
#include "sndbase.h"
#include "sndpcm.h"
#include "sndcpcm.h"
wxSoundStreamPcm::wxSoundStreamPcm(wxSoundStream& sndio)
: wxSoundStreamCodec(sndio)
{
m_function_in = NULL;
m_function_out = NULL;
m_prebuffer = NULL;
m_prebuffer_size = 0;
m_best_size = 0;
}
wxSoundStreamPcm::~wxSoundStreamPcm()
{
if (m_prebuffer)
delete[] m_prebuffer;
}
wxUint32 wxSoundStreamPcm::GetBestSize() const
{
return m_best_size;
}
#include "converter.def"
// -----------------------------------------------------------------------
// Main PCM stream converter table
// -----------------------------------------------------------------------
// Definition
// XX -> YY
// XX -> YY sign
//
// XX swapped -> YY
// XX swapped -> YY sign
//
// XX swapped -> YY swapped
// XX swapped -> YY swapped sign
//
// XX stereo -> YY mono
// XX stereo -> YY mono sign
//
// XX swapped stereo -> YY swapped mono
// XX swapped stereo -> YY swapped mono sign
//
// XX swapped stereo -> YY swapped mono
// XX swapped stereo -> YY swapped mono sign
static wxSoundStreamPcm::ConverterType s_converters[4][3][2] = {
{
{
NULL,
Convert_8_8_sign /* 8 -> 8 sign */
},
{
NULL,
NULL
},
{
NULL,
NULL
}
},
{
{
Convert_8_16, /* 8 -> 16 */
Convert_8_16_sign /* 8 -> 16 sign */
},
{
Convert_8_16_swap, /* 8 -> 16 swapped */
Convert_8_16_sign_swap /* 8 -> 16 sign swapped */
},
{
NULL,
NULL
}
},
{
{
Convert_16_8, /* 16 -> 8 */
Convert_16_8_sign /* 16 -> 8 sign */
},
{
Convert_16_swap_8, /* 16 swapped -> 8 */
Convert_16_swap_8_sign /* 16 swapped -> 8 sign */
},
{
NULL,
NULL
},
},
{
{
NULL, /* 16 -> 16 */
Convert_16_sign /* 16 -> 16 sign */
},
{
Convert_16_swap, /* 16 swapped -> 16 */
Convert_16_swap_16_sign /* 16 swapped -> 16 sign */
},
{
NULL,
Convert_16_swap_16_sign_swap /* 16 swapped -> 16 sign swapped */
}
}
};
// This is the buffer size multiplier. It gives the needed size of the output size.
static float s_converters_multip[] = {1, 2, 0.5, 1};
//
// TODO: Read() and Write() aren't really safe. If you give it a buffer which
// is not aligned on 2, you may crash (See converter.def).
//
wxSoundStream& wxSoundStreamPcm::Read(void *buffer, wxUint32 len)
{
wxUint32 in_bufsize;
// We must have a multiple of 2
len &= 0x01;
if (!m_function_in) {
m_sndio->Read(buffer, len);
m_lastcount = m_sndio->GetLastAccess();
m_snderror = m_sndio->GetError();
return *this;
}
in_bufsize = GetReadSize(len);
if (len <= m_best_size) {
m_sndio->Read(m_prebuffer, in_bufsize);
m_snderror = m_sndio->GetError();
if (m_snderror != wxSOUND_NOERROR) {
m_lastcount = 0;
return *this;
}
m_function_in(m_prebuffer, buffer, m_sndio->GetLastAccess());
} else {
char *temp_buffer;
temp_buffer = new char[in_bufsize];
m_sndio->Read(temp_buffer, in_bufsize);
m_snderror = m_sndio->GetError();
if (m_snderror != wxSOUND_NOERROR) {
m_lastcount = 0;
return *this;
}
m_function_in(temp_buffer, buffer, m_sndio->GetLastAccess());
delete[] temp_buffer;
}
m_lastcount = (wxUint32)(m_sndio->GetLastAccess() * m_multiplier_in);
return *this;
}
wxSoundStream& wxSoundStreamPcm::Write(const void *buffer, wxUint32 len)
{
wxUint32 out_bufsize;
if (!m_function_out) {
m_sndio->Write(buffer, len);
m_lastcount = m_sndio->GetLastAccess();
m_snderror = m_sndio->GetError();
return *this;
}
out_bufsize = GetWriteSize(len);
if (len <= m_best_size) {
out_bufsize = GetWriteSize(len);
m_function_out(buffer, m_prebuffer, len);
m_sndio->Write(m_prebuffer, out_bufsize);
m_snderror = m_sndio->GetError();
if (m_snderror != wxSOUND_NOERROR) {
m_lastcount = 0;
return *this;
}
} else {
char *temp_buffer;
temp_buffer = new char[out_bufsize];
m_function_out(buffer, temp_buffer, len);
m_sndio->Write(temp_buffer, out_bufsize);
m_snderror = m_sndio->GetError();
if (m_snderror != wxSOUND_NOERROR) {
m_lastcount = 0;
return *this;
}
delete[] temp_buffer;
}
m_lastcount = (wxUint32)(m_sndio->GetLastAccess() / m_multiplier_out);
return *this;
}
bool wxSoundStreamPcm::SetSoundFormat(const wxSoundFormatBase& format)
{
wxSoundFormatBase *new_format;
wxSoundFormatPcm *pcm_format, *pcm_format2;
if (m_sndio->SetSoundFormat(format)) {
m_function_out = NULL;
m_function_in = NULL;
return TRUE;
}
if (format.GetType() != wxSOUND_PCM) {
m_snderror = wxSOUND_INVFRMT;
return FALSE;
}
if (m_sndformat)
delete m_sndformat;
new_format = m_sndio->GetSoundFormat().Clone();
pcm_format = (wxSoundFormatPcm *)&format;
pcm_format2 = (wxSoundFormatPcm *)new_format;
#if 0
// ----------------------------------------------------
// Test whether we need to resample
if (pcm_format->GetSampleRate() != pcm_format2->GetSampleRate()) {
wxUint32 src_rate, dst_rate;
src_rate = pcm_format->GetSampleRate();
dst_rate = pcm_format2->GetSampleRate();
m_needResampling = TRUE;
if (src_rate < dst_rate)
m_expandSamples = TRUE;
else
m_expandSamples = FALSE;
m_pitch = (src_rate << FLOATBITS) / dst_rate;
}
#endif
// ----------------------------------------------------
// Select table to use:
// * 8 bits -> 8 bits
// * 16 bits -> 8 bits
// * 8 bits -> 16 bits
// * 16 bits -> 16 bits
int table_no, table_no2;
int i_sign, i_swap;
switch (pcm_format->GetBPS()) {
case 8:
table_no = 0;
break;
case 16:
table_no = 1;
break;
}
switch (pcm_format2->GetBPS()) {
case 8:
table_no2 = 0;
break;
case 16:
table_no2 = 1;
break;
}
if (pcm_format2->Signed() != pcm_format->Signed())
i_sign = 1;
else
i_sign = 0;
#define MY_ORDER wxBYTE_ORDER
#if wxBYTE_ORDER == wxLITTLE_ENDIAN
#define OTHER_ORDER wxBIG_ENDIAN
#else
#define OTHER_ORDER wxLITTLE_ENDIAN
#endif
// --------------------------------------------------------
// Find the good converter !
if (pcm_format->GetOrder() == OTHER_ORDER) {
if (pcm_format->GetOrder() == pcm_format2->GetOrder())
i_swap = 2;
else
i_swap = 1;
} else {
if (pcm_format->GetOrder() == pcm_format2->GetOrder())
i_swap = 0;
else
i_swap = 1;
}
m_function_out = s_converters[table_no*2+table_no2][i_swap][i_sign];
m_function_in = s_converters[table_no2*2+table_no][i_swap][i_sign];
m_multiplier_out = s_converters_multip[table_no*2+table_no2];
m_multiplier_in = s_converters_multip[table_no2*2+table_no2];
if (m_prebuffer)
delete[] m_prebuffer;
// We try to minimize the need of dynamic memory allocation by preallocating a buffer. But
// to be sure it will be efficient we minimize the best size.
if (m_multiplier_in < m_multiplier_out) {
m_prebuffer_size = (wxUint32)(m_sndio->GetBestSize() * m_multiplier_out);
m_best_size = (wxUint32)(m_sndio->GetBestSize() * m_multiplier_in);
} else {
m_prebuffer_size = (wxUint32)(m_sndio->GetBestSize() * m_multiplier_in);
m_best_size = (wxUint32)(m_sndio->GetBestSize() * m_multiplier_out);
}
m_prebuffer = new char[m_prebuffer_size];
bool SetSoundFormatReturn;
SetSoundFormatReturn = m_sndio->SetSoundFormat(*new_format);
wxASSERT( SetSoundFormatReturn );
m_sndformat = new_format;
return TRUE;
}
wxUint32 wxSoundStreamPcm::GetWriteSize(wxUint32 len) const
{
// For the moment, it is simple but next time it will become more complicated
// (Resampling)
return (wxUint32)(len * m_multiplier_out);
}
wxUint32 wxSoundStreamPcm::GetReadSize(wxUint32 len) const
{
return (wxUint32)(len / m_multiplier_in);
}
// Resampling engine. NOT FINISHED and NOT INCLUDED but this is a first DRAFT.
#if 0
#define FLOATBITS 16
#define INTBITS 16
#define FLOATMASK 0xffff
#define INTMASK 0xffff0000
void ResamplingShrink_##DEPTH##(const void *source, void *destination, wxUint32 len)
{
wxUint##DEPTH## *source_data, *dest_data;
wxUint32 pos;
source_data = (wxUint##DEPTH## *)source;
dest_data = (wxUint##DEPTH## *)destination;
pos = m_saved_pos;
while (len > 0) {
// Increment the position in the input buffer
pos += m_pitch;
if (pos & INTMASK) {
pos &= FLOATMASK;
*dest_data ++ = *source_data;
}
len--;
source_data++;
}
m_saved_pos = pos;
}
#endif

View File

@@ -1,53 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndcpcm.h
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifndef _WX_SNDCPCM_H
#define _WX_SNDCPCM_H
#ifdef __GNUG__
#pragma interface "sndcpcm.h"
#endif
#include <stddef.h>
#include "sndcodec.h"
//
// PCM converter class
//
class wxSoundStreamPcm: public wxSoundStreamCodec {
public:
typedef void (*ConverterType)(const void *buf_in, void *buf_out,
wxUint32 len);
wxSoundStreamPcm(wxSoundStream& sndio);
~wxSoundStreamPcm();
wxSoundStream& Read(void *buffer, wxUint32 len);
wxSoundStream& Write(const void *buffer, wxUint32 len);
bool SetSoundFormat(const wxSoundFormatBase& format);
wxUint32 GetBestSize() const;
protected:
wxUint32 GetReadSize(wxUint32 len) const;
wxUint32 GetWriteSize(wxUint32 len) const;
protected:
ConverterType m_function_out, m_function_in;
// Static temporary buffer
char *m_prebuffer;
wxUint32 m_prebuffer_size;
// Estimated best size to fit into the static buffer
wxUint32 m_best_size;
// Multiplier for IO buffer size
float m_multiplier_in, m_multiplier_out;
};
#endif

View File

@@ -1,273 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndesd.cpp
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "sndesd.cpp"
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <wx/defs.h>
#include <wx/string.h>
#include <esd.h>
#include "sndbase.h"
#include "sndesd.h"
#include "sndpcm.h"
#ifdef __WXGTK__
#include <gdk/gdk.h>
#endif
#define MY_ESD_NAME "wxWindows/wxSoundStreamESD"
// -----------------------------------------------------------------------------------------------
// wxSoundStreamESD: ESD sound driver
// --------------------------------------------------------------------------------------------
// Constructors/Destructors
// --------------------------------------------------------------------------------------------
wxSoundStreamESD::wxSoundStreamESD(const wxString& hostname)
{
wxSoundFormatPcm pcm_default;
// First, we make some basic test: is there ESD on this computer ?
if (hostname.IsNull())
m_fd_output = esd_play_stream(ESD_PLAY | ESD_STREAM, 22050,
hostname.mb_str(), MY_ESD_NAME);
else
m_fd_output = esd_play_stream(ESD_PLAY | ESD_STREAM, 22050,
NULL, MY_ESD_NAME);
if (m_fd_output == -1) {
// Answer: no. We return with an error.
m_snderror = wxSOUND_INVDEV;
return;
}
// Close this unuseful stream.
esd_close(m_fd_output);
m_hostname = hostname;
// Set the default audio format
SetSoundFormat(pcm_default);
// Initialize some variable
m_snderror = wxSOUND_NOERROR;
m_esd_stop = TRUE;
m_q_filled = TRUE;
m_fd_output= -1;
}
wxSoundStreamESD::~wxSoundStreamESD()
{
// Close all remaining streams
if (m_fd_output > 0)
esd_close(m_fd_output);
if (m_fd_input > 0)
esd_close(m_fd_input);
}
// --------------------------------------------------------------------------------------------
// Read several samples
// --------------------------------------------------------------------------------------------
wxSoundStream& wxSoundStreamESD::Read(void *buffer, wxUint32 len)
{
int ret;
m_lastcount = (wxUint32)ret = read(m_fd_input, buffer, len);
if (ret < 0)
m_snderror = wxSOUND_IOERROR;
else
m_snderror = wxSOUND_NOERROR;
return *this;
}
// --------------------------------------------------------------------------------------------
// Write several samples
// --------------------------------------------------------------------------------------------
wxSoundStream& wxSoundStreamESD::Write(const void *buffer, wxUint32 len)
{
int ret;
m_lastcount = (wxUint32)ret = write(m_fd_output, buffer, len);
if (ret < 0)
m_snderror = wxSOUND_IOERROR;
else
m_snderror = wxSOUND_NOERROR;
m_q_filled = TRUE;
return *this;
}
// --------------------------------------------------------------------------------------------
// SetSoundFormat(): this function specifies which format we want and which format is available
// --------------------------------------------------------------------------------------------
bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase& format)
{
wxSoundFormatPcm *pcm_format;
if (format.GetType() != wxSOUND_PCM) {
m_snderror = wxSOUND_INVFRMT;
return FALSE;
}
if (m_fd_input == -1 && m_fd_output == -1) {
m_snderror = wxSOUND_INVDEV;
return FALSE;
}
if (m_sndformat)
delete m_sndformat;
m_sndformat = format.Clone();
if (!m_sndformat) {
m_snderror = wxSOUND_MEMERROR;
return FALSE;
}
pcm_format = (wxSoundFormatPcm *)m_sndformat;
// Detect the best format
DetectBest(pcm_format);
m_snderror = wxSOUND_NOERROR;
if (*pcm_format != format) {
m_snderror = wxSOUND_NOEXACT;
return FALSE;
}
return TRUE;
}
// --------------------------------------------------------------------------------------------
// _wxSound_OSS_CBack (internal): it is called when the driver (ESD) is ready for a next
// buffer.
// --------------------------------------------------------------------------------------------
#ifdef __WXGTK__
static void _wxSound_OSS_CBack(gpointer data, int source,
GdkInputCondition condition)
{
wxSoundStreamESD *esd = (wxSoundStreamESD *)data;
switch (condition) {
case GDK_INPUT_READ:
esd->WakeUpEvt(wxSOUND_INPUT);
break;
case GDK_INPUT_WRITE:
esd->WakeUpEvt(wxSOUND_OUTPUT);
break;
default:
break;
}
}
#endif
// --------------------------------------------------------------------------------------------
// WakeUpEvt() (internal): it is called by _wxSound_OSS_CBack to bypass the C++ protection
// --------------------------------------------------------------------------------------------
void wxSoundStreamESD::WakeUpEvt(int evt)
{
m_q_filled = FALSE;
OnSoundEvent(evt);
}
// --------------------------------------------------------------------------------------------
// StartProduction(): see wxSoundStream
// --------------------------------------------------------------------------------------------
bool wxSoundStreamESD::StartProduction(int evt)
{
wxSoundFormatPcm *pcm;
int flag = 0;
if (!m_esd_stop)
StopProduction();
pcm = (wxSoundFormatPcm *)m_sndformat;
flag |= (pcm->GetBPS() == 16) ? ESD_BITS16 : ESD_BITS8;
flag |= (pcm->GetChannels() == 2) ? ESD_STEREO : ESD_MONO;
if ((evt & wxSOUND_OUTPUT) != 0) {
flag |= ESD_PLAY | ESD_STREAM;
m_fd_output = esd_play_stream(flag, pcm->GetSampleRate(), NULL,
MY_ESD_NAME);
}
if ((evt & wxSOUND_INPUT) != 0) {
flag |= ESD_RECORD | ESD_STREAM;
m_fd_input = esd_record_stream(flag, pcm->GetSampleRate(), NULL,
MY_ESD_NAME);
}
#ifdef __WXGTK__
if ((evt & wxSOUND_OUTPUT) != 0) {
m_tag_output = gdk_input_add(m_fd_output, GDK_INPUT_WRITE, _wxSound_OSS_CBack, (gpointer)this);
}
if ((evt & wxSOUND_INPUT) != 0) {
m_tag_input = gdk_input_add(m_fd_input, GDK_INPUT_READ, _wxSound_OSS_CBack, (gpointer)this);
}
#endif
m_esd_stop = FALSE;
m_q_filled = FALSE;
return TRUE;
}
bool wxSoundStreamESD::StopProduction()
{
if (m_esd_stop)
return FALSE;
if (m_fd_input != -1) {
esd_close(m_fd_input);
#ifdef __WXGTK__
gdk_input_remove(m_tag_input);
#endif
}
if (m_fd_output != -1) {
esd_close(m_fd_output);
#ifdef __WXGTK__
gdk_input_remove(m_tag_output);
#endif
}
m_fd_input = -1;
m_fd_output= -1;
m_esd_stop = TRUE;
m_q_filled = TRUE;
return TRUE;
}
//
// Detect the closest format (The best).
//
void wxSoundStreamESD::DetectBest(wxSoundFormatPcm *pcm)
{
wxSoundFormatPcm best_pcm;
// We change neither the number of channels nor the sample rate because ESD is clever.
best_pcm.SetSampleRate(pcm->GetSampleRate());
best_pcm.SetChannels(pcm->GetChannels());
// It supports 16 bits
if (pcm->GetBPS() == 16)
best_pcm.SetBPS(16);
best_pcm.SetOrder(wxLITTLE_ENDIAN);
best_pcm.Signed(TRUE);
// Finally recopy the new format
*pcm = best_pcm;
}

View File

@@ -1,51 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndesd.h
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifndef _WX_SNDESD_H
#define _WX_SNDESD_H
#ifdef __GNUG__
#pragma interface "sndesd.h"
#endif
#include <wx/string.h>
#include "sndbase.h"
#include "sndpcm.h"
//
// ESD output class
//
class wxSoundStreamESD : public wxSoundStream {
public:
wxSoundStreamESD(const wxString& hostname = _T("localhost"));
~wxSoundStreamESD();
wxSoundStream& Read(void *buffer, wxUint32 len);
wxSoundStream& Write(const void *buffer, wxUint32 len);
bool SetSoundFormat(const wxSoundFormatBase& format);
bool StartProduction(int evt);
bool StopProduction();
// You should not call this.
void WakeUpEvt(int evt);
bool QueueFilled() const { return m_q_filled; }
protected:
int m_fd_input, m_fd_output;
int m_tag_input, m_tag_output;
bool m_esd_stop;
wxString m_hostname;
bool m_q_filled;
private:
void DetectBest(wxSoundFormatPcm *pcm);
};
#endif

View File

@@ -1,407 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndfile.cpp
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999, 2000
// CVSID: $Id$
// --------------------------------------------------------------------------
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/stream.h>
#endif
#include "sndbase.h"
#include "sndcodec.h"
#include "sndfile.h"
#include "sndcpcm.h"
#include "sndulaw.h"
#include "sndg72x.h"
// --------------------------------------------------------------------------
// Sound codec router
// A very important class: it ensures that everybody is satisfied.
// It is supposed to create as many codec as it is necessary to transform
// a signal in a specific format in an another.
// --------------------------------------------------------------------------
wxSoundRouterStream::wxSoundRouterStream(wxSoundStream& sndio)
: wxSoundStreamCodec(sndio)
{
m_router = NULL;
}
wxSoundRouterStream::~wxSoundRouterStream()
{
if (m_router)
delete m_router;
}
// --------------------------------------------------------------------------
// Read(void *buffer, wxUint32 len): It reads data synchronously. See sndbase.h
// for possible errors and behaviours ...
// --------------------------------------------------------------------------
wxSoundStream& wxSoundRouterStream::Read(void *buffer, wxUint32 len)
{
if (m_router) {
m_router->Read(buffer, len);
m_snderror = m_router->GetError();
m_lastcount = m_router->GetLastAccess();
} else {
m_sndio->Read(buffer, len);
m_snderror = m_sndio->GetError();
m_lastcount = m_sndio->GetLastAccess();
}
return *this;
}
// --------------------------------------------------------------------------
// Write(const void *buffer, wxUint32 len): It writes data synchronously
// --------------------------------------------------------------------------
wxSoundStream& wxSoundRouterStream::Write(const void *buffer, wxUint32 len)
{
if (m_router) {
m_router->Write(buffer, len);
m_snderror = m_router->GetError();
m_lastcount = m_router->GetLastAccess();
} else {
m_sndio->Write(buffer, len);
m_snderror = m_sndio->GetError();
m_lastcount = m_sndio->GetLastAccess();
}
return *this;
}
// --------------------------------------------------------------------------
// SetSoundFormat(const wxSoundFormatBase& format) first tries to setup the
// sound driver using the specified format. If this fails, it uses personnal
// codec converters: for the moment there is a PCM converter (PCM to PCM:
// with optional resampling, ...), an ULAW converter (ULAW to PCM), a G72X
// converter (G72X to PCM). If nothing works, it returns FALSE.
// --------------------------------------------------------------------------
bool wxSoundRouterStream::SetSoundFormat(const wxSoundFormatBase& format)
{
if (m_router)
delete m_router;
// First, we try to setup the sound device
if (m_sndio->SetSoundFormat(format)) {
// We are lucky, it is working.
wxSoundStream::SetSoundFormat(m_sndio->GetSoundFormat());
return TRUE;
}
switch(format.GetType()) {
case wxSOUND_NOFORMAT:
return FALSE;
case wxSOUND_PCM:
m_router = new wxSoundStreamPcm(*m_sndio);
m_router->SetSoundFormat(format);
break;
case wxSOUND_ULAW:
m_router = new wxSoundStreamUlaw(*m_sndio);
m_router->SetSoundFormat(format);
break;
case wxSOUND_G72X:
m_router = new wxSoundStreamG72X(*m_sndio);
m_router->SetSoundFormat(format);
break;
}
wxSoundStream::SetSoundFormat(m_router->GetSoundFormat());
return TRUE;
}
// --------------------------------------------------------------------------
// GetBestSize() returns the specific best buffer size a sound driver
// can manage. It means that it will be easier for it to manage the buffer
// and so it will be faster and in some case more accurate for real-time event.
// --------------------------------------------------------------------------
wxUint32 wxSoundRouterStream::GetBestSize() const
{
if (m_router)
return m_router->GetBestSize();
else
return m_sndio->GetBestSize();
}
// --------------------------------------------------------------------------
// StartProduction(int evt). See sndbase.h
// --------------------------------------------------------------------------
bool wxSoundRouterStream::StartProduction(int evt)
{
if (!m_router) {
if (m_sndio->StartProduction(evt))
return TRUE;
m_snderror = m_sndio->GetError();
m_lastcount = m_sndio->GetLastAccess();
return FALSE;
}
if (m_router->StartProduction(evt))
return TRUE;
m_snderror = m_router->GetError();
m_lastcount = m_router->GetLastAccess();
return FALSE;
}
// --------------------------------------------------------------------------
// StopProduction(). See sndbase.h
// --------------------------------------------------------------------------
bool wxSoundRouterStream::StopProduction()
{
if (!m_router) {
if (m_sndio->StopProduction())
return TRUE;
m_snderror = m_sndio->GetError();
m_lastcount = m_sndio->GetLastAccess();
return FALSE;
}
if (m_router->StopProduction())
return TRUE;
m_snderror = m_router->GetError();
m_lastcount = m_router->GetLastAccess();
return FALSE;
}
// --------------------------------------------------------------------------
// wxSoundFileStream: generic reader
// --------------------------------------------------------------------------
wxSoundFileStream::wxSoundFileStream(wxInputStream& stream,
wxSoundStream& io_sound)
: m_codec(io_sound), m_sndio(&io_sound),
m_input(&stream), m_output(NULL), m_state(wxSOUND_FILE_STOPPED)
{
m_length = 0;
m_bytes_left = 0;
m_prepared = FALSE;
}
wxSoundFileStream::wxSoundFileStream(wxOutputStream& stream,
wxSoundStream& io_sound)
: m_codec(io_sound), m_sndio(&io_sound),
m_input(NULL), m_output(&stream), m_state(wxSOUND_FILE_STOPPED)
{
m_length = 0;
m_bytes_left = 0;
m_prepared = FALSE;
}
wxSoundFileStream::~wxSoundFileStream()
{
if (m_state != wxSOUND_FILE_STOPPED)
Stop();
}
bool wxSoundFileStream::Play()
{
if (m_state != wxSOUND_FILE_STOPPED)
return FALSE;
if (!m_prepared)
if (!PrepareToPlay())
return FALSE;
m_state = wxSOUND_FILE_PLAYING;
if (!StartProduction(wxSOUND_OUTPUT))
return FALSE;
return TRUE;
}
bool wxSoundFileStream::Record(wxUint32 time)
{
if (m_state != wxSOUND_FILE_STOPPED)
return FALSE;
if (!PrepareToRecord(time))
return FALSE;
FinishPreparation(m_sndformat->GetBytesFromTime(time));
m_state = wxSOUND_FILE_RECORDING;
if (!StartProduction(wxSOUND_INPUT))
return FALSE;
return TRUE;
}
bool wxSoundFileStream::Stop()
{
if (m_state == wxSOUND_FILE_STOPPED)
return FALSE;
if (!StopProduction())
return FALSE;
m_prepared = FALSE;
if (m_state == wxSOUND_FILE_RECORDING)
if (!FinishRecording()) {
m_state = wxSOUND_FILE_STOPPED;
return FALSE;
}
if (m_input)
m_input->SeekI(0, wxFromStart);
if (m_output)
m_output->SeekO(0, wxFromStart);
m_state = wxSOUND_FILE_STOPPED;
return TRUE;
}
bool wxSoundFileStream::Pause()
{
if (m_state == wxSOUND_FILE_PAUSED || m_state == wxSOUND_FILE_STOPPED)
return FALSE;
if (!StopProduction())
return FALSE;
m_oldstate = m_state;
m_state = wxSOUND_FILE_PAUSED;
return TRUE;
}
bool wxSoundFileStream::Resume()
{
if (m_state == wxSOUND_FILE_PLAYING || m_state == wxSOUND_FILE_RECORDING ||
m_state == wxSOUND_FILE_STOPPED)
return FALSE;
if (!StartProduction( (m_oldstate == wxSOUND_FILE_PLAYING) ?
wxSOUND_OUTPUT : wxSOUND_INPUT))
return FALSE;
m_state = m_oldstate;
return TRUE;
}
wxSoundStream& wxSoundFileStream::Read(void *buffer, wxUint32 len)
{
m_lastcount = GetData(buffer, len);
return *this;
}
wxSoundStream& wxSoundFileStream::Write(const void *buffer, wxUint32 len)
{
m_lastcount = PutData(buffer, len);
return *this;
}
bool wxSoundFileStream::StartProduction(int evt)
{
m_sndio->SetEventHandler(this);
if (!m_codec.StartProduction(evt))
return FALSE;
return TRUE;
}
bool wxSoundFileStream::StopProduction()
{
return m_codec.StopProduction();
}
void wxSoundFileStream::FinishPreparation(wxUint32 len)
{
m_bytes_left = m_length = len;
m_prepared = TRUE;
}
wxString wxSoundFileStream::GetCodecName() const
{
return wxString(wxT("wxSoundFileStream base codec"));
}
wxUint32 wxSoundFileStream::GetLength()
{
if (m_input && !m_prepared && GetError() == wxSOUND_NOERROR)
return (PrepareToPlay()) ? m_length : 0;
return m_length;
}
wxUint32 wxSoundFileStream::GetPosition()
{
if (!m_prepared && m_input != NULL && GetError() == wxSOUND_NOERROR)
PrepareToPlay();
return m_length-m_bytes_left;
}
wxUint32 wxSoundFileStream::SetPosition(wxUint32 new_position)
{
if (!m_prepared && m_input != NULL && GetError() == wxSOUND_NOERROR)
PrepareToPlay();
if (!m_prepared)
return 0;
if (!RepositionStream(new_position))
return m_length-m_bytes_left;
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();
char *buffer;
buffer = new char[len];
wxSoundStream::OnSoundEvent(evt);
while (!m_sndio->QueueFilled()) {
switch(evt) {
case wxSOUND_INPUT:
if (len > m_bytes_left)
len = m_bytes_left;
len = m_codec.Read(buffer, len).GetLastAccess();
PutData(buffer, len);
m_bytes_left -= len;
if (m_bytes_left == 0) {
Stop();
delete[] buffer;
return;
}
break;
case wxSOUND_OUTPUT:
if (len > m_bytes_left)
len = m_bytes_left;
len = GetData(buffer, len);
m_bytes_left -= len;
if (m_bytes_left == 0) {
Stop();
delete[] buffer;
return;
}
m_codec.Write(buffer, len);
break;
}
}
delete[] buffer;
}
bool wxSoundFileStream::SetSoundFormat(const wxSoundFormatBase& format)
{
wxSoundStream::SetSoundFormat(format);
return m_codec.SetSoundFormat(format);
}

View File

@@ -1,126 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndfile.h
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifndef _WX_SNDFILE_H
#define _WX_SNDFILE_H
#include <wx/defs.h>
#include <wx/stream.h>
#include <stdlib.h>
#include "sndbase.h"
#include "sndcodec.h"
#define wxSOUND_INFINITE_TIME ((wxUint32)-1)
//
// Codec router class
//
class WXDLLEXPORT wxSoundRouterStream: public wxSoundStreamCodec {
public:
wxSoundRouterStream(wxSoundStream& sndio);
~wxSoundRouterStream();
wxSoundStream& Read(void *buffer, wxUint32 len);
wxSoundStream& Write(const void *buffer, wxUint32 len);
bool SetSoundFormat(const wxSoundFormatBase& format);
bool StartProduction(int evt);
bool StopProduction();
wxUint32 GetBestSize() const;
protected:
wxSoundStream *m_router;
};
typedef enum {
wxSOUND_FILE_STOPPED,
wxSOUND_FILE_PAUSED,
wxSOUND_FILE_PLAYING,
wxSOUND_FILE_RECORDING
} wxSoundFileState;
//
// Base class for file coders/decoders
//
class wxSoundFileStream: public wxSoundStream {
public:
wxSoundFileStream(wxInputStream& stream, wxSoundStream& io_sound);
wxSoundFileStream(wxOutputStream& stream, wxSoundStream& io_sound);
~wxSoundFileStream();
// Usual sound file calls (Play, Stop, ...)
bool Play();
bool Record(wxUint32 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);
// 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);
// This function returns the Codec name. This is useful for those who want to build
// a player (But also in some other case).
virtual wxString GetCodecName() const;
// 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:
wxSoundRouterStream m_codec;
wxSoundStream *m_sndio;
wxInputStream *m_input;
wxOutputStream *m_output;
wxSoundFileState m_state, m_oldstate;
wxUint32 m_length, m_bytes_left;
bool m_prepared;
protected:
virtual bool PrepareToPlay() = 0;
virtual bool PrepareToRecord(wxUint32 time) = 0;
virtual bool FinishRecording() = 0;
virtual bool RepositionStream(wxUint32 position) = 0;
void FinishPreparation(wxUint32 len);
virtual wxUint32 GetData(void *buffer, wxUint32 len) = 0;
virtual wxUint32 PutData(const void *buffer, wxUint32 len) = 0;
void OnSoundEvent(int evt);
};
#endif

View File

@@ -1,304 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndg72x.cpp
// Purpose:
// Date: 08/26/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "sndg72x.cpp"
#endif
#include <wx/wxprec.h>
#include "sndbase.h"
#include "sndfile.h"
#include "sndpcm.h"
#include "sndg72x.h"
#include "g72x.h"
// --------------------------------------------------------------------------
// wxSoundFormatG72X
// --------------------------------------------------------------------------
wxSoundFormatG72X::wxSoundFormatG72X()
: m_srate(22050)
{
}
wxSoundFormatG72X::~wxSoundFormatG72X()
{
}
void wxSoundFormatG72X::SetSampleRate(wxUint32 srate)
{
m_srate = srate;
}
wxUint32 wxSoundFormatG72X::GetSampleRate() const
{
return m_srate;
}
void wxSoundFormatG72X::SetG72XType(wxSoundG72XType type)
{
m_g72x_type = type;
}
wxSoundFormatBase *wxSoundFormatG72X::Clone() const
{
wxSoundFormatG72X *g72x = new wxSoundFormatG72X();
g72x->m_srate = m_srate;
g72x->m_g72x_type = m_g72x_type;
return g72x;
}
wxUint32 wxSoundFormatG72X::GetTimeFromBytes(wxUint32 bytes) const
{
int n_bits;
switch (m_g72x_type) {
case wxSOUND_G721:
n_bits = 4;
break;
case wxSOUND_G723_24:
n_bits = 3;
break;
case wxSOUND_G723_40:
n_bits = 5;
break;
default:
n_bits = 0;
break;
}
return (wxUint32)((bytes / m_srate) * n_bits) / 8;
}
wxUint32 wxSoundFormatG72X::GetBytesFromTime(wxUint32 time) const
{
int n_bits;
switch (m_g72x_type) {
case wxSOUND_G721:
n_bits = 4;
break;
case wxSOUND_G723_24:
n_bits = 3;
break;
case wxSOUND_G723_40:
n_bits = 5;
break;
default:
n_bits = 0;
}
return (wxUint32)((time * m_srate * n_bits) / 8);
}
bool wxSoundFormatG72X::operator !=(const wxSoundFormatBase& frmt2) const
{
wxSoundFormatG72X *g72x = (wxSoundFormatG72X *)&frmt2;
if (frmt2.GetType() != wxSOUND_G72X)
return TRUE;
return (g72x->m_srate != m_srate || g72x->m_g72x_type != m_g72x_type);
}
// --------------------------------------------------------------------------
// wxSoundStreamG72X
// --------------------------------------------------------------------------
wxSoundStreamG72X::wxSoundStreamG72X(wxSoundStream& sndio)
: wxSoundStreamCodec(sndio)
{
// PCM converter
m_router = new wxSoundRouterStream(sndio);
m_state = new g72state;
g72x_init_state(m_state);
}
wxSoundStreamG72X::~wxSoundStreamG72X()
{
delete m_router;
}
wxSoundStream& wxSoundStreamG72X::Read(void *buffer, wxUint32 len)
{
wxUint16 *old_linear;
register wxUint16 *linear_buffer;
register wxUint32 real_len;
register wxUint32 countdown = len;
real_len = (len * 8 / m_n_bits);
old_linear = linear_buffer = new wxUint16[real_len];
m_router->Read(linear_buffer, real_len);
real_len = (wxUint32)(m_router->GetLastAccess() * ((float)m_n_bits / 8));
if (!real_len)
return *m_router;
m_io_buffer = (wxUint8 *)buffer;
m_current_b_pos = 0;
while (countdown != 0) {
PutBits(m_coder(*linear_buffer++, AUDIO_ENCODING_LINEAR, m_state));
countdown--;
}
m_lastcount = real_len;
m_snderror = m_router->GetError();
delete[] old_linear;
return *this;
}
wxSoundStream& wxSoundStreamG72X::Write(const void *buffer, wxUint32 len)
{
wxUint16 *old_linear;
register wxUint16 *linear_buffer;
register wxUint32 countdown = len;
register wxUint32 real_len;
// Compute the real length (PCM format) to sendt to the sound card
real_len = (len * m_n_bits / 8);
// Allocate a temporary buffer
old_linear = linear_buffer = new wxUint16[real_len];
// Bad, we override the const
m_io_buffer = (wxUint8 *)buffer;
m_current_b_pos = 0;
// Decode the datas
while (countdown != 0) {
*linear_buffer++ = m_decoder(GetBits(), AUDIO_ENCODING_LINEAR, m_state);
countdown--;
}
m_lastcount = len;
// Send them to the sound card
m_router->Write(old_linear, real_len);
// Destroy the temporary buffer
delete[] old_linear;
return *m_router;
}
bool wxSoundStreamG72X::SetSoundFormat(const wxSoundFormatBase& format)
{
if (format.GetType() != wxSOUND_G72X) {
m_snderror = wxSOUND_INVFRMT;
return FALSE;
}
wxSoundFormatPcm pcm;
wxSoundFormatG72X *g72x;
wxSoundStreamCodec::SetSoundFormat(format);
g72x = (wxSoundFormatG72X *)m_sndformat;
// Set PCM as the output format of the codec
pcm.SetSampleRate(g72x->GetSampleRate());
pcm.SetBPS(16);
pcm.SetChannels(1); // Only mono supported
pcm.Signed(TRUE);
pcm.SetOrder(wxBYTE_ORDER);
// Look for the correct codec to use and set its bit width
switch (g72x->GetG72XType()) {
case wxSOUND_G721:
m_n_bits = 4;
m_coder = g721_encoder;
m_decoder = g721_decoder;
break;
case wxSOUND_G723_24:
m_n_bits = 3;
m_coder = g723_24_encoder;
m_decoder = g723_24_decoder;
break;
case wxSOUND_G723_40:
m_n_bits = 5;
m_coder = g723_40_encoder;
m_decoder = g723_40_decoder;
break;
}
// Let the router finish the work
m_router->SetSoundFormat(pcm);
return TRUE;
}
#define BYTE_SIZE 8
wxUint8 wxSoundStreamG72X::GetBits()
{
register wxUint8 bits;
// We have two bytes to compute
if (m_current_b_pos < m_n_bits) {
register wxUint8 b_left;
// TRANSLATE the mask
m_current_mask >>= m_current_b_pos;
// GET the last bits: 0001..1
bits = (m_current_byte & m_current_mask) << (m_n_bits - m_current_b_pos);
// GEN: 1. n times .1000
b_left = BYTE_SIZE-m_n_bits;
m_current_mask = ((1 << m_n_bits) - 1) << b_left;
// GET the next byte
m_current_byte = *m_io_buffer++;
register wxUint8 tmp_mask;
// COMPUTE a new temporary mask to get the last bits
b_left = m_n_bits - b_left;
tmp_mask = (1 << b_left) - 1;
// TRANSLATE the old mask to get ready for the next time
m_current_mask >>= b_left;
// COMPUTE the new bit position
b_left = BYTE_SIZE - b_left;
m_current_b_pos = b_left;
tmp_mask <<= b_left;
// GET the last bits
bits |= (m_current_byte & tmp_mask) >> b_left;
} else {
m_current_mask >>= m_n_bits;
m_current_b_pos -= m_n_bits;
bits = (m_current_byte & m_current_mask) >> m_current_b_pos;
}
return bits;
}
void wxSoundStreamG72X::PutBits(wxUint8 bits)
{
if (m_current_b_pos < m_n_bits) {
register wxUint8 tmp_mask;
register wxUint8 diff;
diff = m_n_bits - m_current_b_pos;
// Pack bits and put the byte in the buffer
m_current_byte |= bits >> diff;
*m_io_buffer++ = m_current_byte;
// Gen a mask
tmp_mask = ~((1 << diff) - 1);
m_current_b_pos = BYTE_SIZE - (m_n_bits - m_current_b_pos);
m_current_byte = (bits & (tmp_mask)) << m_current_b_pos;
} else {
m_current_b_pos -= m_n_bits;
bits <<= m_current_b_pos;
m_current_byte |= bits;
}
}

View File

@@ -1,84 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndg72x.h
// Purpose:
// Date: 08/26/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifndef _WX_SNDG72X_H
#define _WX_SNDG72X_H
#ifdef __GNUG__
#pragma interface "sndg72x.h"
#endif
#include <stddef.h>
#include "sndcodec.h"
#include "sndbase.h"
typedef enum {
wxSOUND_G721,
wxSOUND_G723_24,
wxSOUND_G723_40
} wxSoundG72XType;
// This fixes a bug in Mingw95
typedef struct g72x_state g72state;
//
// G72X format
//
class WXDLLEXPORT wxSoundFormatG72X: public wxSoundFormatBase {
public:
wxSoundFormatG72X();
~wxSoundFormatG72X();
void SetG72XType(wxSoundG72XType type);
wxSoundG72XType GetG72XType() const { return m_g72x_type; }
void SetSampleRate(wxUint32 srate);
wxUint32 GetSampleRate() const;
wxSoundFormatType GetType() const { return wxSOUND_G72X; }
wxSoundFormatBase *Clone() const;
wxUint32 GetTimeFromBytes(wxUint32 bytes) const;
wxUint32 GetBytesFromTime(wxUint32 time) const;
bool operator !=(const wxSoundFormatBase& frmt2) const;
protected:
wxUint32 m_srate;
wxSoundG72XType m_g72x_type;
};
//
// ULAW converter class
//
class WXDLLEXPORT wxSoundRouterStream;
class WXDLLEXPORT wxSoundStreamG72X: public wxSoundStreamCodec {
public:
wxSoundStreamG72X(wxSoundStream& sndio);
~wxSoundStreamG72X();
wxSoundStream& Read(void *buffer, wxUint32 len);
wxSoundStream& Write(const void *buffer, wxUint32 len);
bool SetSoundFormat(const wxSoundFormatBase& format);
protected:
wxSoundRouterStream *m_router;
wxUint8 m_n_bits, m_current_mask, m_current_b_pos, m_current_byte;
wxUint8 *m_io_buffer;
g72state *m_state;
int (*m_coder)(int code, int in_code, struct g72x_state *state);
int (*m_decoder)(int code, int out_code, struct g72x_state *state);
protected:
void PutBits(wxUint8 bits);
wxUint8 GetBits();
};
#endif

View File

@@ -1,338 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndoss.cpp
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999, 2000
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "sndoss.cpp"
#endif
#include <sys/soundcard.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <wx/defs.h>
#include <wx/string.h>
#include "sndbase.h"
#include "sndoss.h"
#include "sndpcm.h"
#ifdef __WXGTK__
#include <gdk/gdk.h>
#endif
wxSoundStreamOSS::wxSoundStreamOSS(const wxString& dev_name)
{
wxSoundFormatPcm pcm_default;
m_fd = open(dev_name.mb_str(), O_WRONLY);
if (m_fd == -1) {
m_snderror = wxSOUND_INVDEV;
return;
}
m_devname = dev_name;
wxSoundStreamOSS::SetSoundFormat(pcm_default);
ioctl(m_fd, SNDCTL_DSP_GETBLKSIZE, &m_bufsize);
m_snderror = wxSOUND_NOERROR;
close(m_fd);
m_oss_stop = TRUE;
m_q_filled = TRUE;
}
wxSoundStreamOSS::~wxSoundStreamOSS()
{
if (m_fd > 0)
close(m_fd);
}
wxUint32 wxSoundStreamOSS::GetBestSize() const
{
return m_bufsize;
}
wxSoundStream& wxSoundStreamOSS::Read(void *buffer, wxUint32 len)
{
int ret;
m_lastcount = (wxUint32)ret = read(m_fd, buffer, len);
m_q_filled = TRUE;
if (ret < 0)
m_snderror = wxSOUND_IOERROR;
else
m_snderror = wxSOUND_NOERROR;
return *this;
}
wxSoundStream& wxSoundStreamOSS::Write(const void *buffer, wxUint32 len)
{
int ret;
m_lastcount = (wxUint32)ret = write(m_fd, buffer, len);
m_q_filled = TRUE;
if (ret < 0)
m_snderror = wxSOUND_IOERROR;
else
m_snderror = wxSOUND_NOERROR;
return *this;
}
bool wxSoundStreamOSS::SetSoundFormat(const wxSoundFormatBase& format)
{
int tmp;
wxSoundFormatPcm *pcm_format;
if (format.GetType() != wxSOUND_PCM) {
m_snderror = wxSOUND_INVFRMT;
return FALSE;
}
if (m_fd == -1) {
m_snderror = wxSOUND_INVDEV;
return FALSE;
}
if (m_sndformat)
delete m_sndformat;
m_sndformat = format.Clone();
if (!m_sndformat) {
m_snderror = wxSOUND_MEMERROR;
return FALSE;
}
pcm_format = (wxSoundFormatPcm *)m_sndformat;
// Set the sample rate field.
tmp = pcm_format->GetSampleRate();
ioctl(m_fd, SNDCTL_DSP_SPEED, &tmp);
pcm_format->SetSampleRate(tmp);
// Detect the best format
DetectBest(pcm_format);
SetupFormat(pcm_format);
tmp = pcm_format->GetChannels();
ioctl(m_fd, SNDCTL_DSP_CHANNELS, &tmp);
pcm_format->SetChannels(tmp);
m_snderror = wxSOUND_NOERROR;
if (*pcm_format != format) {
m_snderror = wxSOUND_NOEXACT;
return FALSE;
}
return TRUE;
}
bool wxSoundStreamOSS::SetupFormat(wxSoundFormatPcm *pcm_format)
{
int tmp;
switch(pcm_format->GetBPS()) {
case 8:
if (pcm_format->Signed())
tmp = AFMT_S8;
else
tmp = AFMT_U8;
break;
case 16:
switch (pcm_format->GetOrder()) {
case wxBIG_ENDIAN:
if (pcm_format->Signed())
tmp = AFMT_S16_BE;
else
tmp = AFMT_U16_BE;
break;
case wxLITTLE_ENDIAN:
if (pcm_format->Signed())
tmp = AFMT_S16_LE;
else
tmp = AFMT_U16_LE;
break;
}
break;
}
ioctl(m_fd, SNDCTL_DSP_SETFMT, &tmp);
// Demangling.
switch (tmp) {
case AFMT_U8:
pcm_format->SetBPS(8);
pcm_format->Signed(FALSE);
break;
case AFMT_S8:
pcm_format->SetBPS(8);
pcm_format->Signed(TRUE);
break;
case AFMT_U16_LE:
pcm_format->SetBPS(16);
pcm_format->Signed(FALSE);
pcm_format->SetOrder(wxLITTLE_ENDIAN);
break;
case AFMT_U16_BE:
pcm_format->SetBPS(16);
pcm_format->Signed(FALSE);
pcm_format->SetOrder(wxBIG_ENDIAN);
break;
case AFMT_S16_LE:
pcm_format->SetBPS(16);
pcm_format->Signed(TRUE);
pcm_format->SetOrder(wxLITTLE_ENDIAN);
break;
case AFMT_S16_BE:
pcm_format->SetBPS(16);
pcm_format->Signed(TRUE);
pcm_format->SetOrder(wxBIG_ENDIAN);
break;
}
return TRUE;
}
#ifdef __WXGTK__
static void _wxSound_OSS_CBack(gpointer data, int source,
GdkInputCondition condition)
{
wxSoundStreamOSS *oss = (wxSoundStreamOSS *)data;
switch (condition) {
case GDK_INPUT_READ:
oss->WakeUpEvt(wxSOUND_INPUT);
break;
case GDK_INPUT_WRITE:
oss->WakeUpEvt(wxSOUND_OUTPUT);
break;
default:
break;
}
}
#endif
void wxSoundStreamOSS::WakeUpEvt(int evt)
{
m_q_filled = FALSE;
OnSoundEvent(evt);
}
bool wxSoundStreamOSS::StartProduction(int evt)
{
wxSoundFormatBase *old_frmt;
if (!m_oss_stop)
StopProduction();
old_frmt = m_sndformat->Clone();
if (!old_frmt) {
m_snderror = wxSOUND_MEMERROR;
return FALSE;
}
if (evt == wxSOUND_OUTPUT)
m_fd = open(m_devname.mb_str(), O_WRONLY);
else if (evt == wxSOUND_INPUT)
m_fd = open(m_devname.mb_str(), O_RDONLY);
if (m_fd == -1) {
m_snderror = wxSOUND_INVDEV;
return FALSE;
}
SetSoundFormat(*old_frmt);
delete old_frmt;
int trig;
if (evt == wxSOUND_OUTPUT) {
#ifdef __WXGTK__
m_tag = gdk_input_add(m_fd, GDK_INPUT_WRITE, _wxSound_OSS_CBack, (gpointer)this);
#endif
trig = PCM_ENABLE_OUTPUT;
} else {
#ifdef __WXGTK__
m_tag = gdk_input_add(m_fd, GDK_INPUT_READ, _wxSound_OSS_CBack, (gpointer)this);
#endif
trig = PCM_ENABLE_INPUT;
}
ioctl(m_fd, SNDCTL_DSP_SETTRIGGER, &trig);
m_oss_stop = FALSE;
m_q_filled = FALSE;
return TRUE;
}
bool wxSoundStreamOSS::StopProduction()
{
if (m_oss_stop)
return FALSE;
#ifdef __WXGTK__
gdk_input_remove(m_tag);
#endif
close(m_fd);
m_oss_stop = TRUE;
m_q_filled = TRUE;
return TRUE;
}
bool wxSoundStreamOSS::QueueFilled() const
{
return m_q_filled;
}
//
// Detect the closest format (The best).
//
void wxSoundStreamOSS::DetectBest(wxSoundFormatPcm *pcm)
{
#define MASK_16BITS (AFMT_S16_LE | AFMT_S16_BE | AFMT_U16_LE | AFMT_U16_BE)
int fmt_mask;
wxSoundFormatPcm best_pcm;
// We change neither the number of channels nor the sample rate
best_pcm.SetSampleRate(pcm->GetSampleRate());
best_pcm.SetChannels(pcm->GetChannels());
// Get the supported format by the sound card
ioctl(m_fd, SNDCTL_DSP_GETFMTS, &fmt_mask);
// It supports 16 bits
if (pcm->GetBPS() == 16 && ((fmt_mask & MASK_16BITS) != 0))
best_pcm.SetBPS(16);
// It supports big endianness
if (pcm->GetOrder() == wxBIG_ENDIAN && ((fmt_mask & (AFMT_S16_BE | AFMT_U16_BE)) != 0))
best_pcm.SetOrder(wxBIG_ENDIAN);
// It supports little endianness
if (pcm->GetOrder() == wxLITTLE_ENDIAN && ((fmt_mask & (AFMT_S16_LE | AFMT_U16_LE)) != 0))
best_pcm.SetOrder(wxLITTLE_ENDIAN);
// It supports signed samples
if (pcm->Signed() && ((fmt_mask & (AFMT_S16_LE | AFMT_S16_BE | AFMT_S8)) != 0))
best_pcm.Signed(TRUE);
// It supports unsigned samples
if (!pcm->Signed() && ((fmt_mask & (AFMT_U16_LE | AFMT_U16_BE | AFMT_U8)) != 0))
best_pcm.Signed(FALSE);
// Finally recopy the new format
*pcm = best_pcm;
}

View File

@@ -1,53 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndoss.h
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifndef _WX_SNDOSS_H
#define _WX_SNDOSS_H
#ifdef __GNUG__
#pragma interface "sndoss.h"
#endif
#include <wx/string.h>
#include "sndbase.h"
#include "sndpcm.h"
//
// OSS output class
//
class wxSoundStreamOSS : public wxSoundStream {
public:
wxSoundStreamOSS(const wxString& dev_name = _T("/dev/dsp"));
~wxSoundStreamOSS();
wxSoundStream& Read(void *buffer, wxUint32 len);
wxSoundStream& Write(const void *buffer, wxUint32 len);
wxUint32 GetBestSize() const;
bool SetSoundFormat(const wxSoundFormatBase& format);
bool StartProduction(int evt);
bool StopProduction();
bool QueueFilled() const;
// You should not call this.
void WakeUpEvt(int evt);
protected:
int m_fd;
wxUint32 m_bufsize;
int m_tag;
bool m_oss_stop, m_q_filled;
wxString m_devname;
private:
bool SetupFormat(wxSoundFormatPcm *pcm);
void DetectBest(wxSoundFormatPcm *pcm);
};
#endif

View File

@@ -1,89 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndpcm.cpp
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "sndpcm.cpp"
#endif
#include <wx/wxprec.h>
#include "sndbase.h"
#include "sndpcm.h"
wxSoundFormatPcm::wxSoundFormatPcm(wxUint32 srate, wxUint8 bps,
wxUint16 nchannels, bool sign,
int order)
: m_srate(srate), m_bps(bps), m_nchan(nchannels), m_order(order),
m_signed(sign)
{
}
wxSoundFormatPcm::~wxSoundFormatPcm()
{
}
void wxSoundFormatPcm::SetSampleRate(wxUint32 srate)
{
m_srate = srate;
}
void wxSoundFormatPcm::SetBPS(wxUint8 bps)
{
m_bps = bps;
}
void wxSoundFormatPcm::SetChannels(wxUint16 nchannels)
{
m_nchan = nchannels;
}
void wxSoundFormatPcm::SetOrder(int order)
{
m_order = order;
}
void wxSoundFormatPcm::Signed(bool sign)
{
m_signed = sign;
}
wxSoundFormatBase *wxSoundFormatPcm::Clone() const
{
wxSoundFormatPcm *new_pcm;
new_pcm = new wxSoundFormatPcm();
new_pcm->m_srate = m_srate;
new_pcm->m_bps = m_bps;
new_pcm->m_nchan = m_nchan;
new_pcm->m_order = m_order;
new_pcm->m_signed= m_signed;
return new_pcm;
}
wxUint32 wxSoundFormatPcm::GetTimeFromBytes(wxUint32 bytes) const
{
return (bytes / (m_srate * (m_bps / 8) * m_nchan));
}
wxUint32 wxSoundFormatPcm::GetBytesFromTime(wxUint32 time) const
{
return (time * (m_srate * (m_bps / 8) * m_nchan));
}
bool wxSoundFormatPcm::operator!=(const wxSoundFormatBase& format) const
{
wxSoundFormatPcm *format2 = (wxSoundFormatPcm *)&format;
if (format.GetType() != wxSOUND_PCM)
return TRUE;
return ( (m_srate != format2->m_srate) ||
(m_bps != format2->m_bps) ||
(m_nchan != format2->m_nchan) ||
(m_order != format2->m_order) ||
(m_signed != format2->m_signed) );
}

View File

@@ -1,57 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndpcm.h
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifndef _WX_SNDPCM_H
#define _WX_SNDPCM_H
#ifdef __GNUG__
#pragma interface "sndpcm.h"
#endif
#include <wx/defs.h>
#include "sndbase.h"
//
// PCM specification class
//
class wxSoundFormatPcm : public wxSoundFormatBase {
public:
wxSoundFormatPcm(wxUint32 srate = 22500, wxUint8 bps = 8,
wxUint16 channels = 2, bool sign = TRUE,
int order = wxLITTLE_ENDIAN);
~wxSoundFormatPcm();
void SetSampleRate(wxUint32 srate);
void SetBPS(wxUint8 bps);
void SetChannels(wxUint16 nchannels);
void SetOrder(int order);
void Signed(bool sign);
wxUint32 GetSampleRate() const { return m_srate; }
wxUint8 GetBPS() const { return m_bps; }
wxUint16 GetChannels() const { return m_nchan; }
int GetOrder() const { return m_order; }
bool Signed() const { return m_signed; }
wxSoundFormatType GetType() const { return wxSOUND_PCM; }
wxSoundFormatBase *Clone() const;
wxUint32 GetTimeFromBytes(wxUint32 bytes) const;
wxUint32 GetBytesFromTime(wxUint32 time) const;
bool operator!=(const wxSoundFormatBase& frmt2) const;
protected:
wxUint32 m_srate;
wxUint8 m_bps;
wxUint16 m_nchan;
int m_order;
bool m_signed;
};
#endif

View File

@@ -1,180 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndulaw.cpp
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "sndulaw.cpp"
#endif
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#endif
#include "sndbase.h"
#include "sndfile.h"
#include "sndpcm.h"
#include "sndulaw.h"
#include "g72x.h"
// --------------------------------------------------------------------------
// wxSoundFormatUlaw
// --------------------------------------------------------------------------
wxSoundFormatUlaw::wxSoundFormatUlaw()
: m_srate(22050), m_channels(1)
{
}
wxSoundFormatUlaw::~wxSoundFormatUlaw()
{
}
void wxSoundFormatUlaw::SetSampleRate(wxUint32 srate)
{
m_srate = srate;
}
wxUint32 wxSoundFormatUlaw::GetSampleRate() const
{
return m_srate;
}
wxUint8 wxSoundFormatUlaw::GetChannels() const
{
return m_channels;
}
void wxSoundFormatUlaw::SetChannels(wxUint8 nchannels)
{
m_channels = nchannels;
}
wxSoundFormatBase *wxSoundFormatUlaw::Clone() const
{
wxSoundFormatUlaw *ulaw = new wxSoundFormatUlaw();
ulaw->m_srate = m_srate;
ulaw->m_channels = m_channels;
return ulaw;
}
wxUint32 wxSoundFormatUlaw::GetTimeFromBytes(wxUint32 bytes) const
{
return (bytes / m_srate);
}
wxUint32 wxSoundFormatUlaw::GetBytesFromTime(wxUint32 time) const
{
return time * m_srate;
}
bool wxSoundFormatUlaw::operator !=(const wxSoundFormatBase& frmt2) const
{
wxSoundFormatUlaw *ulaw = (wxSoundFormatUlaw *)&frmt2;
if (frmt2.GetType() != wxSOUND_ULAW)
return TRUE;
return (ulaw->m_srate != m_srate);
}
// --------------------------------------------------------------------------
// wxSoundStreamUlaw
// --------------------------------------------------------------------------
wxSoundStreamUlaw::wxSoundStreamUlaw(wxSoundStream& sndio)
: wxSoundStreamCodec(sndio)
{
// PCM converter
m_router = new wxSoundRouterStream(sndio);
}
wxSoundStreamUlaw::~wxSoundStreamUlaw()
{
delete m_router;
}
wxSoundStream& wxSoundStreamUlaw::Read(void *buffer, wxUint32 len)
{
wxUint16 *old_linear;
register wxUint16 *linear_buffer;
register const wxUint8 *ulaw_buffer;
register wxUint32 countdown;
old_linear = linear_buffer = new wxUint16[len*2];
ulaw_buffer = (const wxUint8 *)buffer;
m_router->Read(linear_buffer, len * 2);
m_lastcount = countdown = m_router->GetLastAccess() / 2;
m_snderror = m_router->GetError();
if (m_snderror != wxSOUND_NOERROR)
return *this;
while (countdown > 0) {
*linear_buffer++ = ulaw2linear(*ulaw_buffer++);
countdown--;
}
delete[] old_linear;
return *m_router;
}
wxSoundStream& wxSoundStreamUlaw::Write(const void *buffer, wxUint32 len)
{
wxUint16 *old_linear;
register wxUint16 *linear_buffer;
register const wxUint8 *ulaw_buffer;
register wxUint32 countdown = len;
old_linear = linear_buffer = new wxUint16[len*2];
ulaw_buffer = (const wxUint8 *)buffer;
while (countdown > 0) {
*linear_buffer++ = ulaw2linear(*ulaw_buffer++);
countdown--;
}
m_router->Write(old_linear, len * 2);
delete[] old_linear;
return *m_router;
}
wxUint32 wxSoundStreamUlaw::GetBestSize() const
{
return m_sndio->GetBestSize() / 2;
}
bool wxSoundStreamUlaw::SetSoundFormat(const wxSoundFormatBase& format)
{
if (format.GetType() != wxSOUND_ULAW) {
m_snderror = wxSOUND_INVFRMT;
return FALSE;
}
// As the codec only support 16 bits, Mono we must use a wxSoundRouter to filter the data and
// to translate them to a format supported by the sound card.
wxSoundFormatPcm pcm;
wxSoundFormatUlaw *ulaw;
wxSoundStreamCodec::SetSoundFormat(format);
ulaw = (wxSoundFormatUlaw *)m_sndformat;
pcm.SetSampleRate(ulaw->GetSampleRate());
pcm.SetBPS(16);
pcm.SetChannels(ulaw->GetChannels());
pcm.Signed(TRUE);
pcm.SetOrder(wxBYTE_ORDER);
m_router->SetSoundFormat(pcm);
return TRUE;
}

View File

@@ -1,68 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndulaw.h
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifndef _WX_SNDULAW_H
#define _WX_SNDULAW_H
#ifdef __GNUG__
#pragma interface "sndulaw.h"
#endif
#include "wx/defs.h"
#include "sndcodec.h"
#include "sndbase.h"
//
// ULAW format
//
class WXDLLEXPORT wxSoundFormatUlaw: public wxSoundFormatBase {
public:
wxSoundFormatUlaw();
~wxSoundFormatUlaw();
void SetSampleRate(wxUint32 srate);
wxUint32 GetSampleRate() const;
void SetChannels(wxUint8 channels);
wxUint8 GetChannels() const;
wxSoundFormatType GetType() const { return wxSOUND_ULAW; }
wxSoundFormatBase *Clone() const;
wxUint32 GetTimeFromBytes(wxUint32 bytes) const;
wxUint32 GetBytesFromTime(wxUint32 time) const;
bool operator !=(const wxSoundFormatBase& frmt2) const;
protected:
wxUint32 m_srate;
wxUint8 m_channels;
};
//
// ULAW converter class
//
class WXDLLEXPORT wxSoundRouterStream;
class WXDLLEXPORT wxSoundStreamUlaw: public wxSoundStreamCodec {
public:
wxSoundStreamUlaw(wxSoundStream& sndio);
~wxSoundStreamUlaw();
wxSoundStream& Read(void *buffer, wxUint32 len);
wxSoundStream& Write(const void *buffer, wxUint32 len);
bool SetSoundFormat(const wxSoundFormatBase& format);
wxUint32 GetBestSize() const;
protected:
wxSoundRouterStream *m_router;
};
#endif

View File

@@ -1,355 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndwav.cpp
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "sndwav.cpp"
#endif
#include <wx/wxprec.h>
#include <wx/stream.h>
#include <wx/datstrm.h>
#include <wx/filefn.h>
#include <wx/mstream.h>
#include "sndbase.h"
#include "sndcodec.h"
#include "sndfile.h"
#include "sndpcm.h"
#include "sndg72x.h"
#include "sndwav.h"
#define BUILD_SIGNATURE(a,b,c,d) (((wxUint32)a) | (((wxUint32)b) << 8) | (((wxUint32)c) << 16) | (((wxUint32)d) << 24))
#define RIFF_SIGNATURE BUILD_SIGNATURE('R','I','F','F')
#define WAVE_SIGNATURE BUILD_SIGNATURE('W','A','V','E')
#define FMT_SIGNATURE BUILD_SIGNATURE('f','m','t',' ')
#define DATA_SIGNATURE BUILD_SIGNATURE('d','a','t','a')
#define HEADER_SIZE 4+4 + 4+4+16 + 4+4
// 4+4 => NAME + LEN
// 16 => fmt size
wxSoundWave::wxSoundWave(wxInputStream& stream, wxSoundStream& io_sound)
: wxSoundFileStream(stream, io_sound)
{
m_base_offset = wxInvalidOffset;
}
wxSoundWave::wxSoundWave(wxOutputStream& stream, wxSoundStream& io_sound)
: wxSoundFileStream(stream, io_sound)
{
m_base_offset = wxInvalidOffset;
}
wxSoundWave::~wxSoundWave()
{
}
wxString wxSoundWave::GetCodecName() const
{
return wxString(wxT("wxSoundWave codec"));
}
#define FAIL_WITH(condition, err) if (condition) { m_snderror = err; return FALSE; }
bool wxSoundWave::CanRead()
{
wxUint32 len, signature1, signature2;
m_snderror = wxSOUND_NOERROR;
// Test the main signatures:
// "RIFF"
FAIL_WITH(m_input->Read(&signature1, 4).LastRead() != 4, wxSOUND_INVSTRM);
if (wxUINT32_SWAP_ON_BE(signature1) != RIFF_SIGNATURE) {
m_input->Ungetch(&signature1, 4);
return FALSE;
}
// Pass the global length
m_input->Read(&len, 4);
FAIL_WITH(m_input->LastRead() != 4, wxSOUND_INVSTRM);
// Get the second signature
FAIL_WITH(m_input->Read(&signature2, 4).LastRead() != 4, wxSOUND_INVSTRM);
// Ungetch all
m_input->Ungetch(&signature2, 4);
m_input->Ungetch(&len, 4);
m_input->Ungetch(&signature1, 4);
// Test the second signature
if (wxUINT32_SWAP_ON_BE(signature2) != WAVE_SIGNATURE)
return FALSE;
return TRUE;
}
bool wxSoundWave::HandleOutputPCM(wxDataInputStream& data, wxUint16 channels,
wxUint32 sample_fq, wxUint32 byte_p_sec,
wxUint16 byte_p_spl, wxUint16 bits_p_spl)
{
wxSoundFormatPcm sndformat;
sndformat.SetSampleRate(sample_fq);
sndformat.SetBPS(bits_p_spl);
sndformat.SetChannels(channels);
sndformat.Signed(TRUE);
sndformat.SetOrder(wxLITTLE_ENDIAN);
if (!SetSoundFormat(sndformat))
return FALSE;
return TRUE;
}
bool wxSoundWave::HandleOutputG721(wxDataInputStream& data, wxUint16 channels,
wxUint32 sample_fq, wxUint32 byte_p_sec,
wxUint16 byte_p_spl, wxUint16 bits_p_spl)
{
wxSoundFormatG72X sndformat;
sndformat.SetSampleRate(sample_fq);
sndformat.SetG72XType(wxSOUND_G721);
if (!SetSoundFormat(sndformat))
return FALSE;
return TRUE;
}
bool wxSoundWave::PrepareToPlay()
{
wxUint32 signature, len;
bool end_headers;
if (!m_input) {
m_snderror = wxSOUND_INVSTRM;
return FALSE;
}
wxDataInputStream data(*m_input);
data.BigEndianOrdered(FALSE);
// Get the first signature
FAIL_WITH(m_input->Read(&signature, 4).LastRead() != 4, wxSOUND_INVSTRM);
FAIL_WITH(wxUINT32_SWAP_ON_BE(signature) != RIFF_SIGNATURE, wxSOUND_INVSTRM);
// "RIFF"
len = data.Read32();
FAIL_WITH(m_input->LastRead() != 4, wxSOUND_INVSTRM);
// dummy len
// Get the second signature
FAIL_WITH(m_input->Read(&signature, 4).LastRead() != 4, wxSOUND_INVSTRM);
FAIL_WITH(wxUINT32_SWAP_ON_BE(signature) != WAVE_SIGNATURE, wxSOUND_INVSTRM);
// "WAVE"
end_headers = FALSE;
// Chunk loop
while (!end_headers) {
FAIL_WITH(m_input->Read(&signature, 4).LastRead() != 4, wxSOUND_INVSTRM);
len = data.Read32();
FAIL_WITH(m_input->LastRead() != 4, wxSOUND_INVSTRM);
switch (wxUINT32_SWAP_ON_BE(signature)) {
case FMT_SIGNATURE: { // "fmt "
wxUint16 format, channels, byte_p_spl, bits_p_spl;
wxUint32 sample_fq, byte_p_sec;
// Get the common parameters
data >> format >> channels >> sample_fq
>> byte_p_sec >> byte_p_spl >> bits_p_spl;
switch (format) {
case 0x01: // PCM
if (!HandleOutputPCM(data, channels, sample_fq,
byte_p_sec, byte_p_spl, bits_p_spl))
return FALSE;
break;
case 0x40: // G721
if (!HandleOutputG721(data, channels, sample_fq,
byte_p_sec, byte_p_spl, bits_p_spl))
return FALSE;
break;
default:
m_snderror = wxSOUND_NOCODEC;
return FALSE;
}
break;
}
case DATA_SIGNATURE: // "data"
m_base_offset = m_input->TellI();
end_headers = TRUE;
FinishPreparation(len);
break;
default:
// We pass the chunk
m_input->SeekI(len, wxFromCurrent);
break;
}
}
return TRUE;
}
wxSoundFormatBase *wxSoundWave::HandleInputPCM(wxDataOutputStream& data)
{
wxUint16 format, channels, byte_p_spl, bits_p_spl;
wxUint32 sample_fq, byte_p_sec;
wxSoundFormatPcm *pcm;
pcm = (wxSoundFormatPcm *)(m_sndformat->Clone());
// Write block length
data.Write32(16);
sample_fq = pcm->GetSampleRate();
bits_p_spl = pcm->GetBPS();
channels = pcm->GetChannels();
byte_p_spl = pcm->GetBPS() / 8;
byte_p_sec = pcm->GetBytesFromTime(1);
format = 0x01;
pcm->Signed(TRUE);
pcm->SetOrder(wxLITTLE_ENDIAN);
data << format << channels << sample_fq
<< byte_p_sec << byte_p_spl << bits_p_spl;
return pcm;
}
wxSoundFormatBase *wxSoundWave::HandleInputG72X(wxDataOutputStream& data)
{
wxUint16 format, channels, byte_p_spl, bits_p_spl;
wxUint32 sample_fq, byte_p_sec;
wxSoundFormatG72X *g72x;
// Write block length
data.Write32(16);
g72x = (wxSoundFormatG72X *)(m_sndformat->Clone());
if (g72x->GetG72XType() != wxSOUND_G721) {
delete g72x;
return NULL;
}
sample_fq = g72x->GetSampleRate();
bits_p_spl = 4;
channels = 1;
byte_p_spl = 0;
byte_p_sec = g72x->GetBytesFromTime(1);
format = 0x40;
data << format << channels << sample_fq
<< byte_p_sec << byte_p_spl << bits_p_spl;
return g72x;
}
bool wxSoundWave::PrepareToRecord(wxUint32 time)
{
#define WRITE_SIGNATURE(s,sig) \
signature = sig; \
signature = wxUINT32_SWAP_ON_BE(signature); \
FAIL_WITH(s->Write(&signature, 4).LastWrite() != 4, wxSOUND_INVSTRM);
wxUint32 signature;
wxMemoryOutputStream fmt_data;
if (!m_output) {
m_snderror = wxSOUND_INVSTRM;
return FALSE;
}
wxDataOutputStream data(*m_output);
wxDataOutputStream fmt_d_data(fmt_data);
data.BigEndianOrdered(FALSE);
fmt_d_data.BigEndianOrdered(FALSE);
WRITE_SIGNATURE(m_output, RIFF_SIGNATURE);
FAIL_WITH(m_output->LastWrite() != 4, wxSOUND_INVSTRM);
WRITE_SIGNATURE((&fmt_data), WAVE_SIGNATURE);
{
wxSoundFormatBase *frmt;
WRITE_SIGNATURE((&fmt_data), FMT_SIGNATURE);
switch (m_sndformat->GetType()) {
case wxSOUND_PCM:
frmt = HandleInputPCM(fmt_d_data);
break;
case wxSOUND_G72X:
frmt = HandleInputG72X(fmt_d_data);
break;
default:
m_snderror = wxSOUND_NOCODEC;
return FALSE;
}
FAIL_WITH(!frmt, wxSOUND_NOCODEC);
if (!SetSoundFormat(*frmt)) {
delete frmt;
return FALSE;
}
delete frmt;
}
data << (fmt_data.GetSize() + m_sndformat->GetBytesFromTime(time));
// We, finally, copy the header block to the output stream
{
char *out_buf;
out_buf = new char[fmt_data.GetSize()];
fmt_data.CopyTo(out_buf, fmt_data.GetSize());
m_output->Write(out_buf, fmt_data.GetSize());
delete[] out_buf;
}
WRITE_SIGNATURE(m_output, DATA_SIGNATURE);
data.Write32(m_sndformat->GetBytesFromTime(time));
return TRUE;
}
bool wxSoundWave::FinishRecording()
{
if (m_output->SeekO(0, wxFromStart) == wxInvalidOffset)
// We can't but there is no error.
return TRUE;
if (m_bytes_left == 0)
return TRUE;
// TODO: Update headers when we stop before the specified time (if possible)
return TRUE;
}
bool wxSoundWave::RepositionStream(wxUint32 position)
{
if (m_base_offset == wxInvalidOffset)
return FALSE;
m_input->SeekI(m_base_offset, wxFromStart);
return TRUE;
}
wxUint32 wxSoundWave::GetData(void *buffer, wxUint32 len)
{
return m_input->Read(buffer, len).LastRead();
}
wxUint32 wxSoundWave::PutData(const void *buffer, wxUint32 len)
{
return m_output->Write(buffer, len).LastWrite();
}

View File

@@ -1,57 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndwav.h
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifndef _WX_SNDWAV_H
#define _WX_SNDWAV_H
#ifdef __GNUG__
#pragma interface "sndwav.h"
#endif
#include <wx/defs.h>
#include <wx/stream.h>
#include <wx/datstrm.h>
#include "sndbase.h"
#include "sndcodec.h"
#include "sndfile.h"
//
// WAVE codec
//
class wxSoundWave: public wxSoundFileStream {
public:
wxSoundWave(wxInputStream& stream, wxSoundStream& io_sound);
wxSoundWave(wxOutputStream& stream, wxSoundStream& io_sound);
~wxSoundWave();
bool CanRead();
wxString GetCodecName() const;
protected:
bool PrepareToPlay();
bool PrepareToRecord(wxUint32 time);
bool FinishRecording();
bool RepositionStream(wxUint32 position);
wxUint32 GetData(void *buffer, wxUint32 len);
wxUint32 PutData(const void *buffer, wxUint32 len);
bool HandleOutputPCM(wxDataInputStream& data, wxUint16 channels,
wxUint32 sample_fq, wxUint32 byte_p_sec,
wxUint16 byte_p_spl, wxUint16 bits_p_spl);
bool HandleOutputG721(wxDataInputStream& data, wxUint16 channels,
wxUint32 sample_fq, wxUint32 byte_p_sec,
wxUint16 byte_p_spl, wxUint16 bits_p_spl);
wxSoundFormatBase *HandleInputPCM(wxDataOutputStream& data);
wxSoundFormatBase *HandleInputG72X(wxDataOutputStream& data);
protected:
off_t m_base_offset;
};
#endif

View File

@@ -1,751 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndwin.cpp
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999, 2000
// CVSID: $Id$
// --------------------------------------------------------------------------
#include <wx/wxprec.h>
#include <wx/app.h>
#include <wx/module.h>
#include <wx/msw/private.h>
#include <string.h>
#include "sndbase.h"
#include "sndwin.h"
#include "sndpcm.h"
#include <windows.h>
#include <mmsystem.h>
typedef struct _wxSoundInternal wxSoundInternal;
typedef struct _wxSoundInfoHeader wxSoundInfoHeader;
extern const wxChar *wxCanvasClassName;
wxList *wxSoundHandleList = NULL;
static inline wxSoundStreamWin *wxFindSoundFromHandle(WXHWND hWnd)
{
wxNode *node = wxSoundHandleList->Find((long)hWnd);
if (!node)
return NULL;
return (wxSoundStreamWin *)node->Data();
}
struct _wxSoundInternal {
HWND m_sndWin;
HWAVEIN m_devin;
HWAVEOUT m_devout;
bool m_output_enabled, m_input_enabled;
};
struct _wxSoundInfoHeader {
HGLOBAL m_h_header, m_h_data;
char *m_data;
WAVEHDR *m_header;
int m_mode;
bool m_playing, m_recording;
wxUint32 m_position, m_size;
wxSoundStreamWin *m_driver;
};
#define WXSOUND_MAX_QUEUE 10
wxSoundStreamWin::wxSoundStreamWin()
{
wxSoundFormatPcm pcm;
m_production_started = FALSE;
m_internal = new wxSoundInternal;
if (!m_internal) {
m_snderror = wxSOUND_MEMERROR;
m_internal = NULL;
return;
}
m_snderror = wxSOUND_NOERROR;
// Setup defaults
CreateSndWindow();
SetSoundFormat(pcm);
m_internal->m_input_enabled = FALSE;
m_internal->m_output_enabled = FALSE;
m_waiting_for = FALSE;
if (!OpenDevice(wxSOUND_OUTPUT))
return;
CloseDevice();
}
wxSoundStreamWin::~wxSoundStreamWin()
{
if (m_internal) {
if (m_production_started)
StopProduction();
DestroySndWindow();
delete m_internal;
}
}
// -----------------------------------------------------------------------
// _wxSoundHandlerWndProc: Window callback to handle buffer completion
// -----------------------------------------------------------------------
LRESULT APIENTRY _EXPORT _wxSoundHandlerWndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
wxSoundStreamWin *sndwin;
sndwin = wxFindSoundFromHandle((WXHWND)hWnd);
if (!sndwin)
return (LRESULT)0;
switch (message) {
case MM_WOM_DONE:
sndwin->NotifyDoneBuffer(wParam, wxSOUND_OUTPUT);
break;
case MM_WIM_DATA:
sndwin->NotifyDoneBuffer(wParam, wxSOUND_INPUT);
break;
default:
break;
}
return (LRESULT)0;
}
// -----------------------------------------------------------------------
// CreateSndWindow() creates an hidden window which will receive the sound
// events
// -----------------------------------------------------------------------
void wxSoundStreamWin::CreateSndWindow()
{
FARPROC proc = MakeProcInstance((FARPROC)_wxSoundHandlerWndProc,
wxGetInstance());
int error;
m_internal->m_sndWin = ::CreateWindow(wxCanvasClassName, NULL, 0,
0, 0, 0, 0, NULL, (HMENU) NULL,
wxGetInstance(), NULL);
error = GetLastError();
::SetWindowLong(m_internal->m_sndWin, GWL_WNDPROC, (LONG)proc);
// Add this window to the sound handle list so we'll be able to redecode
// the "magic" number.
wxSoundHandleList->Append((long)m_internal->m_sndWin, (wxObject *)this);
}
// -----------------------------------------------------------------------
// DestroySndWindow() destroys the hidden window
// -----------------------------------------------------------------------
void wxSoundStreamWin::DestroySndWindow()
{
if (m_internal->m_sndWin) {
::DestroyWindow(m_internal->m_sndWin);
wxSoundHandleList->DeleteObject((wxObject *)this);
}
}
// -------------------------------------------------------------------------
// OpenDevice(int mode) initializes the windows driver for a "mode"
// operation. mode is a bit mask: if the bit "wxSOUND_OUTPUT" is set,
// the driver is opened for output operation, and if the bit "wxSOUND_INPUT"
// is set, then the driver is opened for input operation. The two modes
// aren't exclusive.
// The initialization parameters (sample rate, ...) are taken from the
// m_sndformat object.
// At the end, OpenDevice() calls AllocHeaders() to initialize the Sound IO
// queue.
// -------------------------------------------------------------------------
bool wxSoundStreamWin::OpenDevice(int mode)
{
wxSoundFormatPcm *pcm;
WAVEFORMATEX wformat;
if (!m_sndformat) {
m_snderror = wxSOUND_INVFRMT;
return FALSE;
}
pcm = (wxSoundFormatPcm *)m_sndformat;
wformat.wFormatTag = WAVE_FORMAT_PCM;
wformat.nChannels = pcm->GetChannels();
wformat.nBlockAlign = wformat.nChannels * pcm->GetBPS() / 8;
wformat.nSamplesPerSec = pcm->GetSampleRate();
wformat.nAvgBytesPerSec = wformat.nSamplesPerSec * wformat.nBlockAlign;
wformat.wBitsPerSample = pcm->GetBPS();
wformat.cbSize = 0;
// -----------------------------------
// Open the driver for Output operation
// -----------------------------------
if (mode & wxSOUND_OUTPUT) {
MMRESULT result;
result = waveOutOpen(&m_internal->m_devout,
WAVE_MAPPER, &wformat,
(DWORD)m_internal->m_sndWin, 0,
CALLBACK_WINDOW);
if (result != MMSYSERR_NOERROR) {
m_snderror = wxSOUND_INVDEV;
return FALSE;
}
m_output_frag_out = WXSOUND_MAX_QUEUE-1;
m_current_frag_out = 0;
m_internal->m_output_enabled = TRUE;
}
// -----------------------------------
// Open the driver for Input operation
// -----------------------------------
if (mode & wxSOUND_INPUT) {
MMRESULT result;
result = waveInOpen(&m_internal->m_devin,
WAVE_MAPPER, &wformat,
(DWORD)m_internal->m_sndWin, 0,
CALLBACK_WINDOW);
if (result != MMSYSERR_NOERROR) {
m_snderror = wxSOUND_INVDEV;
return FALSE;
}
m_current_frag_in = WXSOUND_MAX_QUEUE-1;
m_input_frag_in = 0;
m_internal->m_input_enabled = TRUE;
}
if (mode & wxSOUND_OUTPUT) {
if (!AllocHeaders(wxSOUND_OUTPUT)) {
CloseDevice();
return FALSE;
}
}
if (mode & wxSOUND_INPUT) {
if (!AllocHeaders(wxSOUND_INPUT)) {
CloseDevice();
return FALSE;
}
}
return TRUE;
}
// -------------------------------------------------------------------------
// CloseDevice() closes the driver handles and frees memory allocated for
// IO queues.
// -------------------------------------------------------------------------
void wxSoundStreamWin::CloseDevice()
{
if (m_internal->m_output_enabled) {
FreeHeaders(wxSOUND_OUTPUT);
m_internal->m_output_enabled = FALSE;
waveOutClose(m_internal->m_devout);
}
if (m_internal->m_input_enabled) {
FreeHeaders(wxSOUND_INPUT);
m_internal->m_input_enabled = FALSE;
waveInClose(m_internal->m_devin);
}
}
// -------------------------------------------------------------------------
// AllocHeader(int mode)
//
// mode has the same mean as in OpenDevice() except that here the two flags
// must be exclusive.
// AllocHeader() initializes an element of an operation (this can be input
// or output). It means it allocates the sound header's memory block
// and "prepares" it (It is needed by Windows). At the same time, it sets
// private datas so we can the header's owner (See callback).
//
// It returns the new allocated block or NULL.
// -------------------------------------------------------------------------
wxSoundInfoHeader *wxSoundStreamWin::AllocHeader(int mode)
{
wxSoundInfoHeader *info;
WAVEHDR *header;
// Some memory allocation
info = new wxSoundInfoHeader;
info->m_h_data = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, GetBestSize());
info->m_h_header = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, sizeof(WAVEHDR));
if (!info->m_h_data || !info->m_h_header) {
delete info;
m_snderror = wxSOUND_MEMERR;
return NULL;
}
// Get the two pointers from the system
info->m_data = (char *)GlobalLock(info->m_h_data);
info->m_header = (WAVEHDR *)GlobalLock(info->m_h_header);
// Set the header's mode
info->m_mode = mode;
// Set the parent of the header
info->m_driver = this;
// Clean it up
ClearHeader(info);
header = info->m_header;
// Initialize Windows variables
header->lpData = info->m_data;
header->dwBufferLength = GetBestSize();
header->dwUser = (DWORD)info;
header->dwFlags = WHDR_DONE;
// "Prepare" the header
if (mode == wxSOUND_INPUT) {
MMRESULT result;
result = waveInPrepareHeader(m_internal->m_devin, header,
sizeof(WAVEHDR));
if (result != MMSYSERR_NOERROR) {
// If something goes wrong, free everything.
GlobalUnlock(info->m_data);
GlobalUnlock(info->m_header);
GlobalFree(info->m_h_data);
GlobalFree(info->m_h_header);
delete info;
m_snderror = wxSOUND_IOERROR;
return NULL;
}
} else if (mode == wxSOUND_OUTPUT) {
MMRESULT result;
result = waveOutPrepareHeader(m_internal->m_devout, header,
sizeof(WAVEHDR));
if (result != MMSYSERR_NOERROR) {
// If something goes wrong, free everything.
GlobalUnlock(info->m_data);
GlobalUnlock(info->m_header);
GlobalFree(info->m_h_data);
GlobalFree(info->m_h_header);
delete info;
m_snderror = wxSOUND_IOERROR;
return NULL;
}
}
return info;
}
// -------------------------------------------------------------------------
// AllocHeaders(int mode)
//
// "mode" has the same mean as for OpenDevice() except that the two flags must
// be exclusive.
// AllocHeaders() allocates WXSOUND_MAX_QUEUE (= 128) blocks for an operation
// queue. It uses AllocHeader() for each element.
//
// Once it has allocated all blocks, it returns TRUE and if an error occured
// it returns FALSE.
// -------------------------------------------------------------------------
bool wxSoundStreamWin::AllocHeaders(int mode)
{
int i;
wxSoundInfoHeader **headers;
if (mode == wxSOUND_OUTPUT)
headers = m_headers_play = new wxSoundInfoHeader *[WXSOUND_MAX_QUEUE];
else
headers = m_headers_rec = new wxSoundInfoHeader *[WXSOUND_MAX_QUEUE];
memset(headers, 0, WXSOUND_MAX_QUEUE*sizeof(wxSoundInfoHeader *));
for (i=0;i<WXSOUND_MAX_QUEUE;i++) {
headers[i] = AllocHeader(mode);
if (!headers[i]) {
FreeHeaders(mode);
return FALSE;
}
}
return TRUE;
}
// -------------------------------------------------------------------------
// FreeHeader(int mode)
//
// "mode" has the same mean as for OpenDevice() except that the two flags must
// be exclusive.
// FreeHeader() frees a memory block and "unprepares" it.
// -------------------------------------------------------------------------
void wxSoundStreamWin::FreeHeader(wxSoundInfoHeader *header, int mode)
{
if (mode == wxSOUND_OUTPUT)
waveOutUnprepareHeader(m_internal->m_devout, header->m_header, sizeof(WAVEHDR));
else
waveInUnprepareHeader(m_internal->m_devin, header->m_header, sizeof(WAVEHDR));
GlobalUnlock(header->m_data);
GlobalUnlock(header->m_header);
GlobalFree(header->m_h_header);
GlobalFree(header->m_h_data);
delete header;
}
// -------------------------------------------------------------------------
// FreeHeaders(int mode)
//
// "mode" has the same mean as for OpenDevice() except that the two flags must
// be exclusive.
// FreeHeaders() frees all an operation queue once it has checked that
// all buffers have been terminated.
// -------------------------------------------------------------------------
void wxSoundStreamWin::FreeHeaders(int mode)
{
int i;
wxSoundInfoHeader ***headers;
if (mode == wxSOUND_OUTPUT)
headers = &m_headers_play;
else
headers = &m_headers_rec;
for (i=0;i<WXSOUND_MAX_QUEUE;i++) {
if ((*headers)[i]) {
// We wait for the end of the buffer
WaitFor((*headers)[i]);
// Then, we free the header
FreeHeader((*headers)[i], mode);
}
}
delete[] (*headers);
(*headers) = NULL;
}
// -------------------------------------------------------------------------
// WaitFor(wxSoundInfoHeader *info)
//
// "info" is one element of an IO queue
// WaitFor() checks whether the specified block has been terminated.
// If it hasn't been terminated, it waits for its termination.
//
// NB: if it's a partially filled buffer it adds it to the Windows queue
// -------------------------------------------------------------------------
void wxSoundStreamWin::WaitFor(wxSoundInfoHeader *info)
{
// If the buffer is finished, we return immediately
if (!info->m_playing) {
// We begun filling it: we must send it to the Windows queue
if (info->m_position != 0) {
memset(info->m_data + info->m_position, 0, info->m_size);
AddToQueue(info);
}
}
if (m_waiting_for) {
// PROBLEM //
return;
}
m_waiting_for = TRUE;
// Else, we wait for its termination
while (info->m_playing || info->m_recording)
wxYield();
m_waiting_for = FALSE;
}
// -------------------------------------------------------------------------
// AddToQueue(wxSoundInfoHeader *info)
//
// For "info", see WaitFor()
// AddToQueue() sends the IO queue element to the Windows queue.
//
// Warning: in the current implementation, it partially assume we send the
// element in the right order. This is true in that implementation but if
// you use it elsewhere, be careful: it may shuffle all your sound datas.
// -------------------------------------------------------------------------
bool wxSoundStreamWin::AddToQueue(wxSoundInfoHeader *info)
{
MMRESULT result;
if (info->m_mode == wxSOUND_INPUT) {
// Increment the input fragment pointer
result = waveInAddBuffer(m_internal->m_devin,
info->m_header, sizeof(WAVEHDR));
if (result == MMSYSERR_NOERROR)
info->m_recording = TRUE;
else
return FALSE;
} else if (info->m_mode == wxSOUND_OUTPUT) {
result = waveOutWrite(m_internal->m_devout,
info->m_header, sizeof(WAVEHDR));
if (result == MMSYSERR_NOERROR)
info->m_playing = TRUE;
else
return FALSE;
}
return TRUE;
}
// -------------------------------------------------------------------------
// ClearHeader(wxSoundInfoHeader *info)
//
// ClearHeader() reinitializes the parameters of "info" to their default
// value.
// -------------------------------------------------------------------------
void wxSoundStreamWin::ClearHeader(wxSoundInfoHeader *info)
{
info->m_playing = FALSE;
info->m_recording = FALSE;
info->m_position = 0;
info->m_size = GetBestSize();
}
// -------------------------------------------------------------------------
// wxSoundInfoHeader *NextFragmentOutput()
//
// NextFragmentOutput() looks for a free output block. It will always
// return you a non-NULL pointer but it may waits for an empty buffer a long
// time.
// -------------------------------------------------------------------------
wxSoundInfoHeader *wxSoundStreamWin::NextFragmentOutput()
{
if (m_headers_play[m_current_frag_out]->m_playing) {
m_current_frag_out = (m_current_frag_out + 1) % WXSOUND_MAX_QUEUE;
if (m_headers_play[m_current_frag_out]->m_playing)
WaitFor(m_headers_play[m_current_frag_out]);
}
if (m_current_frag_out == m_output_frag_out)
m_queue_filled = TRUE;
return m_headers_play[m_current_frag_out];
}
// -------------------------------------------------------------------------
// The behaviour of Write is documented in the global documentation.
// -------------------------------------------------------------------------
wxSoundStream& wxSoundStreamWin::Write(const void *buffer, wxUint32 len)
{
m_lastcount = 0;
if (!m_internal->m_output_enabled) {
m_snderror = wxSOUND_NOTSTARTED;
return *this;
}
while (len > 0) {
wxSoundInfoHeader *header;
wxUint32 to_copy;
// Get a new output fragment
header = NextFragmentOutput();
to_copy = (len > header->m_size) ? header->m_size : len;
memcpy(header->m_data + header->m_position, buffer, to_copy);
header->m_position += to_copy;
header->m_size -= to_copy;
buffer = (((const char *)buffer) + to_copy);
len -= to_copy;
m_lastcount += to_copy;
// If the fragment is full, we send it to the Windows queue.
if (header->m_size == 0)
if (!AddToQueue(header)) {
m_snderror = wxSOUND_IOERROR;
return *this;
}
}
return *this;
}
// -------------------------------------------------------------------------
// NextFragmentInput is not functional.
// -------------------------------------------------------------------------
wxSoundInfoHeader *wxSoundStreamWin::NextFragmentInput()
{
wxSoundInfoHeader *header;
// Queue pointer: reader
m_current_frag_in = (m_current_frag_in + 1) % WXSOUND_MAX_QUEUE;
header = m_headers_rec[m_current_frag_in];
// If the current buffer is in recording mode, we must wait for its
// completion.
if (header->m_recording)
WaitFor(header);
// We reached the writer position: the queue is full.
if (m_current_frag_in == m_input_frag_in)
m_queue_filled = TRUE;
return header;
}
// -------------------------------------------------------------------------
// The behaviour of Read is documented in the global documentation.
// -------------------------------------------------------------------------
wxSoundStream& wxSoundStreamWin::Read(void *buffer, wxUint32 len)
{
wxSoundInfoHeader *header;
wxUint32 to_copy;
m_lastcount = 0;
if (!m_internal->m_input_enabled)
return *this;
while (len > 0) {
header = NextFragmentInput();
to_copy = (len > header->m_size) ? header->m_size : len;
memcpy(buffer, header->m_data + header->m_position, to_copy);
header->m_position += to_copy;
header->m_size -= to_copy;
buffer = (((char *)buffer) + to_copy);
len -= to_copy;
m_lastcount += to_copy;
if (header->m_size == 0) {
ClearHeader(header);
if (!AddToQueue(header)) {
m_snderror = wxSOUND_IOERROR;
return *this;
}
}
}
return *this;
}
// -------------------------------------------------------------------------
// NotifyDoneBuffer(wxUint32 dev_handle)
//
// NotifyDoneBuffer() is called by wxSoundHandlerProc each time a sound
// fragment finished. It reinitializes the parameters of the fragment and
// sends an event to the clients.
// -------------------------------------------------------------------------
void wxSoundStreamWin::NotifyDoneBuffer(wxUint32 dev_handle, int flag)
{
wxSoundInfoHeader *info;
if (flag == wxSOUND_OUTPUT) {
if (!m_internal->m_output_enabled)
return;
// Queue pointer: reader
m_output_frag_out = (m_output_frag_out + 1) % WXSOUND_MAX_QUEUE;
info = m_headers_play[m_output_frag_out];
// Clear header to tell the system the buffer is free now
ClearHeader(info);
m_queue_filled = FALSE;
if (!m_waiting_for)
// Try to requeue a new buffer.
OnSoundEvent(wxSOUND_OUTPUT);
} else {
if (!m_internal->m_input_enabled)
return;
// Recording completed
m_headers_rec[m_input_frag_in]->m_recording = FALSE;
// Queue pointer: writer
m_input_frag_in = (m_input_frag_in + 1) % WXSOUND_MAX_QUEUE;
if (!m_waiting_for)
OnSoundEvent(wxSOUND_INPUT);
m_queue_filled = FALSE;
}
}
// -------------------------------------------------------------------------
// SetSoundFormat()
// -------------------------------------------------------------------------
bool wxSoundStreamWin::SetSoundFormat(wxSoundFormatBase& base)
{
// TODO: detect best format
return wxSoundStream::SetSoundFormat(base);
}
// -------------------------------------------------------------------------
// StartProduction()
// -------------------------------------------------------------------------
bool wxSoundStreamWin::StartProduction(int evt)
{
if (!m_internal)
return FALSE;
if ((m_internal->m_output_enabled && (evt & wxSOUND_OUTPUT)) ||
(m_internal->m_input_enabled && (evt & wxSOUND_INPUT)))
CloseDevice();
if (!OpenDevice(evt))
return FALSE;
m_production_started = TRUE;
m_queue_filled = FALSE;
// Send a dummy event to start.
if (evt & wxSOUND_OUTPUT)
OnSoundEvent(wxSOUND_OUTPUT);
if (evt & wxSOUND_INPUT) {
int i;
for (i=0;i<WXSOUND_MAX_QUEUE;i++)
AddToQueue(m_headers_rec[i]);
waveInStart(m_internal->m_devin);
}
return TRUE;
}
// -------------------------------------------------------------------------
// StopProduction()
// ------------------------------------------------------------------------
bool wxSoundStreamWin::StopProduction()
{
if (!m_production_started) {
m_snderror = wxSOUND_NOTSTARTED;
return FALSE;
}
m_snderror = wxSOUND_NOERROR;
m_production_started = FALSE;
CloseDevice();
return TRUE;
}
// -------------------------------------------------------------------------
// QueueFilled()
// -------------------------------------------------------------------------
bool wxSoundStreamWin::QueueFilled() const
{
return (!m_production_started || m_queue_filled);
}
// --------------------------------------------------------------------------
// wxSoundWinModule
// --------------------------------------------------------------------------
class WXDLLEXPORT wxSoundWinModule : public wxModule {
DECLARE_DYNAMIC_CLASS(wxSoundWinModule)
public:
bool OnInit();
void OnExit();
};
IMPLEMENT_DYNAMIC_CLASS(wxSoundWinModule, wxModule)
bool wxSoundWinModule::OnInit() {
wxSoundHandleList = new wxList(wxKEY_INTEGER);
return TRUE;
}
void wxSoundWinModule::OnExit() {
delete wxSoundHandleList;
}

View File

@@ -1,64 +0,0 @@
// --------------------------------------------------------------------------
// Name: sndwin.h
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#ifndef _WX_SNDWIN_H
#define _WX_SNDWIN_H
#include <wx/wxprec.h>
#include "sndbase.h"
typedef struct _wxSoundInternal wxSoundInternal;
typedef struct _wxSoundInfoHeader wxSoundInfoHeader;
class WXDLLEXPORT wxSoundStreamWin : public wxSoundStream {
public:
wxSoundStreamWin();
~wxSoundStreamWin();
wxSoundStream& Write(const void *buffer, wxUint32 len);
wxSoundStream& Read(void *buffer, wxUint32 len);
bool SetSoundFormat(wxSoundFormatBase& base);
bool StartProduction(int evt);
bool StopProduction();
bool QueueFilled() const;
// Internal but defined as public
void NotifyDoneBuffer(wxUint32 dev_handle, int flag);
wxUint32 GetBestSize() const { return 4096; }
protected:
wxSoundInternal *m_internal;
wxUint32 m_current_frag_in, m_current_frag_out;
wxUint32 m_input_frag_in, m_output_frag_out;
wxSoundInfoHeader **m_headers_play, **m_headers_rec;
bool m_production_started, m_queue_filled, m_waiting_for;
protected:
void CreateSndWindow();
void DestroySndWindow();
bool OpenDevice(int mode);
void CloseDevice();
wxSoundInfoHeader *AllocHeader(int mode);
void FreeHeader(wxSoundInfoHeader *header, int mode);
bool AllocHeaders(int mode);
void FreeHeaders(int mode);
void WaitFor(wxSoundInfoHeader *info);
bool AddToQueue(wxSoundInfoHeader *info);
void ClearHeader(wxSoundInfoHeader *info);
wxSoundInfoHeader *NextFragmentOutput();
wxSoundInfoHeader *NextFragmentInput();
};
#endif

View File

@@ -1,74 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
// Name: vidbdrv.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "vidbase.h"
#endif
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/stream.h>
#include <wx/wfstream.h>
#endif
#include "vidbase.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
IMPLEMENT_ABSTRACT_CLASS(wxVideoBaseDriver, wxObject)
///
wxVideoBaseDriver::wxVideoBaseDriver()
{
m_video_output = NULL;
}
wxVideoBaseDriver::wxVideoBaseDriver(wxInputStream& str)
{
m_video_output = NULL;
}
wxVideoBaseDriver::wxVideoBaseDriver(const wxString& filename)
{
m_video_output = NULL;
}
wxVideoBaseDriver::~wxVideoBaseDriver()
{
}
bool wxVideoBaseDriver::AttachOutput(wxWindow& output)
{
m_video_output = &output;
return TRUE;
}
void wxVideoBaseDriver::DetachOutput()
{
m_video_output = NULL;
}
// Use an external frame for video output
wxFrame *wxVideoCreateFrame(wxVideoBaseDriver *vid_drv)
{
wxFrame *frame = new wxFrame(NULL, -1, "Video Output", wxDefaultPosition, wxSize(100, 100));
wxWindow *vid_out = new wxWindow(frame, -1, wxPoint(0, 0), wxSize(300, 300));
frame->Layout();
frame->Show(TRUE);
vid_drv->AttachOutput(*vid_out);
vid_drv->Play();
return frame;
}

View File

@@ -1,110 +0,0 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: vidbase.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// CVS: $Id$
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
/* Real -*- C++ -*- */
#ifndef __VID_bdrv_H__
#define __VID_bdrv_H__
#ifdef __GNUG__
#pragma interface "vidbase.h"
#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/defs.h"
#include "wx/stream.h"
#include "wx/string.h"
#include "wx/window.h"
#include "wx/frame.h"
#endif
// ----------------------------------------------------------------------------
// wxMMedia2 (video) types
typedef enum {
wxVIDEO_MSAVI,
wxVIDEO_MPEG,
wxVIDEO_QT,
wxVIDEO_GIF,
wxVIDEO_JMOV,
wxVIDEO_FLI,
wxVIDEO_IFF,
wxVIDEO_SGI,
wxVIDEO_MPEG2
} wxVideoType;
// ----------------------------------------------------------------------------
// Classes definition
class WXDLLEXPORT wxVideoBaseDriver : public wxObject {
DECLARE_ABSTRACT_CLASS(wxVideoBaseDriver)
protected:
wxWindow *m_video_output;
public:
// Ctors
wxVideoBaseDriver();
wxVideoBaseDriver(wxInputStream& str);
wxVideoBaseDriver(const wxString& filename);
// Dtor
virtual ~wxVideoBaseDriver();
// Usual functions ... They all return FALSE in case of errors.
virtual bool Play() = 0;
virtual bool Stop() = 0;
virtual bool Pause() = 0;
virtual bool Resume() = 0;
// Size management
virtual bool SetSize(wxSize size) = 0;
virtual bool GetSize(wxSize& size) const = 0;
// Test the capability of the driver to handle the specified type
virtual bool IsCapable(wxVideoType WXUNUSED(v_type)) const { return FALSE; }
// Return the video codec name
virtual wxString GetMovieCodec() const = 0;
// Return the audio codec name
virtual wxString GetAudioCodec() const = 0;
// Return misc info about audio
virtual wxUint32 GetSampleRate() const = 0;
virtual wxUint8 GetChannels() const = 0;
virtual wxUint8 GetBPS() const = 0;
// Return frame rate
virtual double GetFrameRate() const = 0;
// Return number of frames
virtual wxUint32 GetNbFrames() const = 0;
// Called when the movie finished
virtual void OnFinished() {}
// Attaches the video output to a window. The video will be shown in that window.
virtual bool AttachOutput(wxWindow& output);
virtual void DetachOutput();
// They return the state of the movie.
virtual bool IsPaused() const = 0;
virtual bool IsStopped() const = 0;
};
WXDLLEXPORT wxFrame *wxVideoCreateFrame(wxVideoBaseDriver *vid_drv);
#endif

View File

@@ -1,242 +0,0 @@
// -----------------------------------------------------------------------------
// Name: vidwin.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: February 1998
// Updated:
// Copyright: (C) 1998, 1999, 2000 Guilhem Lavaux
// License: wxWindows license
// -----------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "vidwin.h"
#endif
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/stream.h"
#include "wx/wfstream.h"
#define WXMMEDIA_INTERNAL
#include <windows.h>
#include <mmsystem.h>
#include <digitalv.h>
#include "vidwin.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
IMPLEMENT_DYNAMIC_CLASS(wxVideoWindows, wxVideoBaseDriver)
wxVideoWindows::wxVideoWindows()
{
}
wxVideoWindows::wxVideoWindows(wxInputStream& str)
: wxVideoBaseDriver(str)
{
m_internal = new wxVIDWinternal;
m_remove_file = TRUE;
m_filename = wxGetTempFileName("wxvid");
m_paused = FALSE;
m_stopped = TRUE;
m_frameRate = 1.0;
wxFileOutputStream temp_file(m_filename);
temp_file << str;
OpenFile();
}
wxVideoWindows::wxVideoWindows(const wxString& filename)
: wxVideoBaseDriver(filename)
{
m_internal = new wxVIDWinternal;
m_remove_file = FALSE;
m_filename = filename;
m_paused = FALSE;
m_stopped = TRUE;
m_frameRate = 1.0;
OpenFile();
}
wxVideoWindows::~wxVideoWindows(void)
{
mciSendCommand(m_internal->m_dev_id, MCI_CLOSE, 0, 0);
if (m_internal)
delete m_internal;
}
void wxVideoWindows::OpenFile()
{
MCI_DGV_OPEN_PARMS openStruct;
MCI_DGV_SET_PARMS setStruct;
MCI_STATUS_PARMS statusStruct;
DWORD ret;
openStruct.lpstrDeviceType = "avivideo";
openStruct.lpstrElementName = (LPSTR)(m_filename.mb_str());
openStruct.hWndParent = 0;
ret = mciSendCommand(0, MCI_OPEN,
MCI_OPEN_ELEMENT|MCI_DGV_OPEN_PARENT|MCI_OPEN_TYPE|MCI_DGV_OPEN_32BIT,
(DWORD)(LPVOID)&openStruct);
m_internal->m_dev_id = openStruct.wDeviceID;
setStruct.dwCallback = 0;
setStruct.dwTimeFormat = MCI_FORMAT_FRAMES;
ret = mciSendCommand(m_internal->m_dev_id, MCI_SET, MCI_SET_TIME_FORMAT,
(DWORD)(LPVOID)&setStruct);
statusStruct.dwCallback = 0;
statusStruct.dwItem = MCI_DGV_STATUS_FRAME_RATE;
ret = mciSendCommand(m_internal->m_dev_id, MCI_STATUS,
MCI_STATUS_ITEM,
(DWORD)(LPVOID)&statusStruct);
m_frameRate = ((double)statusStruct.dwReturn) / 1000;
statusStruct.dwItem = MCI_DGV_STATUS_BITSPERSAMPLE;
ret = mciSendCommand(m_internal->m_dev_id, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)(LPVOID)&statusStruct);
m_bps = statusStruct.dwReturn;
}
bool wxVideoWindows::Pause()
{
if (m_paused || m_stopped)
return TRUE;
m_paused = TRUE;
return (mciSendCommand(m_internal->m_dev_id, MCI_PAUSE, MCI_WAIT, 0) == 0);
}
bool wxVideoWindows::Resume()
{
if (!m_paused || m_stopped)
return TRUE;
m_paused = FALSE;
return (mciSendCommand(m_internal->m_dev_id, MCI_RESUME, 0, 0) == 0);
}
bool wxVideoWindows::IsPaused() const
{
return m_paused;
}
bool wxVideoWindows::IsStopped() const
{
return m_stopped;
}
bool wxVideoWindows::GetSize(wxSize& size) const
{
size.SetWidth(200);
size.SetHeight(200);
return TRUE;
}
bool wxVideoWindows::SetSize(wxSize size)
{
return TRUE;
}
bool wxVideoWindows::IsCapable(wxVideoType v_type)
{
return (v_type == wxVIDEO_MSAVI);
}
bool wxVideoWindows::AttachOutput(wxWindow& output)
{
MCI_DGV_WINDOW_PARMS win_struct;
if (!wxVideoBaseDriver::AttachOutput(output))
return FALSE;
win_struct.hWnd = (HWND)output.GetHWND();
mciSendCommand(m_internal->m_dev_id, MCI_WINDOW,
MCI_DGV_WINDOW_HWND, (DWORD)(LPVOID)&win_struct);
return TRUE;
}
void wxVideoWindows::DetachOutput()
{
MCI_DGV_WINDOW_PARMS win_struct;
wxVideoBaseDriver::DetachOutput();
win_struct.hWnd = 0;
mciSendCommand(m_internal->m_dev_id, MCI_WINDOW,
MCI_DGV_WINDOW_HWND, (DWORD)(LPVOID)&win_struct);
}
bool wxVideoWindows::Play()
{
if (!m_stopped)
return FALSE;
m_stopped = FALSE;
return (mciSendCommand(m_internal->m_dev_id, MCI_PLAY, 0, NULL) == 0);
}
bool wxVideoWindows::Stop()
{
MCI_SEEK_PARMS seekStruct;
if (m_stopped)
return FALSE;
m_stopped = TRUE;
if (::mciSendCommand(m_internal->m_dev_id, MCI_STOP, MCI_WAIT, NULL) != 0)
return FALSE;
seekStruct.dwCallback = 0;
seekStruct.dwTo = 0;
return (::mciSendCommand(m_internal->m_dev_id, MCI_SEEK, MCI_SEEK_TO_START|MCI_WAIT, (DWORD)(LPVOID)&seekStruct) == 0);
}
// TODO TODO
// I hate windows :-(. The doc says MCI_STATUS should return all info I want but when I call it
// it returns to me with an UNSUPPORTED_FUNCTION error. I will have to do all by myself. Grrrr !
wxString wxVideoWindows::GetMovieCodec() const
{
return wxT("No info");
}
wxString wxVideoWindows::GetAudioCodec() const
{
return wxT("No info");
}
wxUint32 wxVideoWindows::GetSampleRate() const
{
return 22500;
}
wxUint8 wxVideoWindows::GetChannels() const
{
return 1;
}
wxUint8 wxVideoWindows::GetBPS() const
{
return m_bps;
}
double wxVideoWindows::GetFrameRate() const
{
return m_frameRate;
}
wxUint32 wxVideoWindows::GetNbFrames() const
{
return 0;
}

View File

@@ -1,101 +0,0 @@
// ----------------------------------------------------------------------------
// Name: vidwin.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: February 1998
// Updated:
// Copyright: (C) 1998, Guilhem Lavaux
// License: wxWindows license
// ----------------------------------------------------------------------------
#ifndef __VID_windows_H__
#define __VID_windows_H__
#ifdef __GNUG__
#pragma interface "vidwin.h"
#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/string.h"
#include "wx/stream.h"
#include "wx/window.h"
#endif
// ----------------------------------------------------------------------------
// wxMMedia2 headers
#include "vidbase.h"
// ----------------------------------------------------------------------------
// System headers and private types
#ifdef WXMMEDIA_INTERNAL
#include <windows.h>
#include <mmsystem.h>
typedef struct VIDW_Internal {
MCIDEVICEID m_dev_id;
} wxVIDWinternal;
#endif
// ----------------------------------------------------------------------------
// Class definition
class WXDLLEXPORT wxVideoWindows : public wxVideoBaseDriver {
DECLARE_DYNAMIC_CLASS(wxVideoWindows)
protected:
struct VIDW_Internal *m_internal;
bool m_paused, m_stopped, m_remove_file;
wxString m_filename;
double m_frameRate;
wxUint8 m_bps;
void OpenFile();
public:
wxVideoWindows(void);
wxVideoWindows(wxInputStream& str);
wxVideoWindows(const wxString& fname);
~wxVideoWindows(void);
bool Play();
bool Stop();
bool Pause();
bool Resume();
bool GetSize(wxSize& size) const;
bool SetSize(wxSize size);
// Return codec name for each stream.
wxString GetMovieCodec() const;
wxString GetAudioCodec() const;
// Return misc. info about audio
wxUint32 GetSampleRate() const;
wxUint8 GetChannels() const;
wxUint8 GetBPS() const;
// Return the frame rate of the video (in frames/second)
double GetFrameRate() const;
// Return the total number of frames in the movie
wxUint32 GetNbFrames() const;
bool IsCapable(wxVideoType v_type);
bool AttachOutput(wxWindow& output);
void DetachOutput(void);
bool IsPaused() const;
bool IsStopped() const;
};
#endif

View File

@@ -1,510 +0,0 @@
// -------------------------------------------------------------------------
// Name: vidxanm.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, 1999 Guilhem Lavaux
// License: wxWindows license
// -------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "vidxanm.h"
#endif
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
// Pizza !
#include <wx/gtk/win_gtk.h>
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#ifdef __WXGTK__
#include <gtk/gtkwidget.h>
#include <gtk/gtkwindow.h>
#include <gdk/gdk.h>
#include <gdk/gdkprivate.h>
#endif
#include <wx/filefn.h>
#include <wx/wfstream.h>
#include <wx/datstrm.h>
#include <wx/tokenzr.h>
#define WXMMEDIA_INTERNAL
#include "vidbase.h"
#include "vidxanm.h"
IMPLEMENT_DYNAMIC_CLASS(wxVideoXANIM, wxVideoBaseDriver)
// -------------------------------------------------------------------------
// End process detector
class wxVideoXANIMProcess: public wxProcess {
public:
wxVideoXANIMProcess(wxVideoXANIM *xanim);
void OnTerminate(int pid, int status);
protected:
wxVideoXANIM *m_vid_xanim;
};
class wxVideoXANIMOutput: public wxProcess {
public:
wxVideoXANIMOutput();
void OnTerminate(int pid, int status);
bool IsTerminated() const;
protected:
bool m_terminated;
};
// -------------------------------------------------------------------------
// XAnim video driver (process handling implementation)
wxVideoXANIMProcess::wxVideoXANIMProcess(wxVideoXANIM *xanim)
{
m_vid_xanim = xanim;
}
void wxVideoXANIMProcess::OnTerminate(int WXUNUSED(pid), int WXUNUSED(status))
{
m_vid_xanim->m_xanim_started = FALSE;
m_vid_xanim->OnFinished();
}
wxVideoXANIMOutput::wxVideoXANIMOutput()
: wxProcess(NULL, TRUE, -1)
{
m_terminated = FALSE;
}
bool wxVideoXANIMOutput::IsTerminated() const
{
return m_terminated;
}
void wxVideoXANIMOutput::OnTerminate(int pid, int status)
{
m_terminated = TRUE;
}
// -------------------------------------------------------------------------
// XAnim video driver (implementation)
wxVideoXANIM::wxVideoXANIM()
: wxVideoBaseDriver()
{
m_internal = new wxXANIMinternal;
m_xanim_detector = new wxVideoXANIMProcess(this);
m_xanim_started = FALSE;
m_paused = FALSE;
m_filename = "";
m_remove_file = FALSE;
}
wxVideoXANIM::wxVideoXANIM(wxInputStream& str)
: wxVideoBaseDriver(str)
{
m_internal = new wxXANIMinternal;
m_xanim_detector = new wxVideoXANIMProcess(this);
m_xanim_started = FALSE;
m_paused = FALSE;
m_size[0] = 0;
m_size[1] = 0;
m_filename = wxGetTempFileName("vidxa");
m_remove_file = TRUE;
wxFileOutputStream fout(m_filename);
fout << str;
CollectInfo();
}
wxVideoXANIM::wxVideoXANIM(const wxString& filename)
{
m_internal = new wxXANIMinternal;
m_xanim_detector = new wxVideoXANIMProcess(this);
m_xanim_started = FALSE;
m_paused = FALSE;
m_filename = filename;
m_remove_file = FALSE;
m_size[0] = 0;
m_size[1] = 0;
CollectInfo();
}
wxVideoXANIM::~wxVideoXANIM()
{
if (m_xanim_started)
Stop();
delete m_internal;
delete m_xanim_detector;
if (m_remove_file)
wxRemoveFile(m_filename);
}
// -------------------------------------------------------------------------
// Movie controller
bool wxVideoXANIM::Play()
{
if (!m_paused && m_xanim_started)
return TRUE;
if (!m_video_output) {
wxVideoCreateFrame(this);
return TRUE;
}
// The movie starts with xanim
if (RestartXANIM()) {
m_paused = FALSE;
return TRUE;
}
return FALSE;
}
bool wxVideoXANIM::Pause()
{
if (!m_paused && SendCommand(" ")) {
m_paused = TRUE;
return TRUE;
}
return FALSE;
}
bool wxVideoXANIM::Resume()
{
if (m_paused && SendCommand(" ")) {
m_paused = FALSE;
return TRUE;
}
return FALSE;
}
bool wxVideoXANIM::Stop()
{
if (!m_xanim_started)
return FALSE;
SendCommand("q");
// We are waiting for the termination of the subprocess.
while (m_xanim_started) {
wxYield();
}
m_paused = FALSE;
return TRUE;
}
// -------------------------------------------------------------------------
// Movie size controller
bool wxVideoXANIM::SetSize(wxSize size)
{
if (!m_video_output)
return FALSE;
m_video_output->SetSize(size.GetWidth(), size.GetHeight());
return FALSE;
}
bool wxVideoXANIM::GetSize(wxSize& size) const
{
if (m_size[0] == 0)
return FALSE;
size.Set(m_size[0], m_size[1]);
return TRUE;
}
// -------------------------------------------------------------------------
// Capabilities of XAnim
bool wxVideoXANIM::IsCapable(wxVideoType v_type) const
{
if (v_type == wxVIDEO_MSAVI || v_type == wxVIDEO_MPEG ||
v_type == wxVIDEO_QT || v_type == wxVIDEO_GIF || v_type == wxVIDEO_JMOV ||
v_type == wxVIDEO_FLI || v_type == wxVIDEO_IFF || v_type == wxVIDEO_SGI)
return TRUE;
else
return FALSE;
}
// -------------------------------------------------------------------------
// Movie state
wxString wxVideoXANIM::GetMovieCodec() const
{
if (m_size[0] == 0)
return wxT("");
return m_movieCodec;
}
wxString wxVideoXANIM::GetAudioCodec() const
{
if (m_size[0] == 0)
return wxT("");
return m_audioCodec;
}
wxUint32 wxVideoXANIM::GetSampleRate() const
{
if (m_size[0] == 0)
return 0;
return m_sampleRate;
}
wxUint8 wxVideoXANIM::GetChannels() const
{
if (m_size[0] == 0)
return 0;
return m_channels;
}
wxUint8 wxVideoXANIM::GetBPS() const
{
if (m_size[0] == 0)
return 0;
return m_bps;
}
double wxVideoXANIM::GetFrameRate() const
{
if (m_size[0] == 0)
return 0.0;
return m_frameRate;
}
wxUint32 wxVideoXANIM::GetNbFrames() const
{
if (m_size[0] == 0)
return 0;
return m_frames;
}
bool wxVideoXANIM::IsPaused() const
{
return m_paused;
}
bool wxVideoXANIM::IsStopped() const
{
return !m_xanim_started;
}
// -------------------------------------------------------------------------
// Output management
bool wxVideoXANIM::AttachOutput(wxWindow& out)
{
if (!wxVideoBaseDriver::AttachOutput(out))
return FALSE;
return TRUE;
}
void wxVideoXANIM::DetachOutput()
{
SendCommand("q");
m_xanim_started = FALSE;
m_paused = FALSE;
wxVideoBaseDriver::DetachOutput();
}
// -------------------------------------------------------------------------
// Lowlevel XAnim controller
bool wxVideoXANIM::SendCommand(const char *command, char **ret,
wxUint32 *size)
{
if (!m_xanim_started)
if (!RestartXANIM())
return FALSE;
// Send a command to XAnim through X11 Property
XChangeProperty(m_internal->xanim_dpy, m_internal->xanim_window,
m_internal->xanim_atom,
XA_STRING, 8, PropModeReplace, (unsigned char *)command,
strlen(command));
XFlush(m_internal->xanim_dpy);
if (ret) {
int prop_format;
Atom prop_type;
unsigned long extra;
XGetWindowProperty(m_internal->xanim_dpy, m_internal->xanim_window,
m_internal->xanim_ret, 0, 16, True, AnyPropertyType,
&prop_type, &prop_format, (unsigned long *)size,
&extra, (unsigned char **)ret);
}
return TRUE;
}
bool wxVideoXANIM::CollectInfo()
{
wxVideoXANIMOutput *xanimProcess;
wxString xanim_command;
wxStringTokenizer tokenizer;
xanimProcess = new wxVideoXANIMOutput;
xanim_command = wxT("xanim +v +Zv -Ae ");
xanim_command += m_filename;
if (!wxExecute(xanim_command, FALSE, xanimProcess))
return FALSE;
wxInputStream *infoStream = xanimProcess->GetInputStream();
wxString totalOutput;
while (infoStream->LastError() == wxSTREAM_NOERROR) {
char line[100];
infoStream->Read(line, sizeof(line)-1);
if (infoStream->LastRead() == 0)
break;
line[infoStream->LastRead()] = 0;
totalOutput += line;
}
// This is good for everything ... :-)
int position = totalOutput.Find(wxT("Video Codec:"));
totalOutput.Remove(0, position+13);
position = totalOutput.Find(wxT("depth="));
m_movieCodec = totalOutput(0, position);
totalOutput.Remove(0, position);
tokenizer.SetString(totalOutput, "\n\r");
// the rest of the line
wxString token = tokenizer.GetNextToken();
unsigned long my_long;
#define GETINT(i) \
totalOutput.ToULong(&my_long); \
i = my_long;
// 'Audio Codec:'
totalOutput = tokenizer.GetString();
totalOutput.Remove(0, totalOutput.Find(wxT(":"))+2);
position = totalOutput.Find(wxT("Rate"));
m_audioCodec = totalOutput(0, position-1);
// 'Rate='
totalOutput.Remove(0, totalOutput.Find(wxT("="))+1);
GETINT(m_sampleRate);
// 'Chans='
totalOutput.Remove(0, totalOutput.Find(wxT("="))+1);
GETINT(m_channels);
// 'Bps='
totalOutput.Remove(0, totalOutput.Find(wxT("="))+1);
GETINT(m_bps);
// 'Frame Stats:'
tokenizer.Reinit(totalOutput);
tokenizer.GetNextToken();
totalOutput = tokenizer.GetString();
totalOutput.Remove(0, totalOutput.Find(wxT(":"))+2);
// 'Size='
totalOutput.Remove(0, totalOutput.Find(wxT("="))+1);
GETINT(m_size[0]);
// 'x'
totalOutput.Remove(0,1);
GETINT(m_size[1]);
// 'Frames='
totalOutput.Remove(0, totalOutput.Find(wxT("="))+1);
GETINT(m_frames);
// 'avfps='
totalOutput.Remove(0, totalOutput.Find(wxT("="))+1);
totalOutput.ToDouble(&m_frameRate);
// We wait for the conclusion
while (!xanimProcess->IsTerminated())
wxYield();
delete xanimProcess;
return TRUE;
}
bool wxVideoXANIM::RestartXANIM()
{
wxString xanim_command;
int ret;
Atom prop_type;
int prop_format;
unsigned long nitems;
unsigned long extra;
char prop[4];
bool xanim_chg_size;
if (!m_video_output || m_xanim_started)
return FALSE;
// Check if we can change the size of the window dynamicly
xanim_chg_size = TRUE;
// Get current display
#ifdef __WXGTK__
m_internal->xanim_dpy = gdk_display;
GtkPizza *pizza = GTK_PIZZA( m_video_output->m_wxwindow );
GdkWindow *window = pizza->bin_window;
m_internal->xanim_window =
((GdkWindowPrivate *)window)->xwindow;
#endif
// Get the XANIM atom
m_internal->xanim_atom = XInternAtom(m_internal->xanim_dpy,
"XANIM_PROPERTY", False);
// Build the command
xanim_command.Printf(wxT("xanim -Zr +Ze +Sr +f +W%d +f +q "
"+Av70 %s %s"), m_internal->xanim_window,
(xanim_chg_size) ? _T("") : _T(""),
WXSTRINGCAST m_filename);
// Execute it
if (!wxExecute(xanim_command, FALSE, m_xanim_detector))
return FALSE;
// Wait for XAnim to be ready
nitems = 0;
m_xanim_started = TRUE;
while (nitems == 0 && m_xanim_started) {
ret = XGetWindowProperty(m_internal->xanim_dpy, m_internal->xanim_window,
m_internal->xanim_atom,
0, 4, False, AnyPropertyType, &prop_type,
&prop_format, &nitems, &extra,
(unsigned char **)&prop);
wxYield();
}
wxSize vibrato_size;
vibrato_size = m_video_output->GetSize();
vibrato_size.SetWidth(vibrato_size.GetWidth()+1);
m_video_output->SetSize(vibrato_size);
vibrato_size.SetWidth(vibrato_size.GetWidth()-1);
m_video_output->SetSize(vibrato_size);
// Very useful ! Actually it sends a SETSIZE event to XAnim
m_paused = FALSE;
return TRUE;
}

View File

@@ -1,136 +0,0 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: vidxanm.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
/* Real -*- C++ -*- */
#ifndef __VID_xanim_H__
#define __VID_xanim_H__
#ifdef __GNUG__
#pragma interface "vidxanm.h"
#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/defs.h"
#include "wx/string.h"
#include "wx/process.h"
#endif
// ----------------------------------------------------------------------------
// System dependent headers
#if defined(WXMMEDIA_INTERNAL) && (defined(__X__) || defined(__WXGTK__))
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#endif
// ----------------------------------------------------------------------------
// wxMMedia2 headers
#include "vidbase.h"
// ----------------------------------------------------------------------------
// Internal types
#ifdef WXMMEDIA_INTERNAL
typedef struct wxXANIMinternal {
Display *xanim_dpy;
Window xanim_window;
Atom xanim_atom, xanim_ret;
} wxXANIMinternal;
#ifndef __XANIM_COMMAND__
#define __XANIM_COMMAND__ "/usr/X11R6/bin/xanim"
#endif
#endif
// ----------------------------------------------------------------------------
// Class definition
class WXDLLEXPORT wxVideoXANIM : public wxVideoBaseDriver {
DECLARE_DYNAMIC_CLASS(wxVideoXANIM)
protected:
// Remember the state of the subprocess
bool m_xanim_started, m_paused;
// Pure X11 variables
struct wxXANIMinternal *m_internal;
wxString m_filename;
wxProcess *m_xanim_detector;
// Remember to delete the temporary file when necessary
bool m_remove_file;
wxUint32 m_size[2];
wxUint32 m_sampleRate;
wxUint8 m_channels;
wxUint8 m_bps;
wxUint32 m_frames;
double m_frameRate;
wxString m_movieCodec, m_audioCodec;
public:
wxVideoXANIM();
wxVideoXANIM(wxInputStream& str);
wxVideoXANIM(const wxString& filename);
~wxVideoXANIM();
bool Play();
bool Pause();
bool Resume();
bool Stop();
bool SetVolume(wxUint8 vol);
bool SetSize(wxSize size);
bool GetSize(wxSize& size) const;
// Return the video codec name
wxString GetMovieCodec() const;
// Return the audio codec name
wxString GetAudioCodec() const;
// Return misc info about audio
wxUint32 GetSampleRate() const;
wxUint8 GetChannels() const;
wxUint8 GetBPS() const;
// Return frame rate
double GetFrameRate() const;
// Return number of frames in the movie
wxUint32 GetNbFrames() const;
bool IsCapable(wxVideoType v_type) const;
bool AttachOutput(wxWindow& output);
void DetachOutput();
bool IsPaused() const;
bool IsStopped() const;
friend class wxVideoXANIMProcess;
protected:
// Start the subprocess with the right parameters
bool RestartXANIM();
// Send a command to the subprocess
bool SendCommand(const char *command,char **ret = NULL,
wxUint32 *size = NULL);
// Collect informations from XAnim
bool CollectInfo();
};
#endif

View File

@@ -1,85 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: process.cpp
// Purpose: Process termination classes
// Author: Guilhem Lavaux
// Modified by: Vadim Zeitlin to check error codes, added Detach() method
// Created: 24/06/98
// RCS-ID: $Id$
// Copyright: (c) Guilhem Lavaux
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "process.h"
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/defs.h"
#endif
#include "wx/process.h"
IMPLEMENT_DYNAMIC_CLASS(wxProcess, wxEvtHandler)
IMPLEMENT_DYNAMIC_CLASS(wxProcessEvent, wxEvent)
wxProcess::wxProcess(wxEvtHandler *parent, bool needPipe, int id)
{
if (parent)
SetNextHandler(parent);
m_id = id;
m_needPipe = needPipe;
m_in_stream = NULL;
m_out_stream = NULL;
}
wxProcess::~wxProcess()
{
if (m_in_stream)
delete m_in_stream;
if (m_out_stream)
delete m_out_stream;
}
void wxProcess::OnTerminate(int pid, int status)
{
wxProcessEvent event(m_id, pid, status);
if ( !ProcessEvent(event) )
delete this;
//else: the object which processed the event is responsible for deleting
// us!
}
void wxProcess::Detach()
{
SetNextHandler(NULL);
}
void wxProcess::SetPipeStreams(wxInputStream *in_stream, wxOutputStream *out_stream)
{
m_in_stream = in_stream;
m_out_stream = out_stream;
}
wxInputStream *wxProcess::GetInputStream() const
{
return m_in_stream;
}
wxOutputStream *wxProcess::GetOutputStream() const
{
return m_out_stream;
}
bool wxProcess::NeedPipe() const
{
return m_needPipe;
}

View File

@@ -1,86 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: process.h
// Purpose: wxProcess class
// Author: Guilhem Lavaux
// Modified by: Vadim Zeitlin to check error codes, added Detach() method
// Created: 24/06/98
// RCS-ID: $Id$
// Copyright: (c) 1998 Guilhem Lavaux
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_PROCESSH__
#define _WX_PROCESSH__
#ifdef __GNUG__
#pragma interface "process.h"
#endif
#include "wx/defs.h"
#include "wx/object.h"
#include "wx/event.h"
#include "wx/stream.h"
// Process Event handling
class WXDLLEXPORT wxProcessEvent : public wxEvent
{
DECLARE_DYNAMIC_CLASS(wxProcessEvent)
public:
wxProcessEvent(int id = 0, int pid = 0, int exitcode = 0) : wxEvent(id)
{
m_eventType = wxEVT_END_PROCESS;
m_pid = pid;
m_exitcode = exitcode;
}
// accessors
// PID of process which terminated
int GetPid() { return m_pid; }
// the exit code
int GetExitCode() { return m_exitcode; }
public:
int m_pid, m_exitcode;
};
// A wxProcess object should be passed to wxExecute - than its OnTerminate()
// function will be called when the process terminates.
class WXDLLEXPORT wxProcess : public wxEvtHandler
{
DECLARE_DYNAMIC_CLASS(wxProcess)
public:
wxProcess(wxEvtHandler *parent = (wxEvtHandler *) NULL, bool needPipe = FALSE, int id = -1);
~wxProcess();
virtual void OnTerminate(int pid, int status);
// detach from the parent - should be called by the parent if it's deleted
// before the process it started terminates
void Detach();
// Pipe handling
wxInputStream *GetInputStream() const;
wxOutputStream *GetOutputStream() const;
// These functions should not be called by the usual user. They are only
// intended to be used by wxExecute.
// Install pipes
void SetPipeStreams(wxInputStream *in_stream, wxOutputStream *out_stream);
bool NeedPipe() const;
protected:
int m_id;
bool m_needPipe;
wxInputStream *m_in_stream;
wxOutputStream *m_out_stream;
};
typedef void (wxObject::*wxProcessEventFunction)(wxProcessEvent&);
#define EVT_END_PROCESS(id, func) { wxEVT_END_PROCESS, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxProcessEventFunction) & func, NULL},
#endif
// _WX_PROCESSH__

View File

@@ -1,51 +0,0 @@
#
# File: Makefile.in
# Author: Julian Smart
# Created: 1998
# Updated:
# Copyright: (c) 1998 Julian Smart
#
# "%W% %G%"
#
# Makefile for wxsocket example (UNIX).
top_srcdir = @top_srcdir@/..
top_builddir = ../../..
program_dir = utils/wxMMedia2/sample
# the comment at the end of the next line is needed because otherwise autoconf
# would remove this line completely - it contains a built-in hack to remove
# any VPATH assignment not containing ':'
VPATH = @PATH_IFS@$(top_srcdir)/utils/wxMMedia2/sample # ':' for autoconf
# Clears all default suffixes
.SUFFIXES: .o .cpp .c .cxx
.cpp.o :
$(CC) -c $(CPPFLAGS) -o $@ $<
# Set defaults from configure
include ../../../src/make.env
LDLIBS2 = $(LDLIBS) ../lib/libwxmmedia2.a
all: test_med test_med3 test_med5 test_med2 test_med4
test_med: test_med.o ../../../lib/@WX_TARGET_LIBRARY@
$(CC) $(LDFLAGS) -o test_med test_med.o $(LDLIBS2)
test_med2: test_med2.o ../../../lib/@WX_TARGET_LIBRARY@
$(CC) $(LDFLAGS) -o test_med2 test_med2.o $(LDLIBS2)
test_med3: test_med3.o ../../../lib/@WX_TARGET_LIBRARY@
$(CC) $(LDFLAGS) -o test_med3 test_med3.o $(LDLIBS2)
test_med4: test_med4.o ../../../lib/@WX_TARGET_LIBRARY@
$(CC) $(LDFLAGS) -o test_med4 test_med4.o $(LDLIBS2)
test_med5: test_med5.o ../../../lib/@WX_TARGET_LIBRARY@
$(CC) $(LDFLAGS) -o test_med5 test_med5.o $(LDLIBS2)
clean:
rm -f test_med* core

View File

@@ -1,17 +0,0 @@
#
# File: makefile.g95
# Author: Julian Smart
# Created: 1999
# Updated:
# Copyright: (c) Julian Smart, 1999
#
# Makefile for wxWindows sample (Cygwin/Mingw32).
WXDIR = ../../..
TARGET=test_med4
OBJECTS = $(TARGET).o
EXTRALIBS= ../lib/libwxmmedia2 -lwx -lwinmm
include $(WXDIR)\src\makeprog.g95

View File

@@ -1,66 +0,0 @@
// --------------------------------------------------------------------------
// Name: test_med.cpp
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#include <wx/app.h>
#include <wx/wfstream.h>
#include <wx/frame.h>
#include "../lib/sndoss.h"
#include "../lib/sndwav.h"
#include "../lib/sndaiff.h"
#include "../lib/sndulaw.h"
wxSoundStreamOSS *oss_dev;
wxInputStream *f_input;
wxSoundStreamUlaw *ulaw_codec;
class MySoundStream: public wxSoundStream {
public:
wxSoundStream& Read(void *buffer, size_t len) { return *this; }
wxSoundStream& Write(const void *buffer, size_t len) { return *this; }
bool StartProduction(int evt) { return FALSE; }
bool StopProduction() { return FALSE; }
void SetDuplexMode(bool on) {}
void OnSoundEvent(int evt) {
char buffer[2048];
f_input->Read(buffer, sizeof(buffer));
ulaw_codec->Write(buffer, sizeof(buffer));
}
};
class MyApp: public wxApp {
bool OnInit() {
wxSoundFormatUlaw ulaw;
MySoundStream strm;
oss_dev = new wxSoundStreamOSS();
f_input = new wxFileInputStream(argv[1]);
if (oss_dev->GetError() != wxSOUND_NOERR) {
wxPrintf("No device\n");
return FALSE;
}
ulaw.SetSampleRate(8000);
ulaw_codec = new wxSoundStreamUlaw(*oss_dev);
ulaw_codec->SetSoundFormat(ulaw);
oss_dev->SetEventHandler(&strm);
oss_dev->StartProduction(wxSOUND_OUTPUT);
while (1) {
// wxYield();
strm.OnSoundEvent(0);
}
return TRUE;
}
};
IMPLEMENT_APP(MyApp)

View File

@@ -1,43 +0,0 @@
// --------------------------------------------------------------------------
// Name: test_med.cpp
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#include <wx/app.h>
#include <wx/wfstream.h>
#include <wx/frame.h>
#include "../lib/sndoss.h"
#include "../lib/sndesd.h"
#include "../lib/sndwav.h"
#include "../lib/sndaiff.h"
class MyApp: public wxApp {
bool OnInit() {
// wxSoundStreamOSS *oss_dev = new wxSoundStreamOSS();
wxSoundStreamESD *oss_dev = new wxSoundStreamESD();
wxFileInputStream *f_input = new wxFileInputStream(argv[1]);
wxSoundFileStream *wav_file;
wxFrame *frame = new wxFrame(NULL, -1, "My Frame");
wxSoundFormatPcm pcm;
if (oss_dev->GetError() != wxSOUND_NOERR) {
wxPrintf("No device\n");
return FALSE;
}
wav_file = new wxSoundWave(*f_input, *oss_dev);
if (!wav_file->CanRead()) {
wav_file = new wxSoundAiff(*f_input, *oss_dev);
if (!wav_file->CanRead())
return FALSE;
}
wav_file->Play();
frame->Show(TRUE);
return TRUE;
}
};
IMPLEMENT_APP(MyApp)

View File

@@ -1,23 +0,0 @@
// --------------------------------------------------------------------------
// Name: test_med.cpp
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#include <wx/app.h>
#include <wx/wfstream.h>
#include <wx/frame.h>
#include "../lib/vidxanm.h"
class MyApp: public wxApp {
bool OnInit() {
wxFileInputStream *file = new wxFileInputStream(argv[1]);
wxVideoXANIM *vidxanm = new wxVideoXANIM(*file);
vidxanm->Play();
return TRUE;
}
};
IMPLEMENT_APP(MyApp)

View File

@@ -1,54 +0,0 @@
// --------------------------------------------------------------------------
// Name: test_med.cpp
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#include <wx/wxprec.h>
#include <wx/app.h>
#include <wx/wfstream.h>
#include <wx/frame.h>
#include "../lib/sndoss.h"
#include "../lib/sndwav.h"
#include "../lib/sndaiff.h"
#include "../lib/sndwin.h"
class MyApp: public wxApp {
wxSoundStream *oss_dev;
wxOutputStream *f_output;
wxSoundFileStream *wav_file;
bool OnInit() {
wxFrame *frame = new wxFrame(NULL, -1, "My Frame");
wxSoundFormatPcm pcm;
oss_dev = new wxSoundStreamWin();
f_output = new wxFileOutputStream(argv[1]);
wav_file = new wxSoundWave(*f_output, *oss_dev);
if (oss_dev->GetError() != wxSOUND_NOERR) {
wxPrintf("No device\n");
return FALSE;
}
pcm.SetSampleRate(22050);
pcm.SetBPS(8);
pcm.SetChannels(1);
wav_file->SetSoundFormat(pcm);
// Record 10 sec of sound
wav_file->Record(10);
frame->Show(TRUE);
return TRUE;
}
int OnExit() {
delete wav_file;
delete f_output;
delete oss_dev;
return 0;
}
};
IMPLEMENT_APP(MyApp)

View File

@@ -1,22 +0,0 @@
// --------------------------------------------------------------------------
// Name: test_med.cpp
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
#include <wx/app.h>
#include <wx/wfstream.h>
#include <wx/frame.h>
#include "../lib/cdunix.h"
class MyApp: public wxApp {
bool OnInit() {
wxCDAudioLinux m_cd;
m_cd.Play(m_cd.GetToc().GetTrackTime(0),m_cd.GetToc().GetTrackTime(1));
return TRUE;
}
};
IMPLEMENT_APP(MyApp)

View File

@@ -1,672 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: msw/utilsexec.cpp
// Purpose: Various utilities
// Author: Julian Smart
// Modified by:
// Created: 04/01/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart and Markus Holzem
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/utils.h"
#include "wx/app.h"
#include "wx/intl.h"
#endif
#include "wx/log.h"
#ifdef __WIN32__
#include "wx/stream.h"
#include "wx/process.h"
#endif
#include "wx/msw/private.h"
#include <ctype.h>
#if !defined(__GNUWIN32__) && !defined(__WXWINE__) && !defined(__SALFORDC__)
#include <direct.h>
#ifndef __MWERKS__
#include <dos.h>
#endif
#endif
#if defined(__GNUWIN32__) && !defined(__TWIN32__)
#include <sys/unistd.h>
#include <sys/stat.h>
#endif
#if defined(__WIN32__) && !defined(__WXWINE__)
#include <io.h>
#ifndef __GNUWIN32__
#include <shellapi.h>
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef __WATCOMC__
#if !(defined(_MSC_VER) && (_MSC_VER > 800))
#include <errno.h>
#endif
#endif
#include <stdarg.h>
#if wxUSE_IPC
#include "wx/dde.h" // for WX_DDE hack in wxExecute
#endif // wxUSE_IPC
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
// this message is sent when the process we're waiting for terminates
#define wxWM_PROC_TERMINATED (WM_USER + 10000)
// ----------------------------------------------------------------------------
// this module globals
// ----------------------------------------------------------------------------
// we need to create a hidden window to receive the process termination
// notifications and for this we need a (Win) class name for it which we will
// register the first time it's needed
static const wxChar *gs_classForHiddenWindow = NULL;
// ----------------------------------------------------------------------------
// private types
// ----------------------------------------------------------------------------
// structure describing the process we're being waiting for
struct wxExecuteData
{
public:
~wxExecuteData()
{
#ifndef __WIN16__
if ( !::CloseHandle(hProcess) )
{
wxLogLastError("CloseHandle(hProcess)");
}
#endif
}
HWND hWnd; // window to send wxWM_PROC_TERMINATED to
HANDLE hProcess; // handle of the process
DWORD dwProcessId; // pid of the process
wxProcess *handler;
DWORD dwExitCode; // the exit code of the process
bool state; // set to FALSE when the process finishes
};
#ifdef __WIN32__
// ----------------------------------------------------------------------------
// wxPipeStreams
// ----------------------------------------------------------------------------
class wxPipeInputStream: public wxInputStream {
public:
wxPipeInputStream(HANDLE hInput);
~wxPipeInputStream();
protected:
size_t OnSysRead(void *buffer, size_t len);
protected:
HANDLE m_hInput;
};
class wxPipeOutputStream: public wxOutputStream {
public:
wxPipeOutputStream(HANDLE hOutput);
~wxPipeOutputStream();
protected:
size_t OnSysWrite(const void *buffer, size_t len);
protected:
HANDLE m_hOutput;
};
// ==================
// wxPipeInputStream
// ==================
wxPipeInputStream::wxPipeInputStream(HANDLE hInput)
{
m_hInput = hInput;
}
wxPipeInputStream::~wxPipeInputStream()
{
::CloseHandle(m_hInput);
}
size_t wxPipeInputStream::OnSysRead(void *buffer, size_t len)
{
DWORD bytesRead;
m_lasterror = wxSTREAM_NOERROR;
if (! ::ReadFile(m_hInput, buffer, len, &bytesRead, NULL) ) {
if (GetLastError() == ERROR_BROKEN_PIPE)
m_lasterror = wxSTREAM_EOF;
else
m_lasterror = wxSTREAM_READ_ERROR;
}
return bytesRead;
}
// ==================
// wxPipeOutputStream
// ==================
wxPipeOutputStream::wxPipeOutputStream(HANDLE hOutput)
{
m_hOutput = hOutput;
}
wxPipeOutputStream::~wxPipeOutputStream()
{
::CloseHandle(m_hOutput);
}
size_t wxPipeOutputStream::OnSysWrite(const void *buffer, size_t len)
{
DWORD bytesRead;
m_lasterror = wxSTREAM_NOERROR;
if (! ::WriteFile(m_hOutput, buffer, len, &bytesRead, NULL) ) {
if (GetLastError() == ERROR_BROKEN_PIPE)
m_lasterror = wxSTREAM_EOF;
else
m_lasterror = wxSTREAM_READ_ERROR;
}
return bytesRead;
}
#endif // __WIN32__
// ============================================================================
// implementation
// ============================================================================
#ifdef __WIN32__
static DWORD wxExecuteThread(wxExecuteData *data)
{
WaitForSingleObject(data->hProcess, INFINITE);
// get the exit code
if ( !GetExitCodeProcess(data->hProcess, &data->dwExitCode) )
{
wxLogLastError("GetExitCodeProcess");
}
wxASSERT_MSG( data->dwExitCode != STILL_ACTIVE,
wxT("process should have terminated") );
// send a message indicating process termination to the window
SendMessage(data->hWnd, wxWM_PROC_TERMINATED, 0, (LPARAM)data);
return 0;
}
// window procedure of a hidden window which is created just to receive
// the notification message when a process exits
LRESULT APIENTRY _EXPORT wxExecuteWindowCbk(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
if ( message == wxWM_PROC_TERMINATED )
{
DestroyWindow(hWnd); // we don't need it any more
wxExecuteData *data = (wxExecuteData *)lParam;
if ( data->handler )
{
data->handler->OnTerminate((int)data->dwProcessId,
(int)data->dwExitCode);
}
if ( data->state )
{
// we're executing synchronously, tell the waiting thread
// that the process finished
data->state = 0;
}
else
{
// asynchronous execution - we should do the clean up
delete data;
}
return 0;
}
else
{
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
#endif // Win32
long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
{
wxCHECK_MSG( !!cmd, 0, wxT("empty command in wxExecute") );
wxString command;
#if wxUSE_IPC
// DDE hack: this is really not pretty, but we need to allow this for
// transparent handling of DDE servers in wxMimeTypesManager. Usually it
// returns the command which should be run to view/open/... a file of the
// given type. Sometimes, however, this command just launches the server
// and an additional DDE request must be made to really open the file. To
// keep all this well hidden from the application, we allow a special form
// of command: WX_DDE:<command>:DDE_SERVER:DDE_TOPIC:DDE_COMMAND in which
// case we execute just <command> and process the rest below
wxString ddeServer, ddeTopic, ddeCommand;
static const size_t lenDdePrefix = 7; // strlen("WX_DDE:")
if ( cmd.Left(lenDdePrefix) == _T("WX_DDE#") )
{
const wxChar *p = cmd.c_str() + 7;
while ( *p && *p != _T('#') )
{
command += *p++;
}
if ( *p )
{
// skip '#'
p++;
}
else
{
wxFAIL_MSG(_T("invalid WX_DDE command in wxExecute"));
}
while ( *p && *p != _T('#') )
{
ddeServer += *p++;
}
if ( *p )
{
// skip '#'
p++;
}
else
{
wxFAIL_MSG(_T("invalid WX_DDE command in wxExecute"));
}
while ( *p && *p != _T('#') )
{
ddeTopic += *p++;
}
if ( *p )
{
// skip '#'
p++;
}
else
{
wxFAIL_MSG(_T("invalid WX_DDE command in wxExecute"));
}
while ( *p )
{
ddeCommand += *p++;
}
}
else
#endif // wxUSE_IPC
{
// no DDE
command = cmd;
}
#if defined(__WIN32__) && !defined(__TWIN32__)
// the old code is disabled because we really need a process handle
// if we want to execute it asynchronously or even just get its
// return code and for this we must use CreateProcess() and not
// ShellExecute()
#if 0
// isolate command and arguments
wxString commandName;
bool insideQuotes = FALSE;
const char *pc;
for ( pc = command.c_str(); *pc != '\0'; pc++ )
{
switch ( *pc )
{
case ' ':
case '\t':
if ( !insideQuotes )
break;
// fall through
case '"':
insideQuotes = !insideQuotes;
// fall through
default:
commandName += *pc;
continue; // skip the next break
}
// only reached for space not inside quotes
break;
}
wxString commandArgs = pc;
wxWindow *winTop = wxTheApp->GetTopWindow();
HWND hwndTop = (HWND)(winTop ? winTop->GetHWND() : 0);
HANDLE result;
#ifdef __GNUWIN32__
result = ShellExecute(hwndTop,
(const wchar_t)"open",
(const wchar_t)commandName,
(const wchar_t)commandArgs,
(const wchar_t)NULL,
SW_SHOWNORMAL);
#else // !GNUWIN32
result = ShellExecute(hwndTop, "open", commandName,
commandArgs, NULL, SW_SHOWNORMAL);
#endif // GNUWIN32
if ( ((long)result) <= 32 )
wxLogSysError(_("Can't execute command '%s'"), command.c_str());
return result;
#else // 1
HANDLE h_readPipe[2];
HANDLE h_writePipe[2];
HANDLE h_oldreadPipe;
HANDLE h_oldwritePipe;
BOOL inheritHandles;
// ------------------------------------
// Pipe handling
// We are in the case of opening a pipe
inheritHandles = FALSE;
if (handler && handler->NeedPipe()) {
SECURITY_ATTRIBUTES security;
security.nLength = sizeof(security);
security.lpSecurityDescriptor = NULL;
security.bInheritHandle = TRUE;
if (! ::CreatePipe(&h_readPipe[0], &h_readPipe[1], &security, 0) ) {
wxLogSysError(_T("Can't create the inter-process read pipe"));
return 0;
}
if (! ::CreatePipe(&h_writePipe[0], &h_writePipe[1], &security, 0) ) {
wxLogSysError(_T("Can't create the inter-process read pipe"));
return 0;
}
// We need to save the old stdio handles to restore them after the call
// to CreateProcess
h_oldreadPipe = GetStdHandle(STD_INPUT_HANDLE);
h_oldwritePipe = GetStdHandle(STD_OUTPUT_HANDLE);
SetStdHandle(STD_INPUT_HANDLE, h_readPipe[0]);
SetStdHandle(STD_OUTPUT_HANDLE, h_writePipe[1]);
inheritHandles = TRUE;
}
// create the process
STARTUPINFO si;
wxZeroMemory(si);
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
if ( ::CreateProcess(
NULL, // application name (use only cmd line)
(wxChar *)command.c_str(), // full command line
NULL, // security attributes: defaults for both
NULL, // the process and its main thread
inheritHandles, // don't inherit handles
CREATE_DEFAULT_ERROR_MODE |
CREATE_SUSPENDED, // flags
NULL, // environment (use the same)
NULL, // current directory (use the same)
&si, // startup info (unused here)
&pi // process info
) == 0 )
{
if (inheritHandles) {
::CloseHandle(h_writePipe[0]);
::CloseHandle(h_writePipe[1]);
::CloseHandle(h_readPipe[0]);
::CloseHandle(h_readPipe[1]);
}
wxLogSysError(_("Execution of command '%s' failed"), command.c_str());
return 0;
}
// Restore the old stdio handles
if (inheritHandles) {
SetStdHandle(STD_INPUT_HANDLE, h_oldreadPipe);
SetStdHandle(STD_OUTPUT_HANDLE, h_oldwritePipe);
::CloseHandle(h_writePipe[1]);
::CloseHandle(h_readPipe[0]);
// We can now initialize the wxStreams
wxInputStream *processOutput = new wxPipeInputStream(h_writePipe[0]);
wxOutputStream *processInput = new wxPipeOutputStream(h_readPipe[1]);
handler->SetPipeStreams(processOutput, processInput);
}
// register the class for the hidden window used for the notifications
if ( !gs_classForHiddenWindow )
{
gs_classForHiddenWindow = _T("wxHiddenWindow");
WNDCLASS wndclass;
wxZeroMemory(wndclass);
wndclass.lpfnWndProc = (WNDPROC)wxExecuteWindowCbk;
wndclass.hInstance = wxGetInstance();
wndclass.lpszClassName = gs_classForHiddenWindow;
if ( !::RegisterClass(&wndclass) )
{
wxLogLastError("RegisterClass(hidden window)");
}
}
// create a hidden window to receive notification about process
// termination
HWND hwnd = ::CreateWindow(gs_classForHiddenWindow, NULL,
WS_OVERLAPPEDWINDOW,
0, 0, 0, 0, NULL,
(HMENU)NULL, wxGetInstance(), 0);
wxASSERT_MSG( hwnd, wxT("can't create a hidden window for wxExecute") );
// Alloc data
wxExecuteData *data = new wxExecuteData;
data->hProcess = pi.hProcess;
data->dwProcessId = pi.dwProcessId;
data->hWnd = hwnd;
data->state = sync;
if ( sync )
{
wxASSERT_MSG( !handler, wxT("wxProcess param ignored for sync execution") );
data->handler = NULL;
}
else
{
// may be NULL or not
data->handler = handler;
}
DWORD tid;
HANDLE hThread = ::CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)wxExecuteThread,
(void *)data,
0,
&tid);
// resume process we created now - whether the thread creation succeeded or
// not
if ( ::ResumeThread(pi.hThread) == (DWORD)-1 )
{
// ignore it - what can we do?
wxLogLastError("ResumeThread in wxExecute");
}
// close unneeded handle
if ( !::CloseHandle(pi.hThread) )
wxLogLastError("CloseHandle(hThread)");
if ( !hThread )
{
wxLogLastError("CreateThread in wxExecute");
DestroyWindow(hwnd);
delete data;
// the process still started up successfully...
return pi.dwProcessId;
}
#if wxUSE_IPC
// second part of DDE hack: now establish the DDE conversation with the
// just launched process
if ( !!ddeServer )
{
wxDDEClient client;
wxConnectionBase *conn = client.MakeConnection(_T(""),
ddeServer,
ddeTopic);
if ( !conn || !conn->Execute(ddeCommand) )
{
wxLogError(_("Couldn't launch DDE server '%s'."), command.c_str());
}
}
#endif // wxUSE_IPC
if ( !sync )
{
// clean up will be done when the process terminates
// return the pid
return pi.dwProcessId;
}
// waiting until command executed (disable everything while doing it)
#if wxUSE_GUI
wxBeginBusyCursor();
wxEnableTopLevelWindows(FALSE);
#endif // wxUSE_GUI
while ( data->state )
wxYield();
#if wxUSE_GUI
wxEnableTopLevelWindows(TRUE);
wxEndBusyCursor();
#endif // wxUSE_GUI
DWORD dwExitCode = data->dwExitCode;
delete data;
// return the exit code
return dwExitCode;
#endif // 0/1
#else // Win16
long instanceID = WinExec((LPCSTR) WXSTRINGCAST command, SW_SHOW);
if (instanceID < 32) return(0);
if (sync) {
int running;
do {
wxYield();
running = GetModuleUsage((HINSTANCE)instanceID);
} while (running);
}
return(instanceID);
#endif // Win16/32
}
long wxExecute(char **argv, bool sync, wxProcess *handler)
{
wxString command;
while ( *argv != NULL )
{
command << *argv++ << ' ';
}
command.RemoveLast();
return wxExecute(command, sync, handler);
}
// ----------------------------------------------------------------------------
// Metafile helpers
// ----------------------------------------------------------------------------
extern void PixelToHIMETRIC(LONG *x, LONG *y)
{
ScreenHDC hdcRef;
int iWidthMM = GetDeviceCaps(hdcRef, HORZSIZE),
iHeightMM = GetDeviceCaps(hdcRef, VERTSIZE),
iWidthPels = GetDeviceCaps(hdcRef, HORZRES),
iHeightPels = GetDeviceCaps(hdcRef, VERTRES);
*x *= (iWidthMM * 100);
*x /= iWidthPels;
*y *= (iHeightMM * 100);
*y /= iHeightPels;
}
extern void HIMETRICToPixel(LONG *x, LONG *y)
{
ScreenHDC hdcRef;
int iWidthMM = GetDeviceCaps(hdcRef, HORZSIZE),
iHeightMM = GetDeviceCaps(hdcRef, VERTSIZE),
iWidthPels = GetDeviceCaps(hdcRef, HORZRES),
iHeightPels = GetDeviceCaps(hdcRef, VERTRES);
*x *= iWidthPels;
*x /= (iWidthMM * 100);
*y *= iHeightPels;
*y /= (iHeightMM * 100);
}

View File

@@ -1,771 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: utilsunx.cpp
// Purpose: generic Unix implementation of many wx functions
// Author: Vadim Zeitlin
// Id: $Id$
// Copyright: (c) 1998 Robert Roebling, Vadim Zeitlin
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "wx/defs.h"
#include "wx/string.h"
#include "wx/intl.h"
#include "wx/log.h"
#include "wx/utils.h"
#include "wx/process.h"
#include "wx/thread.h"
#include "wx/stream.h"
#if wxUSE_GUI
#include "wx/unix/execute.h"
#endif
#include <stdarg.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <pwd.h>
#include <errno.h>
#include <netdb.h>
#include <signal.h>
#include <fcntl.h> // for O_WRONLY and friends
#include <time.h> // nanosleep() and/or usleep()
#include <ctype.h> // isspace()
#include <sys/time.h> // needed for FD_SETSIZE
#ifdef HAVE_UNAME
#include <sys/utsname.h> // for uname()
#endif // HAVE_UNAME
// ----------------------------------------------------------------------------
// conditional compilation
// ----------------------------------------------------------------------------
// many versions of Unices have this function, but it is not defined in system
// headers - please add your system here if it is the case for your OS.
// SunOS < 5.6 (i.e. Solaris < 2.6) and DG-UX are like this.
#if !defined(HAVE_USLEEP) && \
(defined(__SUN__) && !defined(__SunOs_5_6) && \
!defined(__SunOs_5_7) && !defined(__SUNPRO_CC)) || \
defined(__osf__) || defined(__EMX__)
extern "C"
{
#ifdef __SUN__
int usleep(unsigned int usec);
#else // !Sun
#ifdef __EMX__
/* I copied this from the XFree86 diffs. AV. */
#define INCL_DOSPROCESS
#include <os2.h>
inline void usleep(unsigned long delay)
{
DosSleep(delay ? (delay/1000l) : 1l);
}
#else // !Sun && !EMX
void usleep(unsigned long usec);
#endif
#endif // Sun/EMX/Something else
};
#define HAVE_USLEEP 1
#endif // Unices without usleep()
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// sleeping
// ----------------------------------------------------------------------------
void wxSleep(int nSecs)
{
sleep(nSecs);
}
void wxUsleep(unsigned long milliseconds)
{
#if defined(HAVE_NANOSLEEP)
timespec tmReq;
tmReq.tv_sec = (time_t)(milliseconds / 1000);
tmReq.tv_nsec = (milliseconds % 1000) * 1000 * 1000;
// we're not interested in remaining time nor in return value
(void)nanosleep(&tmReq, (timespec *)NULL);
#elif defined(HAVE_USLEEP)
// uncomment this if you feel brave or if you are sure that your version
// of Solaris has a safe usleep() function but please notice that usleep()
// is known to lead to crashes in MT programs in Solaris 2.[67] and is not
// documented as MT-Safe
#if defined(__SUN__) && wxUSE_THREADS
#error "usleep() cannot be used in MT programs under Solaris."
#endif // Sun
usleep(milliseconds * 1000); // usleep(3) wants microseconds
#elif defined(HAVE_SLEEP)
// under BeOS sleep() takes seconds (what about other platforms, if any?)
sleep(milliseconds * 1000);
#else // !sleep function
#error "usleep() or nanosleep() function required for wxUsleep"
#endif // sleep function
}
// ----------------------------------------------------------------------------
// process management
// ----------------------------------------------------------------------------
int wxKill(long pid, wxSignal sig)
{
return kill((pid_t)pid, (int)sig);
}
#define WXEXECUTE_NARGS 127
long wxExecute( const wxString& command, bool sync, wxProcess *process )
{
wxCHECK_MSG( !command.IsEmpty(), 0, wxT("can't exec empty command") );
int argc = 0;
wxChar *argv[WXEXECUTE_NARGS];
wxString argument;
const wxChar *cptr = command.c_str();
wxChar quotechar = wxT('\0'); // is arg quoted?
bool escaped = FALSE;
// split the command line in arguments
do
{
argument=wxT("");
quotechar = wxT('\0');
// eat leading whitespace:
while ( wxIsspace(*cptr) )
cptr++;
if ( *cptr == wxT('\'') || *cptr == wxT('"') )
quotechar = *cptr++;
do
{
if ( *cptr == wxT('\\') && ! escaped )
{
escaped = TRUE;
cptr++;
continue;
}
// all other characters:
argument += *cptr++;
escaped = FALSE;
// have we reached the end of the argument?
if ( (*cptr == quotechar && ! escaped)
|| (quotechar == wxT('\0') && wxIsspace(*cptr))
|| *cptr == wxT('\0') )
{
wxASSERT_MSG( argc < WXEXECUTE_NARGS,
wxT("too many arguments in wxExecute") );
argv[argc] = new wxChar[argument.length() + 1];
wxStrcpy(argv[argc], argument.c_str());
argc++;
// if not at end of buffer, swallow last character:
if(*cptr)
cptr++;
break; // done with this one, start over
}
} while(*cptr);
} while(*cptr);
argv[argc] = NULL;
// do execute the command
long lRc = wxExecute(argv, sync, process);
// clean up
argc = 0;
while( argv[argc] )
delete [] argv[argc++];
return lRc;
}
bool wxShell(const wxString& command)
{
wxString cmd;
if ( !!command )
cmd.Printf(wxT("xterm -e %s"), command.c_str());
else
cmd = command;
return wxExecute(cmd) != 0;
}
#if wxUSE_GUI
void wxHandleProcessTermination(wxEndProcessData *proc_data)
{
int pid = (proc_data->pid > 0) ? proc_data->pid : -(proc_data->pid);
// waitpid is POSIX so should be available everywhere, however on older
// systems wait() might be used instead in a loop (until the right pid
// terminates)
int status = 0;
int rc;
// wait for child termination and if waitpid() was interrupted, try again
do
{
rc = waitpid(pid, &status, 0);
}
while ( rc == -1 && errno == EINTR );
if( rc == -1 || ! (WIFEXITED(status) || WIFSIGNALED(status)) )
{
wxLogSysError(_("Waiting for subprocess termination failed"));
/* AFAIK, this can only happen if something went wrong within
wxGTK, i.e. due to a race condition or some serious bug.
After having fixed the order of statements in
GTK_EndProcessDetector(). (KB)
*/
}
else
{
// notify user about termination if required
if (proc_data->process)
{
proc_data->process->OnTerminate(proc_data->pid,
WEXITSTATUS(status));
}
// clean up
if ( proc_data->pid > 0 )
{
delete proc_data;
}
else
{
// wxExecute() will know about it
proc_data->exitcode = status;
proc_data->pid = 0;
}
}
}
#endif // wxUSE_GUI
#if wxUSE_GUI
#define WXUNUSED_UNLESS_GUI(p) p
#else
#define WXUNUSED_UNLESS_GUI(p)
#endif
// New wxStream classes to clean up the data when the process terminates
#if wxUSE_GUI
class wxProcessFileInputStream: public wxInputStream {
public:
wxProcessFileInputStream(int fd);
~wxProcessFileInputStream();
protected:
size_t OnSysRead(void *buffer, size_t bufsize);
protected:
int m_fd;
};
class wxProcessFileOutputStream: public wxOutputStream {
public:
wxProcessFileOutputStream(int fd);
~wxProcessFileOutputStream();
protected:
size_t OnSysWrite(const void *buffer, size_t bufsize);
protected:
int m_fd;
};
wxProcessFileInputStream::wxProcessFileInputStream(int fd)
{
m_fd = fd;
}
wxProcessFileInputStream::~wxProcessFileInputStream()
{
close(m_fd);
}
size_t wxProcessFileInputStream::OnSysRead(void *buffer, size_t bufsize)
{
int ret;
ret = read(m_fd, buffer, bufsize);
m_lasterror = wxSTREAM_NOERROR;
if (ret == 0)
m_lasterror = wxSTREAM_EOF;
if (ret == -1) {
m_lasterror = wxSTREAM_READ_ERROR;
ret = 0;
}
return ret;
}
wxProcessFileOutputStream::wxProcessFileOutputStream(int fd)
{
m_fd = fd;
}
wxProcessFileOutputStream::~wxProcessFileOutputStream()
{
close(m_fd);
}
size_t wxProcessFileOutputStream::OnSysWrite(const void *buffer, size_t bufsize)
{
int ret;
ret = write(m_fd, buffer, bufsize);
m_lasterror = wxSTREAM_NOERROR;
if (ret == -1) {
m_lasterror = wxSTREAM_WRITE_ERROR;
ret = 0;
}
return ret;
}
#endif
long wxExecute(wxChar **argv,
bool sync,
wxProcess * WXUNUSED_UNLESS_GUI(process))
{
wxCHECK_MSG( *argv, 0, wxT("can't exec empty command") );
#if wxUSE_UNICODE
int mb_argc = 0;
char *mb_argv[WXEXECUTE_NARGS];
while (argv[mb_argc])
{
wxWX2MBbuf mb_arg = wxConvertWX2MB(argv[mb_argc]);
mb_argv[mb_argc] = strdup(mb_arg);
mb_argc++;
}
mb_argv[mb_argc] = (char *) NULL;
// this macro will free memory we used above
#define ARGS_CLEANUP \
for ( mb_argc = 0; mb_argv[mb_argc]; mb_argc++ ) \
free(mb_argv[mb_argc])
#else // ANSI
// no need for cleanup
#define ARGS_CLEANUP
wxChar **mb_argv = argv;
#endif // Unicode/ANSI
#if wxUSE_GUI
// create pipes
int end_proc_detect[2];
if (pipe(end_proc_detect) == -1)
{
wxLogSysError( _("Pipe creation failed") );
ARGS_CLEANUP;
return 0;
}
#endif // wxUSE_GUI
#if wxUSE_GUI
int in_pipe[2] = { -1, -1 };
int out_pipe[2] = { -1, -1 };
// Only asynchronous mode is interresting
if (!sync && process && process->NeedPipe())
{
if (pipe(in_pipe) == -1 || pipe(out_pipe) == -1)
{
/* Free fds */
close(end_proc_detect[0]);
close(end_proc_detect[1]);
wxLogSysError( _("Pipe creation failed (Console pipes)") );
ARGS_CLEANUP;
return 0;
}
}
#endif // wxUSE_GUI
// fork the process
#ifdef HAVE_VFORK
pid_t pid = vfork();
#else
pid_t pid = fork();
#endif
if (pid == -1)
{
#if wxUSE_GUI
close(end_proc_detect[0]);
close(end_proc_detect[1]);
close(in_pipe[0]);
close(in_pipe[1]);
close(out_pipe[0]);
close(out_pipe[1]);
#endif
wxLogSysError( _("Fork failed") );
ARGS_CLEANUP;
return 0;
}
else if (pid == 0)
{
#if wxUSE_GUI
// we're in child
close(end_proc_detect[0]); // close reading side
#endif // wxUSE_GUI
// These three lines close the open file descriptors to to avoid any
// input/output which might block the process or irritate the user. If
// one wants proper IO for the subprocess, the right thing to do is
// to start an xterm executing it.
if (sync == 0)
{
// leave stderr opened, it won't do any hurm
for ( int fd = 0; fd < FD_SETSIZE; fd++ )
{
#if wxUSE_GUI
if ( fd == end_proc_detect[1] || fd == in_pipe[0] || fd == out_pipe[1] )
continue;
#endif // wxUSE_GUI
if ( fd != STDERR_FILENO )
close(fd);
}
}
// Fake a console by duplicating pipes
#if wxUSE_GUI
if (in_pipe[0] != -1) {
dup2(in_pipe[0], STDIN_FILENO);
dup2(out_pipe[1], STDOUT_FILENO);
close(in_pipe[0]);
close(out_pipe[1]);
}
#endif // wxUSE_GUI
#if 0
close(STDERR_FILENO);
// some programs complain about stderr not being open, so redirect
// them:
open("/dev/null", O_RDONLY); // stdin
open("/dev/null", O_WRONLY); // stdout
open("/dev/null", O_WRONLY); // stderr
#endif
execvp (*mb_argv, mb_argv);
// there is no return after successful exec()
wxFprintf(stderr, _("Can't execute '%s'\n"), *argv);
_exit(-1);
}
else
{
#if wxUSE_GUI
wxEndProcessData *data = new wxEndProcessData;
ARGS_CLEANUP;
if ( sync )
{
wxASSERT_MSG( !process, wxT("wxProcess param ignored for sync exec") );
data->process = NULL;
// sync execution: indicate it by negating the pid
data->pid = -pid;
data->tag = wxAddProcessCallback(data, end_proc_detect[0]);
// we're in parent
close(end_proc_detect[1]); // close writing side
// it will be set to 0 from GTK_EndProcessDetector
while (data->pid != 0)
wxYield();
int exitcode = data->exitcode;
delete data;
return exitcode;
}
else
{
// pipe initialization: construction of the wxStreams
if (process && process->NeedPipe()) {
// These two streams are relative to this process.
wxOutputStream *my_output_stream;
wxInputStream *my_input_stream;
my_output_stream = new wxProcessFileOutputStream(in_pipe[1]);
my_input_stream = new wxProcessFileInputStream(out_pipe[0]);
close(in_pipe[0]); // close reading side
close(out_pipe[1]); // close writing side
process->SetPipeStreams(my_input_stream, my_output_stream);
}
// async execution, nothing special to do - caller will be
// notified about the process termination if process != NULL, data
// will be deleted in GTK_EndProcessDetector
data->process = process;
data->pid = pid;
data->tag = wxAddProcessCallback(data, end_proc_detect[0]);
// we're in parent
close(end_proc_detect[1]); // close writing side
return pid;
}
#else // !wxUSE_GUI
wxASSERT_MSG( sync, wxT("async execution not supported yet") );
int exitcode = 0;
if ( waitpid(pid, &exitcode, 0) == -1 || !WIFEXITED(exitcode) )
{
wxLogSysError(_("Waiting for subprocess termination failed"));
}
return exitcode;
#endif // wxUSE_GUI
}
return 0;
#undef ARGS_CLEANUP
}
// ----------------------------------------------------------------------------
// file and directory functions
// ----------------------------------------------------------------------------
const wxChar* wxGetHomeDir( wxString *home )
{
*home = wxGetUserHome( wxString() );
if ( home->IsEmpty() )
*home = wxT("/");
return home->c_str();
}
#if wxUSE_UNICODE
const wxMB2WXbuf wxGetUserHome( const wxString &user )
#else // just for binary compatibility -- there is no 'const' here
char *wxGetUserHome( const wxString &user )
#endif
{
struct passwd *who = (struct passwd *) NULL;
if ( !user )
{
wxChar *ptr;
if ((ptr = wxGetenv(wxT("HOME"))) != NULL)
{
return ptr;
}
if ((ptr = wxGetenv(wxT("USER"))) != NULL || (ptr = wxGetenv(wxT("LOGNAME"))) != NULL)
{
who = getpwnam(wxConvertWX2MB(ptr));
}
// We now make sure the the user exists!
if (who == NULL)
{
who = getpwuid(getuid());
}
}
else
{
who = getpwnam (user.mb_str());
}
return wxConvertMB2WX(who ? who->pw_dir : 0);
}
// ----------------------------------------------------------------------------
// network and user id routines
// ----------------------------------------------------------------------------
// retrieve either the hostname or FQDN depending on platform (caller must
// check whether it's one or the other, this is why this function is for
// private use only)
static bool wxGetHostNameInternal(wxChar *buf, int sz)
{
wxCHECK_MSG( buf, FALSE, wxT("NULL pointer in wxGetHostNameInternal") );
*buf = wxT('\0');
// we're using uname() which is POSIX instead of less standard sysinfo()
#if defined(HAVE_UNAME)
struct utsname uts;
bool ok = uname(&uts) != -1;
if ( ok )
{
wxStrncpy(buf, wxConvertMB2WX(uts.nodename), sz - 1);
buf[sz] = wxT('\0');
}
#elif defined(HAVE_GETHOSTNAME)
bool ok = gethostname(buf, sz) != -1;
#else // no uname, no gethostname
wxFAIL_MSG(wxT("don't know host name for this machine"));
bool ok = FALSE;
#endif // uname/gethostname
if ( !ok )
{
wxLogSysError(_("Cannot get the hostname"));
}
return ok;
}
bool wxGetHostName(wxChar *buf, int sz)
{
bool ok = wxGetHostNameInternal(buf, sz);
if ( ok )
{
// BSD systems return the FQDN, we only want the hostname, so extract
// it (we consider that dots are domain separators)
wxChar *dot = wxStrchr(buf, wxT('.'));
if ( dot )
{
// nuke it
*dot = wxT('\0');
}
}
return ok;
}
bool wxGetFullHostName(wxChar *buf, int sz)
{
bool ok = wxGetHostNameInternal(buf, sz);
if ( ok )
{
if ( !wxStrchr(buf, wxT('.')) )
{
struct hostent *host = gethostbyname(wxConvertWX2MB(buf));
if ( !host )
{
wxLogSysError(_("Cannot get the official hostname"));
ok = FALSE;
}
else
{
// the canonical name
wxStrncpy(buf, wxConvertMB2WX(host->h_name), sz);
}
}
//else: it's already a FQDN (BSD behaves this way)
}
return ok;
}
bool wxGetUserId(wxChar *buf, int sz)
{
struct passwd *who;
*buf = wxT('\0');
if ((who = getpwuid(getuid ())) != NULL)
{
wxStrncpy (buf, wxConvertMB2WX(who->pw_name), sz - 1);
return TRUE;
}
return FALSE;
}
bool wxGetUserName(wxChar *buf, int sz)
{
struct passwd *who;
*buf = wxT('\0');
if ((who = getpwuid (getuid ())) != NULL)
{
// pw_gecos field in struct passwd is not standard
#if HAVE_PW_GECOS
char *comma = strchr(who->pw_gecos, ',');
if (comma)
*comma = '\0'; // cut off non-name comment fields
wxStrncpy (buf, wxConvertMB2WX(who->pw_gecos), sz - 1);
#else // !HAVE_PW_GECOS
wxStrncpy (buf, wxConvertMB2WX(who->pw_name), sz - 1);
#endif // HAVE_PW_GECOS/!HAVE_PW_GECOS
return TRUE;
}
return FALSE;
}
wxString wxGetOsDescription()
{
#ifndef WXWIN_OS_DESCRIPTION
#error WXWIN_OS_DESCRIPTION should be defined in config.h by configure
#else
return WXWIN_OS_DESCRIPTION;
#endif
}
// ----------------------------------------------------------------------------
// error and debug output routines (deprecated, use wxLog)
// ----------------------------------------------------------------------------
void wxDebugMsg( const char *format, ... )
{
va_list ap;
va_start( ap, format );
vfprintf( stderr, format, ap );
fflush( stderr );
va_end(ap);
}
void wxError( const wxString &msg, const wxString &title )
{
wxFprintf( stderr, _("Error ") );
if (!title.IsNull()) wxFprintf( stderr, wxT("%s "), WXSTRINGCAST(title) );
if (!msg.IsNull()) wxFprintf( stderr, wxT(": %s"), WXSTRINGCAST(msg) );
wxFprintf( stderr, wxT(".\n") );
}
void wxFatalError( const wxString &msg, const wxString &title )
{
wxFprintf( stderr, _("Error ") );
if (!title.IsNull()) wxFprintf( stderr, wxT("%s "), WXSTRINGCAST(title) );
if (!msg.IsNull()) wxFprintf( stderr, wxT(": %s"), WXSTRINGCAST(msg) );
wxFprintf( stderr, wxT(".\n") );
exit(3); // the same exit code as for abort()
}