mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-09-20 12:59:31 +08:00
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:
@@ -1,4 +0,0 @@
|
||||
all:
|
||||
cd lib; make
|
||||
cd sample; make
|
||||
cd board; make
|
||||
@@ -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
|
||||
@@ -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@
|
||||
@@ -1,24 +0,0 @@
|
||||
/* XPM */
|
||||
static char * eject_xpm[] = {
|
||||
"15 16 5 1",
|
||||
" c None",
|
||||
". c #949594",
|
||||
"+ c #000000",
|
||||
"@ c #FFFFFF",
|
||||
"# c #8E8E8E",
|
||||
" . ",
|
||||
" .+@ ",
|
||||
" .+++@ ",
|
||||
" .+++++@ ",
|
||||
" .+++++++@ ",
|
||||
" .+++++++++@ ",
|
||||
" .+++++++++++@ ",
|
||||
".+############@",
|
||||
".@@@@@@@@@@@@@@",
|
||||
" ",
|
||||
"...............",
|
||||
".++++++++++++#@",
|
||||
".++++++++++++#@",
|
||||
".++++++++++++#@",
|
||||
".+############@",
|
||||
".@@@@@@@@@@@@@@"};
|
||||
@@ -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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
||||
NAME Minimal
|
||||
DESCRIPTION 'Minimal wxWindows application'
|
||||
EXETYPE WINDOWS
|
||||
CODE PRELOAD MOVEABLE DISCARDABLE
|
||||
DATA PRELOAD MOVEABLE MULTIPLE
|
||||
HEAPSIZE 4048
|
||||
STACKSIZE 16000
|
||||
@@ -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
|
||||
@@ -1,6 +0,0 @@
|
||||
mondrian ICON "mondrian.ico"
|
||||
#include "wx/msw/wx.rc"
|
||||
|
||||
#define MINIMAL_QUIT 1
|
||||
#define MINIMAL_ABOUT 102
|
||||
|
||||
@@ -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 |
@@ -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.
@@ -1,23 +0,0 @@
|
||||
/* XPM */
|
||||
static char * pause_xpm[] = {
|
||||
"13 15 5 1",
|
||||
" c None",
|
||||
". c #949594",
|
||||
"+ c #000000",
|
||||
"@ c #8E8E8E",
|
||||
"# c #FFFFFF",
|
||||
"...... ......",
|
||||
".+++@# .+++@#",
|
||||
".+++@# .+++@#",
|
||||
".+++@# .+++@#",
|
||||
".+++@# .+++@#",
|
||||
".+++@# .+++@#",
|
||||
".+++@# .+++@#",
|
||||
".+++@# .+++@#",
|
||||
".+++@# .+++@#",
|
||||
".+++@# .+++@#",
|
||||
".+++@# .+++@#",
|
||||
".+++@# .+++@#",
|
||||
".+++@# .+++@#",
|
||||
".+@@@# .+@@@#",
|
||||
".##### .#####"};
|
||||
@@ -1,23 +0,0 @@
|
||||
/* XPM */
|
||||
static char * play_back_xpm[] = {
|
||||
"13 15 5 1",
|
||||
" c None",
|
||||
". c #949594",
|
||||
"+ c #000000",
|
||||
"@ c #8E8E8E",
|
||||
"# c #FFFFFF",
|
||||
"...... ",
|
||||
".+++++. ",
|
||||
".++++++. ",
|
||||
".+++++++. ",
|
||||
".++++++++. ",
|
||||
".+++++++++. ",
|
||||
".++++++++++. ",
|
||||
".++++++++++@#",
|
||||
".+++++++++@# ",
|
||||
".++++++++@# ",
|
||||
".+++++++@# ",
|
||||
".++++++@# ",
|
||||
".+++++@# ",
|
||||
".+@@@@# ",
|
||||
".##### "};
|
||||
@@ -1,23 +0,0 @@
|
||||
/* XPM */
|
||||
static char * stop_back_xpm[] = {
|
||||
"13 15 5 1",
|
||||
" c None",
|
||||
". c #949594",
|
||||
"+ c #000000",
|
||||
"@ c #8E8E8E",
|
||||
"# c #FFFFFF",
|
||||
".............",
|
||||
".++++++++++@#",
|
||||
".++++++++++@#",
|
||||
".++++++++++@#",
|
||||
".++++++++++@#",
|
||||
".++++++++++@#",
|
||||
".++++++++++@#",
|
||||
".++++++++++@#",
|
||||
".++++++++++@#",
|
||||
".++++++++++@#",
|
||||
".++++++++++@#",
|
||||
".++++++++++@#",
|
||||
".++++++++++@#",
|
||||
".+@@@@@@@@@@#",
|
||||
".############"};
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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))
|
||||
@@ -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)));
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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)
|
||||
<<
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
@@ -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]);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user