* Added wxMMedia in the repository so people interrested in it can work on it

* WARNING! It is quite unstable on Windows and it doesn't work on Linux for
  the moment because I didn't finish fixing the CODEC stream.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@975 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Guilhem Lavaux
1998-11-09 18:37:38 +00:00
parent ea57084d10
commit 4d6306eb4d
54 changed files with 7666 additions and 0 deletions

1
utils/wxMMedia/Makefile Normal file
View File

@@ -0,0 +1 @@
include ../../setup/general/makeapp

View File

@@ -0,0 +1,38 @@
# WXXT base directory
WXBASEDIR=@WXBASEDIR@
# set the OS type for compilation
OS=@OS@
# compile a library only
RULE=gslib
# define common stuff
# define library name
LIB_TARGET=wxmmedia
LIB_MAJOR=2
LIB_MINOR=0
# define library sources
ADPCM_SRC=\
g711.cpp g721.cpp g723_24.cpp g723_40.cpp g72x.cpp
MMEDIA_SRC=\
mmdata.cpp mmfile.cpp mmsolve.cpp sndsnd.cpp sndfrmt.cpp sndpcm.o \
snduss.cpp sndfile.cpp sndwav.cpp mmriff.cpp vidbase.cpp vidxanm.cpp \
cdbase.cpp cdunix.cpp
LIB_SRC= $(ADPCM_SRC:%.cpp=adpcm/%.cpp) $(MMEDIA_SRC)
#define library objects
LIB_OBJ=\
$(LIB_SRC:%.cpp=%.o)
#additional things needed for compile
ADD_COMPILE= -I$(UTILS)/wxthread
all::
-mkdir -p adpcm
# include the definitions now
include ../../../template.mak

View File

@@ -0,0 +1,283 @@
/*
* 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
*/
/*
* g711.c
*
* u-law, A-law and linear PCM conversions.
*/
#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
#define QUANT_MASK (0xf) /* Quantization field mask. */
#define NSEGS (8) /* Number of A-law segments. */
#define SEG_SHIFT (4) /* Left shift for segment number. */
#define SEG_MASK (0x70) /* Segment field mask. */
static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,
0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
/* copy from CCITT G.711 specifications */
unsigned char _u2a[128] = { /* u- to A-law conversions */
1, 1, 2, 2, 3, 3, 4, 4,
5, 5, 6, 6, 7, 7, 8, 8,
9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24,
25, 27, 29, 31, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44,
46, 48, 49, 50, 51, 52, 53, 54,
55, 56, 57, 58, 59, 60, 61, 62,
64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79,
81, 82, 83, 84, 85, 86, 87, 88,
89, 90, 91, 92, 93, 94, 95, 96,
97, 98, 99, 100, 101, 102, 103, 104,
105, 106, 107, 108, 109, 110, 111, 112,
113, 114, 115, 116, 117, 118, 119, 120,
121, 122, 123, 124, 125, 126, 127, 128};
unsigned char _a2u[128] = { /* A- to u-law conversions */
1, 3, 5, 7, 9, 11, 13, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
32, 32, 33, 33, 34, 34, 35, 35,
36, 37, 38, 39, 40, 41, 42, 43,
44, 45, 46, 47, 48, 48, 49, 49,
50, 51, 52, 53, 54, 55, 56, 57,
58, 59, 60, 61, 62, 63, 64, 64,
65, 66, 67, 68, 69, 70, 71, 72,
73, 74, 75, 76, 77, 78, 79, 79,
80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99, 100, 101, 102, 103,
104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 122, 123, 124, 125, 126, 127};
static int
search(
int val,
short *table,
int size)
{
int i;
for (i = 0; i < size; i++) {
if (val <= *table++)
return (i);
}
return (size);
}
/*
* linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
*
* linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
*
* Linear Input Code Compressed Code
* ------------------------ ---------------
* 0000000wxyza 000wxyz
* 0000001wxyza 001wxyz
* 000001wxyzab 010wxyz
* 00001wxyzabc 011wxyz
* 0001wxyzabcd 100wxyz
* 001wxyzabcde 101wxyz
* 01wxyzabcdef 110wxyz
* 1wxyzabcdefg 111wxyz
*
* For further information see John C. Bellamy's Digital Telephony, 1982,
* John Wiley & Sons, pps 98-111 and 472-476.
*/
unsigned char
linear2alaw(
int pcm_val) /* 2's complement (16-bit range) */
{
int mask;
int seg;
unsigned char aval;
if (pcm_val >= 0) {
mask = 0xD5; /* sign (7th) bit = 1 */
} else {
mask = 0x55; /* sign bit = 0 */
pcm_val = -pcm_val - 8;
}
/* Convert the scaled magnitude to segment number. */
seg = search(pcm_val, seg_end, 8);
/* Combine the sign, segment, and quantization bits. */
if (seg >= 8) /* out of range, return maximum value. */
return (0x7F ^ mask);
else {
aval = seg << SEG_SHIFT;
if (seg < 2)
aval |= (pcm_val >> 4) & QUANT_MASK;
else
aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
return (aval ^ mask);
}
}
/*
* alaw2linear() - Convert an A-law value to 16-bit linear PCM
*
*/
int
alaw2linear(
unsigned char a_val)
{
int t;
int seg;
a_val ^= 0x55;
t = (a_val & QUANT_MASK) << 4;
seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
switch (seg) {
case 0:
t += 8;
break;
case 1:
t += 0x108;
break;
default:
t += 0x108;
t <<= seg - 1;
}
return ((a_val & SIGN_BIT) ? t : -t);
}
#define BIAS (0x84) /* Bias for linear code. */
/*
* linear2ulaw() - Convert a linear PCM value to u-law
*
* In order to simplify the encoding process, the original linear magnitude
* is biased by adding 33 which shifts the encoding range from (0 - 8158) to
* (33 - 8191). The result can be seen in the following encoding table:
*
* Biased Linear Input Code Compressed Code
* ------------------------ ---------------
* 00000001wxyza 000wxyz
* 0000001wxyzab 001wxyz
* 000001wxyzabc 010wxyz
* 00001wxyzabcd 011wxyz
* 0001wxyzabcde 100wxyz
* 001wxyzabcdef 101wxyz
* 01wxyzabcdefg 110wxyz
* 1wxyzabcdefgh 111wxyz
*
* Each biased linear code has a leading 1 which identifies the segment
* number. The value of the segment number is equal to 7 minus the number
* of leading 0's. The quantization interval is directly available as the
* four bits wxyz. * The trailing bits (a - h) are ignored.
*
* Ordinarily the complement of the resulting code word is used for
* transmission, and so the code word is complemented before it is returned.
*
* For further information see John C. Bellamy's Digital Telephony, 1982,
* John Wiley & Sons, pps 98-111 and 472-476.
*/
unsigned char
linear2ulaw(
int pcm_val) /* 2's complement (16-bit range) */
{
int mask;
int seg;
unsigned char uval;
/* Get the sign and the magnitude of the value. */
if (pcm_val < 0) {
pcm_val = BIAS - pcm_val;
mask = 0x7F;
} else {
pcm_val += BIAS;
mask = 0xFF;
}
/* Convert the scaled magnitude to segment number. */
seg = search(pcm_val, seg_end, 8);
/*
* Combine the sign, segment, quantization bits;
* and complement the code word.
*/
if (seg >= 8) /* out of range, return maximum value. */
return (0x7F ^ mask);
else {
uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
return (uval ^ mask);
}
}
/*
* ulaw2linear() - Convert a u-law value to 16-bit linear PCM
*
* First, a biased linear code is derived from the code word. An unbiased
* output can then be obtained by subtracting 33 from the biased code.
*
* Note that this function expects to be passed the complement of the
* original code word. This is in keeping with ISDN conventions.
*/
int
ulaw2linear(
unsigned char u_val)
{
int t;
/* Complement to obtain normal u-law value. */
u_val = ~u_val;
/*
* Extract and bias the quantization bits. Then
* shift up by the segment number and subtract out the bias.
*/
t = ((u_val & QUANT_MASK) << 3) + BIAS;
t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
}
/* A-law to u-law conversion */
unsigned char
alaw2ulaw(
unsigned char aval)
{
aval &= 0xff;
return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
(0x7F ^ _a2u[aval ^ 0x55]));
}
/* u-law to A-law conversion */
unsigned char
ulaw2alaw(
unsigned char uval)
{
uval &= 0xff;
return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
(0x55 ^ (_u2a[0x7F ^ uval] - 1)));
}

View File

@@ -0,0 +1,173 @@
/*
* 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
*/
/*
* g721.c
*
* Description:
*
* g721_encoder(), g721_decoder()
*
* These routines comprise an implementation of the CCITT G.721 ADPCM
* coding algorithm. Essentially, this implementation is identical to
* the bit level description except for a few deviations which
* take advantage of work station attributes, such as hardware 2's
* complement arithmetic and large memory. Specifically, certain time
* consuming operations such as multiplications are replaced
* with lookup tables and software 2's complement operations are
* replaced with hardware 2's complement.
*
* The deviation from the bit level specification (lookup tables)
* preserves the bit level performance specifications.
*
* As outlined in the G.721 Recommendation, the algorithm is broken
* down into modules. Each section of code below is preceded by
* the name of the module which it is implementing.
*
*/
#include "g72x.h"
static short qtab_721[7] = {-124, 80, 178, 246, 300, 349, 400};
/*
* Maps G.721 code word to reconstructed scale factor normalized log
* magnitude values.
*/
static short _dqlntab[16] = {-2048, 4, 135, 213, 273, 323, 373, 425,
425, 373, 323, 273, 213, 135, 4, -2048};
/* Maps G.721 code word to log of scale factor multiplier. */
static short _witab[16] = {-12, 18, 41, 64, 112, 198, 355, 1122,
1122, 355, 198, 112, 64, 41, 18, -12};
/*
* Maps G.721 code words to a set of values whose long and short
* term averages are computed and then compared to give an indication
* how stationary (steady state) the signal is.
*/
static short _fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00,
0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0};
/*
* g721_encoder()
*
* Encodes the input vale of linear PCM, A-law or u-law data sl and returns
* the resulting code. -1 is returned for unknown input coding value.
*/
int
g721_encoder(
int sl,
int in_coding,
struct g72x_state *state_ptr)
{
short sezi, se, sez; /* ACCUM */
short d; /* SUBTA */
short sr; /* ADDB */
short y; /* MIX */
short dqsez; /* ADDC */
short dq, i;
switch (in_coding) { /* linearize input sample to 14-bit PCM */
case AUDIO_ENCODING_ALAW:
sl = alaw2linear(sl) >> 2;
break;
case AUDIO_ENCODING_ULAW:
sl = ulaw2linear(sl) >> 2;
break;
case AUDIO_ENCODING_LINEAR:
sl = ((short)sl) >> 2; /* 14-bit dynamic range */
break;
default:
return (-1);
}
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
se = (sezi + predictor_pole(state_ptr)) >> 1; /* estimated signal */
d = sl - se; /* estimation difference */
/* quantize the prediction difference */
y = step_size(state_ptr); /* quantizer step size */
i = quantize(d, y, qtab_721, 7); /* i = ADPCM code */
dq = reconstruct(i & 8, _dqlntab[i], y); /* quantized est diff */
sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconst. signal */
dqsez = sr + sez - se; /* pole prediction diff. */
update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
return (i);
}
/*
* g721_decoder()
*
* Description:
*
* Decodes a 4-bit code of G.721 encoded data of i and
* returns the resulting linear PCM, A-law or u-law value.
* return -1 for unknown out_coding value.
*/
int
g721_decoder(
int i,
int out_coding,
struct g72x_state *state_ptr)
{
short sezi, sei, sez, se; /* ACCUM */
short y; /* MIX */
short sr; /* ADDB */
short dq;
short dqsez;
i &= 0x0f; /* mask to get proper bits */
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
y = step_size(state_ptr); /* dynamic quantizer step size */
dq = reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */
sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq; /* reconst. signal */
dqsez = sr - se + sez; /* pole prediction diff. */
update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
switch (out_coding) {
case AUDIO_ENCODING_ALAW:
return (tandem_adjust_alaw(sr, se, y, i, 8, qtab_721));
case AUDIO_ENCODING_ULAW:
return (tandem_adjust_ulaw(sr, se, y, i, 8, qtab_721));
case AUDIO_ENCODING_LINEAR:
return (sr << 2); /* sr was 14-bit dynamic range */
default:
return (-1);
}
}

View File

@@ -0,0 +1,158 @@
/*
* 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 "g72x.h"
/*
* Maps G.723_24 code word to reconstructed scale factor normalized log
* magnitude values.
*/
static short _dqlntab[8] = {-2048, 135, 273, 373, 373, 273, 135, -2048};
/* Maps G.723_24 code word to log of scale factor multiplier. */
static short _witab[8] = {-128, 960, 4384, 18624, 18624, 4384, 960, -128};
/*
* Maps G.723_24 code words to a set of values whose long and short
* term averages are computed and then compared to give an indication
* how stationary (steady state) the signal is.
*/
static short _fitab[8] = {0, 0x200, 0x400, 0xE00, 0xE00, 0x400, 0x200, 0};
static short qtab_723_24[3] = {8, 218, 331};
/*
* g723_24_encoder()
*
* Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code.
* Returns -1 if invalid input coding value.
*/
int
g723_24_encoder(
int sl,
int in_coding,
struct g72x_state *state_ptr)
{
short sei, sezi, se, sez; /* ACCUM */
short d; /* SUBTA */
short y; /* MIX */
short sr; /* ADDB */
short dqsez; /* ADDC */
short dq, i;
switch (in_coding) { /* linearize input sample to 14-bit PCM */
case AUDIO_ENCODING_ALAW:
sl = alaw2linear(sl) >> 2;
break;
case AUDIO_ENCODING_ULAW:
sl = ulaw2linear(sl) >> 2;
break;
case AUDIO_ENCODING_LINEAR:
sl = ((short)sl) >> 2; /* sl of 14-bit dynamic range */
break;
default:
return (-1);
}
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
d = sl - se; /* d = estimation diff. */
/* quantize prediction difference d */
y = step_size(state_ptr); /* quantizer step size */
i = quantize(d, y, qtab_723_24, 3); /* i = ADPCM code */
dq = reconstruct(i & 4, _dqlntab[i], y); /* quantized diff. */
sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconstructed signal */
dqsez = sr + sez - se; /* pole prediction diff. */
update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
return (i);
}
/*
* g723_24_decoder()
*
* Decodes a 3-bit CCITT G.723_24 ADPCM code and returns
* the resulting 16-bit linear PCM, A-law or u-law sample value.
* -1 is returned if the output coding is unknown.
*/
int
g723_24_decoder(
int i,
int out_coding,
struct g72x_state *state_ptr)
{
short sezi, sei, sez, se; /* ACCUM */
short y; /* MIX */
short sr; /* ADDB */
short dq;
short dqsez;
i &= 0x07; /* mask to get proper bits */
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
y = step_size(state_ptr); /* adaptive quantizer step size */
dq = reconstruct(i & 0x04, _dqlntab[i], y); /* unquantize pred diff */
sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); /* reconst. signal */
dqsez = sr - se + sez; /* pole prediction diff. */
update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
switch (out_coding) {
case AUDIO_ENCODING_ALAW:
return (tandem_adjust_alaw(sr, se, y, i, 4, qtab_723_24));
case AUDIO_ENCODING_ULAW:
return (tandem_adjust_ulaw(sr, se, y, i, 4, qtab_723_24));
case AUDIO_ENCODING_LINEAR:
return (sr << 2); /* sr was of 14-bit dynamic range */
default:
return (-1);
}
}

View File

@@ -0,0 +1,178 @@
/*
* 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 "g72x.h"
/*
* Maps G.723_40 code word to ructeconstructed scale factor normalized log
* magnitude values.
*/
static short _dqlntab[32] = {-2048, -66, 28, 104, 169, 224, 274, 318,
358, 395, 429, 459, 488, 514, 539, 566,
566, 539, 514, 488, 459, 429, 395, 358,
318, 274, 224, 169, 104, 28, -66, -2048};
/* Maps G.723_40 code word to log of scale factor multiplier. */
static short _witab[32] = {448, 448, 768, 1248, 1280, 1312, 1856, 3200,
4512, 5728, 7008, 8960, 11456, 14080, 16928, 22272,
22272, 16928, 14080, 11456, 8960, 7008, 5728, 4512,
3200, 1856, 1312, 1280, 1248, 768, 448, 448};
/*
* Maps G.723_40 code words to a set of values whose long and short
* term averages are computed and then compared to give an indication
* how stationary (steady state) the signal is.
*/
static short _fitab[32] = {0, 0, 0, 0, 0, 0x200, 0x200, 0x200,
0x200, 0x200, 0x400, 0x600, 0x800, 0xA00, 0xC00, 0xC00,
0xC00, 0xC00, 0xA00, 0x800, 0x600, 0x400, 0x200, 0x200,
0x200, 0x200, 0x200, 0, 0, 0, 0, 0};
static short qtab_723_40[15] = {-122, -16, 68, 139, 198, 250, 298, 339,
378, 413, 445, 475, 502, 528, 553};
/*
* g723_40_encoder()
*
* Encodes a 16-bit linear PCM, A-law or u-law input sample and retuens
* the resulting 5-bit CCITT G.723 40Kbps code.
* Returns -1 if the input coding value is invalid.
*/
int
g723_40_encoder(
int sl,
int in_coding,
struct g72x_state *state_ptr)
{
short sei, sezi, se, sez; /* ACCUM */
short d; /* SUBTA */
short y; /* MIX */
short sr; /* ADDB */
short dqsez; /* ADDC */
short dq, i;
switch (in_coding) { /* linearize input sample to 14-bit PCM */
case AUDIO_ENCODING_ALAW:
sl = alaw2linear(sl) >> 2;
break;
case AUDIO_ENCODING_ULAW:
sl = ulaw2linear(sl) >> 2;
break;
case AUDIO_ENCODING_LINEAR:
sl = ((short) sl) >> 2; /* sl of 14-bit dynamic range */
break;
default:
return (-1);
}
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
d = sl - se; /* d = estimation difference */
/* quantize prediction difference */
y = step_size(state_ptr); /* adaptive quantizer step size */
i = quantize(d, y, qtab_723_40, 15); /* i = ADPCM code */
dq = reconstruct(i & 0x10, _dqlntab[i], y); /* quantized diff */
sr = (dq < 0) ? se - (dq & 0x7FFF) : se + dq; /* reconstructed signal */
dqsez = sr + sez - se; /* dqsez = pole prediction diff. */
update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
return (i);
}
/*
* g723_40_decoder()
*
* Decodes a 5-bit CCITT G.723 40Kbps code and returns
* the resulting 16-bit linear PCM, A-law or u-law sample value.
* -1 is returned if the output coding is unknown.
*/
int
g723_40_decoder(
int i,
int out_coding,
struct g72x_state *state_ptr)
{
short sezi, sei, sez, se; /* ACCUM */
short y; /* MIX */
short sr; /* ADDB */
short dq;
short dqsez;
i &= 0x1f; /* mask to get proper bits */
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
y = step_size(state_ptr); /* adaptive quantizer step size */
dq = reconstruct(i & 0x10, _dqlntab[i], y); /* estimation diff. */
sr = (dq < 0) ? (se - (dq & 0x7FFF)) : (se + dq); /* reconst. signal */
dqsez = sr - se + sez; /* pole prediction diff. */
update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
switch (out_coding) {
case AUDIO_ENCODING_ALAW:
return (tandem_adjust_alaw(sr, se, y, i, 0x10, qtab_723_40));
case AUDIO_ENCODING_ULAW:
return (tandem_adjust_ulaw(sr, se, y, i, 0x10, qtab_723_40));
case AUDIO_ENCODING_LINEAR:
return (sr << 2); /* sr was of 14-bit dynamic range */
default:
return (-1);
}
}

View File

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

123
utils/wxMMedia/adpcm/g72x.h Normal file
View File

@@ -0,0 +1,123 @@
/*
* 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 */

52
utils/wxMMedia/cdbase.cpp Normal file
View File

@@ -0,0 +1,52 @@
////////////////////////////////////////////////////////////////////////////////
// Name: sndsnd.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation
#endif
#include "cdbase.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
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);
}

88
utils/wxMMedia/cdbase.h Normal file
View File

@@ -0,0 +1,88 @@
// -*- 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
#ifdef WX_PRECOMP
#include "wx_prec.h"
#else
#include "wx/wx.h"
#endif
#include "mmtype.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
/** @param track track to get length */
wxCDtime GetTrackTime(wxUint8 track) const;
/** Returns the position of the specified
@param 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
/**
* @param beg_play start position
* @param end_play end 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
/**
* @param beg_play start position
*/
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

198
utils/wxMMedia/cdunix.cpp Normal file
View File

@@ -0,0 +1,198 @@
////////////////////////////////////////////////////////////////////////////////
// Name: cdlinux.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// 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 "mmtype.h"
#include "cdunix.h"
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;
}

61
utils/wxMMedia/cdunix.h Normal file
View File

@@ -0,0 +1,61 @@
// /////////////////////////////////////////////////////////////////////////////
// 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 "mmtype.h"
#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

208
utils/wxMMedia/cdwin.cpp Normal file
View File

@@ -0,0 +1,208 @@
////////////////////////////////////////////////////////////////////////////////
// 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>
#ifdef WX_PRECOMP
#include "wx/wxprec.h"
#else
#include "wx/wx.h"
#endif
#define WXMMEDIA_INTERNAL
#include "mmtype.h"
#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;
MCI_SET_PARMS set_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;
}
wxCDAudio::CDtoc& wxCDAudioWin::GetToc(void)
{
return *m_toc;
}

67
utils/wxMMedia/cdwin.h Normal file
View File

@@ -0,0 +1,67 @@
// /////////////////////////////////////////////////////////////////////////////
// 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
#ifdef WX_PRECOMP
#include "wx/wxprec.h"
#else
#include "wx/wx.h"
#endif
#include "mmtype.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 CDtoc& GetToc(void);
///
virtual inline bool Ok(void) const { return m_ok; }
protected:
void PrepareToc();
};
#endif

92
utils/wxMMedia/mmdata.cpp Normal file
View File

@@ -0,0 +1,92 @@
////////////////////////////////////////////////////////////////////////////////
// Name: mmdata.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#include "mmfile.h"
#include "sndsnd.h"
#include "sndfrmt.h"
#if defined(__UNIX__)
#include "snduss.h"
#endif
#include "sndfrag.h"
#include "sndfile.h"
#include "sndwav.h"
#include "sndaiff.h"
#include "sndau.h"
#include "sndpcm.h"
#include "sndmulaw.h"
#include "vidbase.h"
#if defined(__X__) || defined(__WXGTK__)
#include "vidxanm.h"
#endif
#ifdef __WINDOWS__
#include "sndwin.h"
#include "cdwin.h"
#include "vidwin.h"
#endif
#include "cdbase.h"
#ifdef __UNIX__
#include "cdunix.h"
#endif
#include "mmsolve.h"
// #include "midfile.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
IMPLEMENT_ABSTRACT_CLASS(wxSound, wxObject)
IMPLEMENT_ABSTRACT_CLASS(wxSndBuffer, wxObject)
IMPLEMENT_DYNAMIC_CLASS(wxSndSimpleBuffer, wxSndBuffer)
IMPLEMENT_ABSTRACT_CLASS(wxSoundCodec, wxObject)
IMPLEMENT_DYNAMIC_CLASS(wxSoundPcmCodec, wxSoundCodec)
IMPLEMENT_DYNAMIC_CLASS(wxSoundMulawCodec, wxSoundCodec)
#ifdef __UNIX__
IMPLEMENT_DYNAMIC_CLASS(wxUssSound, wxSound)
#endif
#ifdef __WINDOWS__
IMPLEMENT_DYNAMIC_CLASS(wxWinSound, wxSound)
#endif
IMPLEMENT_ABSTRACT_CLASS(wxSndFileCodec, wxMMediaFile)
IMPLEMENT_DYNAMIC_CLASS(wxSndWavCodec, wxSndFileCodec)
IMPLEMENT_DYNAMIC_CLASS(wxSndAuCodec, wxSndFileCodec)
IMPLEMENT_DYNAMIC_CLASS(wxSndAiffCodec, wxSndFileCodec)
IMPLEMENT_ABSTRACT_CLASS(wxVideoBaseDriver, wxMMediaFile)
IMPLEMENT_DYNAMIC_CLASS(wxVideoOutput, wxWindow)
#if defined(__X__) || defined(__WXGTK__)
IMPLEMENT_DYNAMIC_CLASS(wxVideoXANIM, wxVideoBaseDriver)
#endif
#ifdef __WINDOWS__
IMPLEMENT_DYNAMIC_CLASS(wxVideoWindows, wxVideoBaseDriver)
#endif
IMPLEMENT_ABSTRACT_CLASS(wxCDAudio, wxObject)
#ifdef linux
IMPLEMENT_DYNAMIC_CLASS(wxCDAudioLinux, wxCDAudio)
#else
IMPLEMENT_DYNAMIC_CLASS(wxCDAudioWin, wxCDAudio)
#endif
// IMPLEMENT_ABSTRACT_CLASS(wxMidiFile, wxObject)
wxMediaFileSolve::wxMFileList *wxMediaFileSolve::m_first = NULL;
wxUint8 wxMediaFileSolve::m_devnum = 0;
MMD_REGISTER_FILE("audio/x-wav", "Wav Player", wxSndWavCodec, "wav")
MMD_REGISTER_FILE("audio/x-aiff", "Aiff Player", wxSndAiffCodec, "aif")
MMD_REGISTER_FILE("audio/x-au", "Sun Audio File Player", wxSndAuCodec, "au")
#if defined(__X__) || defined(__WXGTK__)
MMD_REGISTER_FILE("video/*", "Video Player", wxVideoXANIM, "mov")
#else
MMD_REGISTER_FILE("video/avi", "AVI Player", wxVideoWindows, "avi")
#endif

31
utils/wxMMedia/mmedia.h Normal file
View File

@@ -0,0 +1,31 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: mmedia.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
#ifndef __MMEDIA_H__
#define __MMEDIA_H__
#ifdef __WINDOWS__
#include "sndwin.h"
#define wxSoundDevice wxWinSound
#include "vidwin.h"
#define wxVideoDevice wxVideoWindows
#else
#include "snduss.h"
#define wxSoundDevice wxUssSound
#include "vidxanm.h"
#define wxVideoDevice wxVideoXANIM
#endif
#endif

194
utils/wxMMedia/mmfile.cpp Normal file
View File

@@ -0,0 +1,194 @@
////////////////////////////////////////////////////////////////////////////////
// Name: mmfile.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation
#endif
#ifdef WX_PRECOMP
#include "wx_prec.h"
#else
#include "wx/wx.h"
#endif
#include <wx/stream.h>
#include <wx/fstream.h>
#include <wx/mstream.h>
#include "mmfile.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
wxMMediaFile::wxMMediaFile()
: m_istream(NULL), m_i_temp(NULL), m_ostream(NULL), m_o_temp(NULL),
m_tmpfname((char *)NULL), m_mfname((char *)NULL),
m_seekable(FALSE)
{
}
wxMMediaFile::wxMMediaFile(wxOutputStream& os, bool seekable)
: m_istream(NULL), m_i_temp(NULL), m_ostream(&os), m_o_temp(NULL),
m_tmpfname((char *)NULL), m_mfname((char *)NULL),
m_seekable(seekable)
{
}
wxMMediaFile::wxMMediaFile(wxInputStream& is, bool preload, bool seekable)
: m_istream(&is), m_i_temp(NULL), m_ostream(NULL), m_o_temp(NULL),
m_tmpfname((char *)NULL), m_mfname((char *)NULL),
m_seekable(seekable)
{
/*
if (preload) {
wxMemoryStream *tmpstream = new wxMemoryStream();
m_o_temp = tmpstream;
m_i_temp = tmpstream;
m_o_temp->Write(is);
}
*/
}
wxMMediaFile::wxMMediaFile(const wxString& fname)
: m_istream(NULL), m_i_temp(NULL), m_ostream(NULL), m_o_temp(NULL),
m_tmpfname((char *)NULL), m_mfname(fname),
m_seekable(TRUE)
{
wxFileStream *s = new wxFileStream(fname);
m_mfname = fname;
m_istream = s;
m_ostream = s;
}
void wxMMediaFile::SetFile(wxInputStream& str, bool preload, bool seekable)
{
CleanUpPrevious();
m_istream = &str;
m_ostream = NULL;
m_seekable = seekable;
/*
if (preload) {
wxMemoryStream *tmpstream = new wxMemoryStream();
m_i_temp = tmpstream;
m_o_temp = tmpstream;
m_o_temp->Write(str);
}
*/
}
void wxMMediaFile::SetFile(wxOutputStream& str, bool seekable)
{
CleanUpPrevious();
m_ostream = &str;
m_istream = NULL;
m_seekable = seekable;
}
void wxMMediaFile::SetFile(const wxString& fname)
{
CleanUpPrevious();
m_mfname = fname;
wxFileStream *f = new wxFileStream(fname);
SetFile(*f, FALSE, TRUE);
}
void wxMMediaFile::CleanUpPrevious()
{
if (m_i_temp) {
m_i_temp->SeekI(0);
if (m_ostream)
m_ostream->Write(*m_i_temp);
delete m_i_temp; // Only one delete because m_tmpo* and m_tmpi* are linked
if (m_tmpfname)
wxRemoveFile(m_tmpfname);
}
if (!m_mfname.IsNull() && m_mfname != "")
delete m_istream;
m_i_temp = NULL;
m_o_temp = NULL;
m_istream = NULL;
m_ostream = NULL;
}
wxMMediaFile::~wxMMediaFile()
{
CleanUpPrevious();
}
wxMMtime wxMMediaFile::GetLength()
{
wxMMtime mm_time = {-1, 0, 0};
return mm_time;
}
wxMMtime wxMMediaFile::GetPosition()
{
wxMMtime mm_time = {0, 0, 0};
return mm_time;
}
wxInputStream *wxMMediaFile::GetIRawData()
{
if (!m_istream)
return NULL;
if (!m_seekable && !m_i_temp)
CacheIO();
return (m_i_temp) ? m_i_temp : m_istream;
}
wxOutputStream *wxMMediaFile::GetORawData()
{
if (!m_ostream)
return NULL;
if (!m_seekable && !m_i_temp)
CacheIO();
return (m_o_temp) ? m_o_temp : m_ostream;
}
wxString wxMMediaFile::GetCurrentFile()
{
if (!m_istream && !m_ostream)
return wxString((char *)NULL);
if (!m_mfname && !m_i_temp)
CacheIO();
return (!m_tmpfname.IsEmpty()) ? m_tmpfname : m_mfname;
}
void wxMMediaFile::CacheIO()
{
if ((!m_istream && !m_ostream) || m_i_temp)
return;
m_tmpfname = wxGetTempFileName("mmd");
wxFileStream *tmpstream = new wxFileStream(m_tmpfname);
m_i_temp = tmpstream;
m_o_temp = tmpstream;
if (m_istream)
tmpstream->wxOutputStream::Write(*m_istream);
}

94
utils/wxMMedia/mmfile.h Normal file
View File

@@ -0,0 +1,94 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: mmfile.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
#ifndef __MMD_file_H__
#define __MMD_file_H__
#ifdef __GNUG__
#pragma interface
#endif
#ifdef WX_PRECOMP
#include "wx_prec.h"
#else
#include "wx/wx.h"
#endif
#include "wx/string.h"
#include "wx/stream.h"
#include "mmtype.h"
///
typedef enum {
wxMMFILE_NOERROR,
wxMMFILE_INVALID,
wxMMFILE_EOF
} ///
wxMMFileError;
typedef struct {
wxInt8 hours;
wxUint8 minutes, seconds;
} wxMMtime;
/// Common base class for multimedia file.
class wxMMediaFile {
public:
wxMMediaFile();
///
wxMMediaFile(wxInputStream& is, bool preload, bool seekable);
///
wxMMediaFile(wxOutputStream& is, bool seekable);
///
wxMMediaFile(const wxString& fname);
///
virtual ~wxMMediaFile();
///
wxInputStream *GetIRawData();
wxOutputStream *GetORawData();
///
wxString GetCurrentFile();
///
virtual void SetFile(wxInputStream& is,
bool preload = FALSE, bool seekable = FALSE);
///
virtual void SetFile(wxOutputStream& is, bool seekable = FALSE);
///
void SetFile(const wxString& fname);
///
wxMMFileError GetFileError() const { return m_mmerror; }
///
virtual wxMMtime GetLength();
///
virtual wxMMtime GetPosition();
///
virtual bool StartPlay() = 0;
///
virtual void StopPlay() = 0;
protected:
///
wxMMFileError m_mmerror;
///
wxInputStream *m_istream, *m_i_temp;
///
wxOutputStream *m_ostream, *m_o_temp;
///
wxString m_tmpfname, m_mfname;
///
bool m_seekable;
///
void CacheIO();
///
void CleanUpPrevious();
};
#endif

215
utils/wxMMedia/mmriff.cpp Normal file
View File

@@ -0,0 +1,215 @@
////////////////////////////////////////////////////////////////////////////////
// Name: mmriff.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "mmriff.h"
#endif
#ifdef WX_PRECOMP
#include "wx_prec.h"
#else
#include "wx/wx.h"
#endif
#include "mmfile.h"
#include "mmriff.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
wxRiffCodec::wxRiffCodec() :
riff_i_stream(NULL), riff_o_stream(NULL), chunk_length(INVALID_CHUNK_LEN)
{
}
wxRiffCodec::wxRiffCodec(wxInputStream& s) :
riff_i_stream(&s), riff_o_stream(NULL), chunk_length(INVALID_CHUNK_LEN)
{
}
wxRiffCodec::wxRiffCodec(wxOutputStream& s) :
riff_i_stream(NULL), riff_o_stream(&s), chunk_length(INVALID_CHUNK_LEN)
{
}
wxRiffCodec::~wxRiffCodec()
{
}
bool wxRiffCodec::RiffReset(wxUint8 mode)
{
switch (mode) {
case RIFF_READ:
if (!riff_i_stream)
return FALSE;
riff_i_stream->SeekI(0);
chunk_length = INVALID_CHUNK_LEN;
return TRUE;
case RIFF_WRITE:
if (!riff_o_stream)
return FALSE;
riff_o_stream->SeekO(0);
chunk_length = INVALID_CHUNK_LEN;
return TRUE;
}
return FALSE;
}
bool wxRiffCodec::ReadData(void *data, wxUint32 size)
{
if (!riff_i_stream)
return FALSE;
if (chunk_length != INVALID_CHUNK_LEN && (wxUint32)chunk_length < size) {
riff_error = wxMMFILE_EOF;
return FALSE;
}
if (chunk_length != INVALID_CHUNK_LEN)
chunk_length -= size;
bool ret = (riff_i_stream->Read((char *)data, size).LastRead() == size);
return ret;
}
bool wxRiffCodec::WriteData(void *data, wxUint32 size)
{
if (!riff_o_stream)
return FALSE;
if (chunk_length < size) {
riff_error = wxMMFILE_EOF;
return FALSE;
}
chunk_length -= size;
riff_o_stream->Write(data, size);
return TRUE;
}
bool wxRiffCodec::Read32(wxUint32& i32)
{
wxUint8 i8[4];
if (!ReadData(i8, 4))
return FALSE;
i32 = i8[0];
i32 |= ((wxUint32)i8[1]) << 8;
i32 |= ((wxUint32)i8[2]) << 16;
i32 |= ((wxUint32)i8[3]) << 24;
return TRUE;
}
bool wxRiffCodec::Write32(wxUint32 i32)
{
wxUint8 i8[4];
i8[0] = i32 & 0xff;
i8[1] = (i32 >> 8) & 0xff;
i8[2] = (i32 >> 16) & 0xff;
i8[3] = (i32 >> 24) & 0xff;
if (!WriteData(i8, 4))
return FALSE;
return TRUE;
}
bool wxRiffCodec::Read16(wxUint16& i16)
{
wxUint8 i8[2];
if (!ReadData(i8, 2))
return FALSE;
i16 = i8[0];
i16 |= ((wxUint16)i8[1]) << 8;
return TRUE;
}
bool wxRiffCodec::Write16(wxUint16 i16)
{
wxUint8 i8[2];
i8[0] = i16 & 0xff;
i8[1] = (i16 >> 8) & 0xff;
if (!WriteData(i8, 2))
return FALSE;
return TRUE;
}
bool wxRiffCodec::Skip(wxUint32 skip)
{
if (!riff_i_stream || (chunk_length != INVALID_CHUNK_LEN && (wxInt32)skip > chunk_length))
return FALSE;
if (chunk_length != INVALID_CHUNK_LEN)
chunk_length -= skip;
riff_i_stream->SeekI(skip, wxFromCurrent);
return TRUE;
}
bool wxRiffCodec::CreateChunk(const wxString& name, wxUint32 size)
{
if (!riff_o_stream || name.Length() != 4)
return FALSE;
if (riff_o_stream->Write(name.GetData(), 4).LastError()) {
riff_error = wxMMFILE_EOF;
return FALSE;
}
chunk_length = size+4;
return Write32(size);
}
bool wxRiffCodec::FindChunk(const wxString& name, bool from_here)
{
char buf[5];
wxString str2;
if (!riff_i_stream)
return FALSE;
if (chunk_length != INVALID_CHUNK_LEN && !from_here)
Skip(chunk_length);
while (1) {
if (riff_i_stream->Read(buf, 4).LastError()) {
riff_error = wxMMFILE_EOF;
return FALSE;
}
chunk_length = INVALID_CHUNK_LEN;
if (!Read32(chunk_length)) {
riff_error = wxMMFILE_EOF;
return FALSE;
}
buf[4] = 0;
str2 = buf;
if ((!name.IsNull()) && str2 != name) {
Skip(chunk_length);
continue;
}
m_chunk = str2;
return TRUE;
}
return TRUE;
}

81
utils/wxMMedia/mmriff.h Normal file
View File

@@ -0,0 +1,81 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: mmriff.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1998
// Updated:
// Copyright: (C) 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
/* Real -*- C++ -*- */
#ifndef __MM_riff_H__
#define __MM_riff_H__
#ifdef __GNUG__
#pragma interface
#endif
#include "mmtype.h"
#include "mmfile.h"
#define RIFF_READ 0
#define RIFF_WRITE 1
#define INVALID_CHUNK_LEN ((wxUint32)-1)
///
class wxRiffCodec {
public:
///
wxRiffCodec();
///
wxRiffCodec(wxOutputStream& s);
///
wxRiffCodec(wxInputStream& s);
///
virtual ~wxRiffCodec();
///
void SetFile(wxInputStream& s) { cout << "RIFF:SetFile(i)" << endl; riff_i_stream = &s; riff_o_stream = NULL; }
///
void SetFile(wxOutputStream& s) { cout << "RIFF::SetFile(o)" << endl; riff_i_stream = NULL; riff_o_stream = &s; }
///
bool Read32(wxUint32& i32);
///
bool Read16(wxUint16& i16);
///
bool ReadData(void *data, wxUint32 size);
///
bool Skip(wxUint32 skip);
///
bool Write32(wxUint32 i32);
///
bool Write16(wxUint16 i16);
///
bool WriteData(void *data, wxUint32 size);
///
inline wxUint32 GetChunkLength() const { return chunk_length; }
///
inline const wxString& GetChunkName() const { return m_chunk; }
///
bool RiffReset(wxUint8 state);
///
bool FindChunk(const wxString& name = "", bool from_here = FALSE);
///
bool CreateChunk(const wxString& name, wxUint32 chunk_size);
///
inline wxMMFileError GetError() const { return riff_error; }
protected:
wxInputStream *riff_i_stream;
wxOutputStream *riff_o_stream;
wxUint32 chunk_length;
wxMMFileError riff_error;
wxString m_chunk;
};
#endif

124
utils/wxMMedia/mmsolve.cpp Normal file
View File

@@ -0,0 +1,124 @@
////////////////////////////////////////////////////////////////////////////////
// Name: mmsolve.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation
#endif
#include "mmsolve.h"
wxMMediaFile *wxMediaFileSolve::ByExtension(const wxString& filename)
{
wxMFileList *list = m_first;
wxString tmp, f_ext;
int pos = filename.Find('.', TRUE)+1;
tmp = filename;
f_ext = tmp(pos, filename.Length()-pos);
printf("f_ext = %s\n", f_ext.GetData());
while (list) {
printf("list->ext = %s\n", list->ext.GetData());
if (list->ext.CompareTo(f_ext) == 0) {
wxMMediaFile *mmf = list->creator();
return mmf;
}
list = list->next;
}
return NULL;
}
wxMMediaFile *wxMediaFileSolve::ByName(const wxString& name)
{
wxMFileList *list = m_first;
while (list) {
if (list->name == name)
return (wxMMediaFile *)(list->creator());
list = list->next;
}
return NULL;
}
bool wxMatchMimeType(const wxString& mime_obj, const wxString& type)
{
#ifdef USE_GNU_WXSTRING
wxString mime2_obj = mime_obj;
wxString type2 = type;
#define mime_obj mime2_obj
#define type type2
#endif
if (mime_obj.Find('*') != -1) {
wxString part_str1[2], part_str2[2];
part_str1[0] = mime_obj.Left('/');
part_str1[1] = mime_obj.After('/');
part_str2[0] = type.Left('/');
part_str2[1] = type.After('/');
if (part_str1[0] == "*" && part_str1[1] == "*")
return TRUE;
if (part_str1[0] == "*" && part_str1[1] == part_str2[1])
return TRUE;
if (part_str1[1] == "*" && part_str1[0] == part_str2[1])
return TRUE;
return FALSE;
}
if (mime_obj == type)
return TRUE;
return FALSE;
}
wxMMediaFile *wxMediaFileSolve::ByType(const wxString& type)
{
wxMFileList *list = m_first;
while (list) {
if (wxMatchMimeType(*(list->mime_type), type))
return (wxMMediaFile *)(list->creator());
list = list->next;
}
return NULL;
}
void wxMediaFileSolve::ListMDevice(wxString*& names, wxUint8& devices)
{
wxMFileList *list = m_first;
wxUint8 d = 0;
if (!m_devnum) {
names = NULL;
return;
}
devices = m_devnum;
names = new wxString[devices];
while (list) {
names[d++] = list->name;
list = list->next;
}
}
wxMMDfileRegister::wxMMDfileRegister(wxMediaFileCreator cbk,
char *mtype, char *ext, char *name)
{
wxMediaFileSolve::wxMFileList *entry = new wxMediaFileSolve::wxMFileList;
entry->next = wxMediaFileSolve::m_first;
entry->creator = cbk;
entry->mime_type = wxString(mtype);
entry->name = wxString(name);
entry->ext = wxString(ext);
wxMediaFileSolve::m_devnum++;
wxMediaFileSolve::m_first = entry;
}

92
utils/wxMMedia/mmsolve.h Normal file
View File

@@ -0,0 +1,92 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: mmsolve.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
#ifndef __MMD_solve_H__
#define __MMD_solve_H__
#ifdef __GNUG__
#pragma interface
#endif
#ifdef WX_PRECOMP
#include "wx/wxprec.h"
#else
#include "wx/wx.h"
#endif
#include "mmfile.h"
/** @name Solver classes */
//@{
typedef wxMMediaFile *(*wxMediaFileCreator)();
/** wxMediaFileSolve is a class to do name resolution on multimedia files
* @memo Multimedia file solver
* @author Guilhem Lavaux
*/
class WXDLLEXPORT wxMediaFileSolve : public wxObject {
protected:
typedef struct wxMFileList {
wxMediaFileCreator creator;
wxString mime_type, name, ext;
wxMFileList *next;
} wxMFileList;
static wxMFileList *m_first;
static wxUint8 m_devnum;
friend class wxMMDfileRegister;
public:
wxMediaFileSolve() : wxObject() {}
~wxMediaFileSolve() {}
/** It resolves using the extension of the specified filename
* @memo
* @return the multimedia codec
* @param filename
*/
static wxMMediaFile *ByExtension(const wxString& filename);
/** It resolves using the real name of a codec
* @memo
* @return the multimedia codec
* @param devname
*/
static wxMMediaFile *ByName(const wxString& devname);
/** It resolves using a mime type
* @memo
* @return the multimedia codec
* @param mimetype
*/
static wxMMediaFile *ByType(const wxString& mimetype);
/** It lists all codecs currently registered in "names". "names" is allocated
* by it and devices returns the number of codecs the list contains
* @memo
* @return nothing
* @param names an array
* @param devices
*/
static void ListMDevice(wxString*& names, wxUint8& devices);
};
///
class wxMMDfileRegister {
public:
///
wxMMDfileRegister(wxMediaFileCreator cbk, char *mtype, char *ext, char *name);
};
#define MMD_REGISTER_FILE(mtype, name, class, ext) \
static wxMMediaFile *wxMediaFileConstructor_##class() { return new class(); } \
wxMMDfileRegister mmd_##class(wxMediaFileConstructor_##class, mtype, ext, name);
//@}
#endif

41
utils/wxMMedia/mmtype.h Normal file
View File

@@ -0,0 +1,41 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: mmtype.h
// Purpose: wxMMedia (imported from wxSocket)
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
#ifndef __SOCKTYPEH__
#define __SOCKTYPEH__
#ifdef __UNIX__
#include <stl_config.h>
#endif
/// Type to use for 8 bits unsigned integers
typedef unsigned char wxUint8;
/// Type to use for 16 bits unsigned integers
typedef unsigned short wxUint16;
/// Type to use for 32 bits unsigned integers
typedef unsigned long wxUint32;
#if HAVE_UINT64
/// Type to use for 64 bits unsigned integers
typedef unsigned long long wxUint64;
#endif
/// Type to use for 8 bits signed integers
typedef char wxInt8;
/// Type to use for 16 bits signed integers
typedef short wxInt16;
/// Type to use for 32 bits signed integers
typedef long wxInt32;
#if HAVE_UINT64
/// Type to use for 64 bits signed integers
typedef long long wxInt64;
#endif
#endif

218
utils/wxMMedia/sndaiff.cpp Normal file
View File

@@ -0,0 +1,218 @@
////////////////////////////////////////////////////////////////////////////////
// Name: sndaiff.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: February 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "sndaiff.h"
#endif
#ifdef WX_PRECOMP
#include "wx/wxprec.h"
#else
#include "wx/wx.h"
#endif
#include "wx/datstrm.h"
#include "sndaiff.h"
#include "sndpcm.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#define READ_DATA(n) m_istream->Read(tmp_buf,n)
#define WRITE_DATA(n) m_ostream->Write(tmp_buf,n)
#define READ_STRING(s,n) \
READ_DATA(n); \
tmp_buf[n] = 0; \
s = tmp_buf;
#define WRITE_STRING(s,n) WRITE_DATA((const char *)s, n)
#define READ32(i) \
READ_DATA(4); \
i = (unsigned long)tmp_buf[3] | \
((unsigned long)tmp_buf[2] << 8) | \
((unsigned long)tmp_buf[1] << 16) | \
((unsigned long)tmp_buf[0] << 24);
#define WRITE32(i) \
tmp_buf[3] = i & 0xFF; \
tmp_buf[2] = (i >> 8) & 0xFF; \
tmp_buf[1] = (i >> 16) & 0xFF; \
tmp_buf[0] = (i >> 24) & 0xFF; \
WRITE_DATA(4);
#define READ16(i) \
READ_DATA(2); \
i = (unsigned short)tmp_buf[1] | \
((unsigned short)tmp_buf[0] << 8);
wxSndAiffCodec::wxSndAiffCodec()
: wxSndFileCodec()
{
m_sndtime.hours = -1;
}
wxSndAiffCodec::wxSndAiffCodec(wxOutputStream& s, bool seekable)
: wxSndFileCodec(s, seekable)
{
if (!seekable)
CacheIO();
m_sndtime.hours = -1;
}
wxSndAiffCodec::wxSndAiffCodec(wxInputStream& s, bool preload, bool seekable)
: wxSndFileCodec(s, preload, seekable)
{
if (!seekable)
CacheIO();
m_sndtime.hours = -1;
}
wxSndAiffCodec::wxSndAiffCodec(const wxString& fname)
: wxSndFileCodec(fname)
{
m_sndtime.hours = -1;
}
wxUint32 wxSndAiffCodec::PrepareToPlay()
{
char tmp_buf[5];
wxString chunk_name;
m_istream->SeekI(0, wxFromStart);
wxSndFileCodec::m_mmerror = wxMMFILE_INVALID;
READ_STRING(chunk_name, 4);
if (chunk_name != "FORM")
return 0;
m_istream->SeekI(4, wxFromCurrent);
READ_STRING(chunk_name, 4);
if (chunk_name != "AIFF" && chunk_name != "AIFC")
return 0;
// To check whether the file is good
m_spos = 0;
m_slen = 0;
m_sndformat.SetSampleRate(0);
while (1) {
READ_STRING(chunk_name, 4);
READ32(m_chunksize);
if (chunk_name == "SSND")
ParseSSND();
if (chunk_name == "COMM")
ParseCOMM();
else
m_istream->SeekI(m_chunksize, wxFromCurrent);
if (m_spos && m_sndformat.GetSampleRate())
break;
}
m_sndmode = wxSND_OUTPUT;
wxUint32 sec1 = m_slen / m_sndformat.GetCodec()->GetByteRate(),
sec2 = sec1 % 3600;
m_sndtime.hours = sec1 / 3600;
m_sndtime.minutes = sec2 / 60;
m_sndtime.seconds = sec2 % 60;
wxSndFileCodec::m_mmerror = wxMMFILE_NOERROR;
m_istream->SeekI(m_spos, wxFromStart);
return m_slen;
}
void wxSndAiffCodec::ParseCOMM()
{
wxDataInputStream data_s(*m_istream);
char tmp_buf[10];
wxUint16 channels;
wxUint32 srate, num_samples;
wxUint16 bps;
READ16(channels);
READ32(num_samples);
READ16(bps);
srate = (wxUint32)data_s.ReadDouble();
m_sndformat.SetSampleRate(srate);
m_sndformat.SetBps(bps);
m_sndformat.SetChannels(channels);
m_sndformat.SetByteOrder(wxSND_SAMPLE_BE);
m_sndformat.SetSign(wxSND_SAMPLE_UNSIGNED);
ChangeCodec(WXSOUND_PCM);
m_istream->SeekI(m_chunksize-18, wxFromCurrent);
}
void wxSndAiffCodec::ParseSSND()
{
wxDataInputStream data_s(*m_istream);
char tmp_buf[10];
READ32(m_spos);
m_istream->SeekI(4, wxFromCurrent);
m_slen = m_chunksize - m_spos;
m_spos += m_istream->TellI();
}
wxSndAiffCodec::~wxSndAiffCodec()
{
}
bool wxSndAiffCodec::OnNeedData(char *buf, wxUint32 size)
{
m_istream->Read(buf, size);
return TRUE;
}
bool wxSndAiffCodec::OnWriteData(char *buf, wxUint32 size)
{
return ( !(m_ostream->Write(buf, size).LastError()) );
}
bool wxSndAiffCodec::PrepareToRecord(wxUint32 m_fsize)
{
/*
wxUint32 total_size;
char tmp_buf[10];
m_ostream->SeekO(0, wxBeginPosition);
m_ostream->Write("FORM", 4);
WRITE32(total_size);
m_ostream->Write("AIFF", 4);
WriteCOMM();
WriteSSND(m_fsize);
*/
return TRUE;
}
void wxSndAiffCodec::SetFile(wxInputStream& s, bool preload, bool seekable)
{
wxMMediaFile::SetFile(s, preload, seekable);
if (!seekable)
CacheIO();
}
void wxSndAiffCodec::SetFile(wxOutputStream& s, bool seekable)
{
wxMMediaFile::SetFile(s, seekable);
if (!seekable)
CacheIO();
}

58
utils/wxMMedia/sndaiff.h Normal file
View File

@@ -0,0 +1,58 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: sndaiff.h
// Purpose: wxMMedia Aiff Codec
// Author: Guilhem Lavaux
// Created: 1997
// Updated: February 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
/* Real -*- C++ -*- */
#ifndef __SND_aiff_H__
#define __SND_aiff_H__
#ifdef __GNUG__
#pragma interface
#endif
#include "mmriff.h"
#include "sndfile.h"
///
class wxSndAiffCodec : public wxSndFileCodec {
///
DECLARE_DYNAMIC_CLASS(wxSndAiffCodec)
public:
///
wxSndAiffCodec();
///
wxSndAiffCodec(wxInputStream& s, bool preload = FALSE, bool seekable = TRUE);
///
wxSndAiffCodec(wxOutputStream& s, bool seekable = TRUE);
///
wxSndAiffCodec(const wxString& fname);
///
virtual ~wxSndAiffCodec();
virtual bool OnNeedData(char *buf, wxUint32 size);
virtual bool OnWriteData(char *buf, wxUint32 size);
virtual wxUint32 PrepareToPlay();
virtual bool PrepareToRecord(wxUint32 file_size);
virtual void SetFile(wxInputStream& s, bool preload = FALSE,
bool seekable = FALSE);
virtual void SetFile(wxOutputStream& s,
bool seekable = FALSE);
protected:
void ParseCOMM();
void ParseSSND();
void WriteCOMM();
void WriteSSND(wxUint32 file_size);
protected:
wxUint32 m_spos, m_slen;
wxUint32 m_chunksize;
};
#endif

114
utils/wxMMedia/sndau.cpp Normal file
View File

@@ -0,0 +1,114 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: sndau.cpp
// Purpose: wxMMedia Sun Audio File Codec
// Author: Guilhem Lavaux
// Created: 1998
// Updated:
// Copyright: (C) 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "sndau.h"
#endif
#include "mmriff.h"
#include "sndfile.h"
#include "sndau.h"
#define AU_ISDN_ULAW 1
#define AU_PCM_8BITS 2
#define AU_PCM_16BITS 3
#define AU_ADPCM 23
wxSndAuCodec::wxSndAuCodec()
: wxSndFileCodec()
{
}
wxSndAuCodec::wxSndAuCodec(wxInputStream& s, bool preload, bool seekable)
: wxSndFileCodec(s, preload, seekable)
{
}
wxSndAuCodec::wxSndAuCodec(wxOutputStream& s, bool seekable)
: wxSndFileCodec(s, seekable)
{
}
wxSndAuCodec::wxSndAuCodec(const wxString& fname)
: wxSndFileCodec(fname)
{
}
wxSndAuCodec::~wxSndAuCodec()
{
}
wxUint32 wxSndAuCodec::PrepareToPlay()
{
wxString id;
char temp_buf[5];
int offset, srate, codec, ch_count;
size_t len;
m_istream->SeekI(0);
m_istream->Read(temp_buf, 4);
temp_buf[4] = 0;
id = temp_buf;
if (id != ".snd") {
m_mmerror = wxMMFILE_INVALID;
return 0;
}
#define READ_BE_32(i) \
m_istream->Read(temp_buf, 4); \
i = (unsigned long)temp_buf[0] << 24; \
i |= (unsigned long)temp_buf[1] << 16; \
i |= (unsigned long)temp_buf[2] << 8; \
i |= (unsigned long)temp_buf[3];
READ_BE_32(offset);
READ_BE_32(len);
READ_BE_32(codec);
READ_BE_32(srate);
READ_BE_32(ch_count);
m_sndformat.SetSampleRate(srate);
m_sndformat.SetChannels(ch_count);
switch (codec) {
case AU_ISDN_ULAW:
ChangeCodec(WXSOUND_ULAW);
break;
case AU_PCM_8BITS:
ChangeCodec(WXSOUND_PCM);
m_sndformat.SetByteOrder(wxSND_SAMPLE_LE);
m_sndformat.SetSign(wxSND_SAMPLE_SIGNED);
break;
case AU_PCM_16BITS:
ChangeCodec(WXSOUND_PCM);
m_sndformat.SetByteOrder(wxSND_SAMPLE_LE);
m_sndformat.SetSign(wxSND_SAMPLE_SIGNED);
break;
case AU_ADPCM:
ChangeCodec(WXSOUND_ADPCM);
break;
}
return len;
}
bool wxSndAuCodec::OnNeedData(char *buf, wxUint32 size)
{
return m_istream->Read(buf, size).LastError();
}
bool wxSndAuCodec::OnWriteData(char *buf, wxUint32 size)
{
return m_ostream->Write(buf, size).LastError();
}
bool wxSndAuCodec::PrepareToRecord(wxUint32 file_size)
{
return FALSE;
}

47
utils/wxMMedia/sndau.h Normal file
View File

@@ -0,0 +1,47 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: sndau.h
// Purpose: wxMMedia Sun Audio File Codec
// Author: Guilhem Lavaux
// Created: 1998
// Updated:
// Copyright: (C) 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
/* Real -*- C++ -*- */
#ifndef __SND_au_H__
#define __SND_au_H__
#ifdef __GNUG__
#pragma interface
#endif
#include "mmriff.h"
#include "sndfile.h"
///
class wxSndAuCodec : public wxSndFileCodec {
///
DECLARE_DYNAMIC_CLASS(wxSndAuCodec)
public:
///
wxSndAuCodec();
///
wxSndAuCodec(wxInputStream& s, bool preload = FALSE, bool seekable = TRUE);
///
wxSndAuCodec(wxOutputStream& s, bool seekable = TRUE);
///
wxSndAuCodec(const wxString& fname);
///
virtual ~wxSndAuCodec();
bool OnNeedData(char *buf, wxUint32 size);
bool OnWriteData(char *buf, wxUint32 size);
wxUint32 PrepareToPlay();
bool PrepareToRecord(wxUint32 file_size);
protected:
wxUint32 m_spos, m_slen;
wxUint32 m_chunksize;
};
#endif

323
utils/wxMMedia/sndfile.cpp Normal file
View File

@@ -0,0 +1,323 @@
////////////////////////////////////////////////////////////////////////////////
// Name: sndfile.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "sndfile.h"
#endif
#include "mmedia.h"
#include "sndfile.h"
#ifdef WX_PRECOMP
#include <wx/wxprec.h>
#else
#include <wx/wx.h>
#endif
#include <wx/module.h>
#include "sndfrmt.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
wxSndFileCodec::wxSndFileCodec()
: wxMMediaFile(), wxSndBuffer(),
m_fstate(wxSFILE_STOPPED)
{
}
wxSndFileCodec::wxSndFileCodec(wxOutputStream& s, bool seekable)
: wxMMediaFile(s, seekable),
wxSndBuffer(),
m_fstate(wxSFILE_STOPPED)
{
}
wxSndFileCodec::wxSndFileCodec(wxInputStream& s, bool preload, bool seekable)
: wxMMediaFile(s, preload, seekable),
wxSndBuffer(),
m_fstate(wxSFILE_STOPPED)
{
}
wxSndFileCodec::wxSndFileCodec(const wxString& fname)
: wxMMediaFile(fname), wxSndBuffer(),
m_fstate(wxSFILE_STOPPED)
{
}
wxSndFileCodec::~wxSndFileCodec()
{
}
void wxSndFileCodec::Play(wxSound& snd)
{
if (m_fstate != wxSFILE_STOPPED || IsSet(wxSND_BUFLOCKED))
return;
if (!(m_fsize = PrepareToPlay()))
return;
m_fpos = 0;
m_fstate = wxSFILE_PLAYING;
Set(wxSND_BUFREADY | wxSND_KEEPQUEUED);
snd.QueueBuffer(*this);
}
void wxSndFileCodec::Stop(wxSound& snd)
{
if (m_fstate == wxSFILE_STOPPED)
return;
snd.UnqueueBuffer(*this);
Clear(wxSND_BUFREADY | wxSND_KEEPQUEUED);
m_fstate = wxSFILE_STOPPED;
}
void wxSndFileCodec::Record(wxSound& snd,
const wxSoundDataFormat& format,
wxUint32 seconds)
{
wxUint32 byterate;
if (m_fstate != wxSFILE_STOPPED)
return;
m_sndformat = format;
byterate = m_sndformat.GetCodec()->GetByteRate();
m_fsize = seconds*byterate;
if (!PrepareToRecord(m_fsize))
return;
if (IsSet(wxSND_BUFLOCKED))
return;
wxUint32 sec1 = m_fsize / byterate,
sec2 = sec1 % 3600;
m_sndtime.hours = sec1 / 3600;
m_sndtime.minutes = sec2 / 60;
m_sndtime.seconds = sec2 % 60;
m_fdone = m_fpos = 0;
m_fstate = wxSFILE_RECORDING;
m_sndmode = wxSND_INPUT;
Set(wxSND_BUFREADY | wxSND_KEEPQUEUED);
snd.QueueBuffer(*this);
}
void wxSndFileCodec::OnNeedOutputData(char *data, wxUint32& size)
{
wxUint32 datas_left = m_fsize-m_fpos;
if (m_fstate != wxSFILE_PLAYING) {
size = 0;
return;
}
if (!datas_left) {
size = 0;
m_fpos = 0;
m_fstate = wxSFILE_STOPPED;
Clear(wxSND_KEEPQUEUED);
return;
}
if (size > datas_left)
size = datas_left;
if (!OnNeedData(data, size)) {
size = 0;
m_fpos = 0;
m_fstate = wxSFILE_STOPPED;
Clear(wxSND_KEEPQUEUED);
return;
}
m_fpos += size;
}
void wxSndFileCodec::OnBufferInFinished(char *iobuf, wxUint32& size)
{
wxUint32 datas_left = m_fsize-m_fdone;
if (m_fstate != wxSFILE_RECORDING) {
size = 0;
return;
}
if (!datas_left) {
size = 0;
Clear(wxSND_KEEPQUEUED); // To be sure.
return;
}
if (size > datas_left)
size = datas_left;
OnWriteData(iobuf, size);
m_fdone += size;
}
wxMMtime wxSndFileCodec::GetPosition()
{
wxMMtime mm_time;
wxUint32 sec1, sec2;
wxUint32 byterate;
byterate = m_sndformat.GetCodec()->GetByteRate();
if (m_fpos && byterate) {
sec1 = m_fpos / byterate;
sec2 = sec1 % 3600;
mm_time.hours = sec1 / 3600;
mm_time.minutes = sec2 / 60;
mm_time.seconds = sec2 % 60;
} else {
mm_time.hours = 0;
mm_time.minutes = 0;
mm_time.seconds = 0;
}
return mm_time;
}
wxMMtime wxSndFileCodec::GetLength()
{
if (m_sndtime.hours == -1 && m_istream)
PrepareToPlay();
return m_sndtime;
}
bool wxSndFileCodec::TranslateBuffer(wxSndBuffer& buf)
{
#define TMP_BUFSIZE 10240
wxUint32 buf_size;
wxStreamBuffer *tmp_buf;
wxSoundCodec *codec_in, *codec_out;
wxSoundDataFormat std_format;
if (!m_ostream || !buf.RestartBuffer(wxSND_OUTPUT))
return FALSE;
m_sndformat = buf.GetFormat();
codec_in = buf.GetCurrentCodec();
m_fdone = 0;
if (!PrepareToRecord(m_fsize))
return FALSE;
codec_out = GetCurrentCodec();
m_fsize = (int)(((float)buf.GetSize() / codec_in->GetByteRate()) *
codec_out->GetByteRate());
if (!PrepareToRecord(m_fsize))
return FALSE;
codec_out = GetCurrentCodec();
codec_in->InitIO(m_sndformat);
codec_out->InitIO(m_sndformat);
tmp_buf = new wxStreamBuffer(wxStreamBuffer::read_write);
tmp_buf->Fixed(TRUE);
tmp_buf->Flushable(FALSE);
tmp_buf->SetBufferIO(TMP_BUFSIZE);
m_fstate = wxSFILE_RECORDING;
while (m_fdone < m_fsize) {
tmp_buf->ResetBuffer();
codec_in->SetOutStream(tmp_buf);
codec_in->Decode();
tmp_buf->ResetBuffer();
codec_out->SetInStream(tmp_buf);
codec_out->Encode();
buf.OnBufferOutFinished();
}
delete tmp_buf;
m_fstate = wxSFILE_STOPPED;
return TRUE;
}
bool wxSndFileCodec::RestartBuffer(wxSndMode mode)
{
if (IsSet(wxSND_BUFLOCKED))
return FALSE;
m_fdone = 0;
m_fpos = 0;
if (mode == wxSND_OUTPUT && m_istream) {
m_fsize = PrepareToPlay();
m_fstate = wxSFILE_PLAYING;
return TRUE;
}
if (mode == wxSND_INPUT && m_ostream) {
m_fsize = 0;
m_fstate = wxSFILE_RECORDING;
return TRUE;
}
return FALSE;
}
wxUint32 wxSndFileCodec::GetSize() const
{
return m_fsize;
}
wxUint32 wxSndFileCodec::Available() const
{
return m_fsize-m_fpos;
}
//
// Simple API
//
static wxSoundDevice *dev_snd = NULL;
bool wxSndFileCodec::StartPlay()
{
if (!dev_snd)
dev_snd = new wxSoundDevice;
Play(*dev_snd);
return TRUE;
}
void wxSndFileCodec::StopPlay()
{
if (!dev_snd)
return;
Stop(*dev_snd);
m_fpos = 0;
}
class wxSoundModule : public wxModule {
DECLARE_DYNAMIC_CLASS(wxSoundModule)
public:
virtual bool OnInit() { return TRUE; }
virtual void OnExit() {
if (dev_snd)
delete dev_snd;
}
};
IMPLEMENT_DYNAMIC_CLASS(wxSoundModule, wxModule)

91
utils/wxMMedia/sndfile.h Normal file
View File

@@ -0,0 +1,91 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: sndfile.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
/* Real -*- C++ -*- */
#ifndef __SND_file_H__
#define __SND_file_H__
#ifdef __GNUG__
#pragma interface
#endif
#include "mmfile.h"
#include "sndsnd.h"
///
class wxSndFileCodec : public wxMMediaFile, public wxSndBuffer {
///
DECLARE_ABSTRACT_CLASS(wxSndFileCodec)
public:
typedef enum {
wxSFILE_STOPPED,
wxSFILE_PLAYING,
wxSFILE_RECORDING
} FileState;
protected:
wxUint32 m_fsize, m_fpos, m_fdone;
FileState m_fstate;
wxMMtime m_sndtime;
public:
///
wxSndFileCodec();
///
wxSndFileCodec(wxInputStream& s, bool preload, bool seekable);
///
wxSndFileCodec(wxOutputStream& s, bool seekable);
///
wxSndFileCodec(const wxString& fname);
///
virtual ~wxSndFileCodec();
///
void Play(wxSound& snd);
///
void Stop(wxSound& snd);
///
void Record(wxSound& snd,
const wxSoundDataFormat& format, wxUint32 seconds);
///
void OnNeedOutputData(char *data, wxUint32& size);
///
void OnBufferInFinished(char *iobuf, wxUint32& size);
///
virtual bool OnNeedData(char *buf, wxUint32 size) = 0;
///
virtual bool OnWriteData(char *buf, wxUint32 size) = 0;
///
virtual wxUint32 PrepareToPlay() = 0;
///
virtual bool PrepareToRecord(wxUint32 file_size) = 0;
///
virtual bool TranslateBuffer(wxSndBuffer& buf);
///
virtual bool RestartBuffer(wxSndMode mode);
///
virtual wxUint32 GetSize() const;
///
virtual wxUint32 Available() const;
///
virtual wxMMtime GetLength();
///
wxMMtime GetPosition();
///
virtual bool StartPlay();
///
virtual void StopPlay();
};
#endif

268
utils/wxMMedia/sndfrag.cpp Normal file
View File

@@ -0,0 +1,268 @@
////////////////////////////////////////////////////////////////////////////////
// Name: sndfrag.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "sndfrag.h"
#endif
#include <stdio.h>
#ifdef WX_PRECOMP
#include "wx_prec.h"
#else
#include "wx/wx.h"
#endif
#include "sndfrag.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
wxFragmentBuffer::wxFragmentBuffer(wxSound& io_drv)
: m_iodrv(&io_drv), m_maxoq(0), m_maxiq(0),
m_optrs(NULL), m_iptrs(NULL), m_lstoptrs(NULL), m_lstiptrs(NULL),
m_buf2free(FALSE), m_dontq(FALSE), m_freeing(FALSE)
{
}
wxFragmentBuffer::~wxFragmentBuffer()
{
}
void wxFragmentBuffer::AbortBuffer(wxSndBuffer *buf)
{
for (wxUint8 i=0;i<m_maxoq;i++)
if (m_lstoptrs[i].buffers->Member(buf)) {
if (m_lstoptrs[i].state == wxBUFFER_PLAYING)
// TODO: Do something.
;
m_lstoptrs[i].state = wxBUFFER_TOFREE;
}
for (wxUint8 i=0;i<m_maxiq;i++)
if (m_lstiptrs[i].buffers->Member(buf)) {
if (m_lstiptrs[i].state == wxBUFFER_PLAYING)
// Do something.
;
m_lstiptrs[i].state = wxBUFFER_TOFREE;
}
}
wxFragmentBuffer::wxFragBufPtr *wxFragmentBuffer::FindFreeBuffer(
wxFragBufPtr *list, wxUint8 max_queue)
{
if (!list)
return NULL;
for (wxUint8 i=0;i<max_queue;i++) {
if (list[i].state == wxBUFFER_FREE)
return &list[i];
}
return NULL;
}
bool wxFragmentBuffer::NotifyOutputBuffer(wxSndBuffer *buf)
{
wxFragBufPtr *ptr;
char *raw_buf;
wxUint32 rawbuf_size;
if (!m_iodrv->OnSetupDriver(*buf, wxSND_OUTPUT))
return FALSE;
while (1) {
// Find the first free (at least partly free) output buffer
ptr = FindFreeBuffer(m_lstoptrs, m_maxoq);
// No free : go out !
if (!ptr)
return FALSE;
// Find the end of the buffer
raw_buf = ptr->data + ptr->ptr;
rawbuf_size = ptr->size - ptr->ptr;
// Fill it up
buf->OnNeedOutputData(raw_buf, rawbuf_size);
// No data to fill the buffer: dequeue the current wxSndBuffer
if (!rawbuf_size) {
if (buf->IsNotSet(wxSND_KEEPQUEUED)) {
buf->Set(wxSND_UNQUEUEING);
m_iodrv->m_buffers.DeleteObject(buf);
}
return TRUE;
}
// Data: append it to the list
ptr->buffers->Append(buf);
ptr->ptr += rawbuf_size;
// Output buffer full: send it to the driver
if (ptr->ptr == ptr->size) {
ptr->state = wxBUFFER_FFILLED;
OnBufferFilled(ptr, wxSND_OUTPUT);
}
}
}
bool wxFragmentBuffer::NotifyInputBuffer(wxSndBuffer *buf)
{
wxFragBufPtr *ptr;
char *raw_buf;
wxUint32 rawbuf_size;
if (!m_iodrv->OnSetupDriver(*buf, wxSND_INPUT))
return FALSE;
while (1) {
ptr = FindFreeBuffer(m_lstiptrs, m_maxiq);
if (!ptr)
return FALSE;
raw_buf = ptr->data + ptr->ptr;
rawbuf_size = ptr->size - ptr->ptr;
rawbuf_size = (buf->Available() < rawbuf_size) ? buf->Available() : rawbuf_size;
if (!rawbuf_size) {
if (buf->IsNotSet(wxSND_KEEPQUEUED)) {
buf->Set(wxSND_UNQUEUEING);
m_iodrv->m_buffers.DeleteObject(buf);
}
// Get data now when there isn't anymore buffer in the queue
if (!LastBuffer() && ptr->ptr) {
ptr->state = wxBUFFER_FFILLED;
if (!OnBufferFilled(ptr, wxSND_INPUT))
return FALSE;
}
return TRUE;
}
ptr->buffers->Append(buf);
ptr->ptr += rawbuf_size;
// Input buffer full => get data
if (ptr->ptr == ptr->size) {
ptr->state = wxBUFFER_FFILLED;
if (!OnBufferFilled(ptr, wxSND_INPUT))
return FALSE;
}
}
return TRUE;
}
void wxFragmentBuffer::FreeBufToFree(bool force)
{
wxUint8 i;
// Garbage collecting
m_dontq = TRUE;
m_buf2free = FALSE;
for (i=0;i<m_maxoq;i++) {
if ((m_lstoptrs[i].state == wxBUFFER_TOFREE) ||
(force && m_lstoptrs[i].state == wxBUFFER_FFILLED))
ClearBuffer(&m_lstoptrs[i]);
}
for (i=0;i<m_maxiq;i++) {
if ((m_lstiptrs[i].state == wxBUFFER_TOFREE) ||
(force && m_lstoptrs[i].state == wxBUFFER_FFILLED))
ClearBuffer(&m_lstiptrs[i]);
}
m_dontq = FALSE;
}
void wxFragmentBuffer::ClearBuffer(wxFragBufPtr *ptr)
{
wxNode *node;
wxSndBuffer *buf;
char *data;
wxUint32 size, data_read;
data = ptr->data;
size = ptr->size;
node = ptr->buffers->First();
while (node) {
buf = (wxSndBuffer *)node->Data();
if (buf->GetMode() == wxSND_OUTPUT) {
buf->OnBufferOutFinished();
} else {
data_read = buf->OnBufferInFinished(data, size);
data += data_read;
size -= data_read;
}
if (buf->IsSet(wxSND_UNQUEUEING))
buf->Clear(wxSND_UNQUEUEING | wxSND_BUFLOCKED | wxSND_BUFREADY);
delete node;
node = ptr->buffers->First();
}
ptr->ptr = 0;
ptr->state = wxBUFFER_FREE;
}
void wxFragmentBuffer::OnBufferFinished(wxFragBufPtr *ptr)
{
wxNode *node;
wxSndBuffer *buf;
bool ret = TRUE;
if (m_freeing) {
ptr->state = wxBUFFER_TOFREE;
m_buf2free = TRUE;
return;
}
m_freeing = TRUE;
// Clean up the old buffer.
if (ptr && ptr->state != wxBUFFER_FREE)
ClearBuffer(ptr);
// Garbage collecting ...
if (m_buf2free)
FreeBufToFree();
// If we are queueing, return immediately.
if (m_dontq) {
m_freeing = FALSE;
return;
}
node = m_iodrv->m_buffers.First();
while (node && ret) {
buf = (wxSndBuffer *)node->Data();
node = node->Next();
buf->HardLock();
// Stop request on this buffer.
if (buf->IsSet(wxSND_BUFSTOP)) {
buf->Clear(wxSND_BUFSTOP);
continue;
}
if (buf->GetMode() == wxSND_OUTPUT)
ret = NotifyOutputBuffer(buf);
else
ret = NotifyInputBuffer(buf);
buf->HardUnlock();
}
m_freeing = FALSE;
}

103
utils/wxMMedia/sndfrag.h Normal file
View File

@@ -0,0 +1,103 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: sndfrag.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
#ifndef __SND_frag_H__
#define __SND_frag_H__
#ifdef __GNUG__
#pragma interface
#endif
#ifdef WX_PRECOMP
#include "wx_prec.h"
#else
#include "wx/wx.h"
#endif
#include "sndsnd.h"
///
class wxFragmentBuffer {
protected:
wxSound *m_iodrv;
///
wxUint8 m_maxoq, m_maxiq;
///
typedef enum {
wxBUFFER_FREE,
wxBUFFER_FFILLED,
wxBUFFER_TOFREE
} BufState;
public:
///
typedef struct {
char *data;
///
char *user_data;
///
wxUint32 size, ptr;
///
wxList *buffers;
///
BufState state;
} wxFragBufPtr;
protected:
///
wxFragBufPtr *m_optrs, *m_iptrs;
///
wxFragBufPtr *m_lstoptrs, *m_lstiptrs;
///
bool m_buf2free, m_dontq, m_freeing;
public:
///
wxFragmentBuffer(wxSound& io_drv);
///
virtual ~wxFragmentBuffer();
///
virtual void AllocIOBuffer() = 0;
///
virtual void FreeIOBuffer() = 0;
///
void AbortBuffer(wxSndBuffer *buf);
///
wxFragBufPtr *FindFreeBuffer(wxFragBufPtr *list, wxUint8 max_queue);
///
bool NotifyOutputBuffer(wxSndBuffer *buf);
///
bool NotifyInputBuffer(wxSndBuffer *buf);
///
void OnBufferFinished(wxFragBufPtr *ptr);
///
virtual bool OnBufferFilled(wxFragBufPtr *ptr, wxSndMode mode) = 0;
///
inline wxSndBuffer *LastBuffer() {
wxNode *node = m_iodrv->m_buffers.Last();
if (!node) return NULL;
return (wxSndBuffer *)node->Data();
}
///
inline wxSndBuffer *FirstBuffer() {
wxNode *node = m_iodrv->m_buffers.First();
if (!node) return NULL;
return (wxSndBuffer *)node->Data();
}
protected:
void FreeBufToFree(bool force = FALSE);
void ClearBuffer(wxFragBufPtr *ptr);
};
#endif

266
utils/wxMMedia/sndfrmt.cpp Normal file
View File

@@ -0,0 +1,266 @@
#ifdef __GNUG__
#pragma implementation "sndfrmt.h"
#endif
#include "sndsnd.h"
#include "sndfrmt.h"
#include "sndpcm.h"
#include <dmalloc.h>
// ----------------------------------------------------------------------------
// wxSoundDataFormat
// ----------------------------------------------------------------------------
wxSoundDataFormat::wxSoundDataFormat()
{
m_srate = 22050;
m_bps = 8;
m_channels = 1;
m_codno = 1;
m_codec = NULL;
m_codchange = FALSE;
m_codcreate = TRUE;
}
wxSoundDataFormat::~wxSoundDataFormat()
{
wxDELETE(m_codec);
}
void wxSoundDataFormat::SetChannels(int channels)
{
m_channels = channels;
}
void wxSoundDataFormat::SetBps(int bps)
{
m_bps = bps;
CodecChange();
}
void wxSoundDataFormat::SetSign(int sign)
{
m_sign = sign;
CodecChange();
}
void wxSoundDataFormat::SetByteOrder(int byteorder)
{
m_byteorder = byteorder;
CodecChange();
}
void wxSoundDataFormat::SetCodecNo(int codno)
{
m_codno = codno;
m_codchange = TRUE;
CodecChange();
}
wxSoundCodec *wxSoundDataFormat::GetCodec()
{
if (!m_codcreate)
return NULL;
if (m_codchange)
wxDELETEA(m_codec);
if (m_codec)
return m_codec;
m_codchange = FALSE;
m_codec = wxSoundCodec::Get(m_codno);
return m_codec;
}
void wxSoundDataFormat::CodecChange()
{
wxSoundCodec *codec = GetCodec();
if (!codec)
return;
switch (m_codno) {
case WXSOUND_PCM: {
wxSoundPcmCodec *pcm_codec = (wxSoundPcmCodec *)codec;
pcm_codec->SetBits(m_bps);
pcm_codec->SetByteOrder(m_byteorder);
pcm_codec->SetSign(m_sign);
break;
}
default:
break;
}
}
wxSoundDataFormat& wxSoundDataFormat::operator =(const wxSoundDataFormat& format)
{
wxDELETE(m_codec);
m_srate = format.m_srate;
m_bps = format.m_bps;
m_channels = format.m_channels;
m_codno = format.m_codno;
m_sign = format.m_sign;
m_byteorder = format.m_byteorder;
return *this;
}
bool wxSoundDataFormat::operator ==(const wxSoundDataFormat& format) const
{
if (m_codno != format.m_codno || m_srate != format.m_srate ||
m_bps != format.m_bps || m_channels != format.m_channels)
return FALSE;
if (m_codno == WXSOUND_PCM &&
(m_sign != format.m_sign || m_byteorder != format.m_byteorder))
return FALSE;
return TRUE;
}
// ----------------------------------------------------------------------------
// wxSoundCodec
// ----------------------------------------------------------------------------
#include "sndpcm.h"
//#include "sndadpcm.h"
//#include "sndalaw.h"
#include "sndmulaw.h"
static wxClassInfo *l_sound_formats[] = {
NULL,
CLASSINFO(wxSoundPcmCodec),
NULL, // CLASSINFO(wxSoundAdpcmCodec),
NULL,
NULL,
NULL,
NULL, // CLASSINFO(wxSoundAlawCodec),
NULL // CLASSINFO(wxSoundMulawCodec)
};
static int l_nb_formats = WXSIZEOF(l_sound_formats);
wxSoundCodec::wxSoundCodec()
{
m_in_sound = NULL;
m_out_sound = NULL;
m_init = TRUE;
}
wxSoundCodec::~wxSoundCodec()
{
}
void wxSoundCodec::InitIO(const wxSoundDataFormat& format)
{
m_io_format = format;
}
void wxSoundCodec::InitMode(int mode)
{
wxStreamBuffer *buf_snd;
m_mode = (mode == 0) ? ENCODING : DECODING;
if (!m_chain_codec) {
if (mode == ENCODING) {
m_out_sound = new wxStreamBuffer(*this, wxStreamBuffer::write);
m_out_sound->SetBufferIO(1024);
} else {
m_in_sound = new wxStreamBuffer(*this, wxStreamBuffer::read);
m_in_sound->SetBufferIO(1024);
}
}
if (m_chain_codec) {
if (m_chain_before) {
m_chain_codec->SetInStream(m_in_sound);
buf_snd = new wxStreamBuffer(wxStreamBuffer::read_write);
buf_snd->Fixed(FALSE);
m_chain_codec->SetOutStream(buf_snd);
m_chain_codec->Decode();
buf_snd->Seek(0, wxFromStart);
m_in_sound = buf_snd;
} else {
buf_snd = new wxStreamBuffer(wxStreamBuffer::read_write);
buf_snd->Fixed(FALSE);
m_chain_codec->SetInStream(buf_snd);
m_chain_codec->SetOutStream(m_out_sound);
m_out_sound = buf_snd;
buf_snd->Seek(0, wxFromStart);
}
}
}
void wxSoundCodec::ExitMode()
{
if (m_chain_codec) {
if (m_chain_before) {
delete m_in_sound;
m_in_sound = m_chain_codec->GetInStream();
} else {
delete m_out_sound;
m_out_sound = m_chain_codec->GetOutStream();
}
}
}
bool wxSoundCodec::ChainCodecBefore(wxSoundDataFormat& format)
{
m_chain_codec = format.GetCodec();
if (!m_chain_codec)
return FALSE;
m_chain_before = TRUE;
return TRUE;
}
bool wxSoundCodec::ChainCodecAfter(wxSoundDataFormat& format)
{
m_chain_codec = format.GetCodec();
if (!m_chain_codec)
return FALSE;
m_chain_before = FALSE;
return TRUE;
}
void wxSoundCodec::CopyToOutput()
{
m_out_sound->Write(m_in_sound);
}
size_t wxSoundCodec::Available()
{
return m_io_sndbuf->Available();
}
size_t wxSoundCodec::OnSysRead(void *buffer, size_t bsize)
{
wxUint32 s = bsize;
m_io_sndbuf->OnNeedOutputData((char *)buffer, s);
return bsize;
}
size_t wxSoundCodec::OnSysWrite(const void *buffer, size_t bsize)
{
wxUint32 s = bsize;
m_io_sndbuf->OnBufferInFinished((char *)buffer, s);
return bsize;
}
wxSoundCodec *wxSoundCodec::Get(int no)
{
if (no < 0 || no >= l_nb_formats)
return NULL;
if (!l_sound_formats[no])
return NULL;
return (wxSoundCodec *)l_sound_formats[no]->CreateObject();
}

119
utils/wxMMedia/sndfrmt.h Normal file
View File

@@ -0,0 +1,119 @@
#ifndef __SNDFRMT_H__
#define __SNDFRMT_H__
#ifdef __GNUG__
#pragma interface
#endif
#include <wx/object.h>
class wxSndBuffer;
// Standard Microsoft types (why change ?)
#define WXSOUND_PCM 0x0001
#define WXSOUND_ADPCM 0x0002
#define WXSOUND_ALAW 0x0006
#define WXSOUND_ULAW 0x0007
class wxSoundCodec;
class wxSoundDataFormat {
public:
wxSoundDataFormat();
~wxSoundDataFormat();
void SetSampleRate(int srate) { m_srate = srate; }
void SetChannels(int channels);
void SetStereo(bool on);
void SetCodecNo(int no);
void SetCodecCreate(bool create) { m_codcreate = create; }
int GetSampleRate() const { return m_srate; }
int GetChannels() const { return m_channels; }
bool GetStereo() const { return (m_channels == 2); }
int GetCodecNo() const { return m_codno; }
wxSoundCodec *GetCodec();
wxSoundDataFormat& operator =(const wxSoundDataFormat& format);
bool operator ==(const wxSoundDataFormat& format) const;
bool operator !=(const wxSoundDataFormat& format) const
{ return !(operator ==(format)); }
/// PCM format
void SetByteOrder(int order);
void SetSign(int sign);
int GetByteOrder() const { return m_byteorder; }
int GetSign() const { return m_sign; }
void SetBps(int bps);
int GetBps() const { return m_bps; }
protected:
void CodecChange();
protected:
int m_srate, m_bps, m_channels, m_codno;
int m_byteorder, m_sign;
bool m_codchange, m_codcreate;
wxSoundCodec *m_codec;
};
class wxSoundCodec : public wxObject, public wxStreamBase {
DECLARE_ABSTRACT_CLASS(wxSoundCodec)
public:
wxSoundCodec();
virtual ~wxSoundCodec();
void SetIOBuffer(wxSndBuffer *sndbuf) { m_io_sndbuf = sndbuf; }
size_t Available();
void InitIO(const wxSoundDataFormat& format);
void InitMode(int mode);
void ExitMode();
inline void SetInStream(wxStreamBuffer *s)
{ m_in_sound = s; }
inline void SetOutStream(wxStreamBuffer *s)
{ m_out_sound = s; }
inline wxStreamBuffer *GetInStream() const { return m_in_sound; }
inline wxStreamBuffer *GetOutStream() const { return m_out_sound; }
inline bool Good() const { return (m_in_sound->Stream()->LastError() == wxStream_NOERROR) && (m_out_sound->Stream()->LastError() == wxStream_NOERROR); }
virtual size_t GetByteRate() const = 0;
virtual wxSoundDataFormat GetPreferredFormat(int codec = 0) const = 0;
virtual void Decode() = 0;
virtual void Encode() = 0;
static wxSoundCodec *Get(int no);
protected:
void CopyToOutput();
unsigned short Convert8_16(unsigned char s) { return (s & 0xff) << 8; }
unsigned char Convert16_8(unsigned short s) { return (s & 0xff00) >> 8; }
bool ChainCodecBefore(wxSoundDataFormat& cod_to);
bool ChainCodecAfter(wxSoundDataFormat& cod_to);
// -------------
// wxStream part
// -------------
size_t OnSysWrite(const void *buffer, size_t bsize);
size_t OnSysRead(void *buffer, size_t bsize);
protected:
wxSndBuffer *m_io_sndbuf;
wxSoundDataFormat m_io_format;
wxStreamBuffer *m_in_sound, *m_out_sound;
wxSoundCodec *m_chain_codec;
bool m_init, m_chain_before;
enum {
ENCODING = 0,
DECODING
} m_mode;
};
#endif

View File

@@ -0,0 +1,85 @@
#ifdef __GNUG__
#pragma implementation "sndmulaw.h"
#endif
#include "sndsnd.h"
#include "sndfrmt.h"
#include "sndmulaw.h"
#include "adpcm/g72x.h"
wxSoundMulawCodec::wxSoundMulawCodec()
: wxSoundCodec()
{
}
wxSoundMulawCodec::~wxSoundMulawCodec()
{
}
void wxSoundMulawCodec::Decode()
{
int smp;
wxSoundDataFormat pref_frmt;
pref_frmt = GetPreferredFormat(0);
if (m_io_format != pref_frmt)
ChainCodecAfter(pref_frmt);
InitMode(DECODING);
while (!Good()) {
smp = ulaw2linear(m_in_sound->GetChar());
#ifdef USE_BE_MACH
m_out_sound->PutChar((smp & 0xff00) >> 8);
m_out_sound->PutChar(smp & 0xff);
#else
m_out_sound->PutChar(smp & 0xff);
m_out_sound->PutChar((smp & 0xff00) >> 8);
#endif
}
}
void wxSoundMulawCodec::Encode()
{
int smp;
wxSoundDataFormat pref_frmt;
pref_frmt = GetPreferredFormat(0);
if (m_io_format != pref_frmt)
ChainCodecBefore(pref_frmt);
InitMode(ENCODING);
while (!Good()) {
#ifdef USE_BE_MACH
smp = ((unsigned short)m_in_sound->GetChar()) << 8;
smp |= m_in_sound->GetChar() & 0xff;
#else
smp = m_in_sound->GetChar() & 0xff;
smp |= ((unsigned short)m_in_sound->GetChar()) << 8;
#endif
m_out_sound->PutChar(linear2ulaw(smp));
}
}
size_t wxSoundMulawCodec::GetByteRate() const
{
return m_srate;
}
wxSoundDataFormat wxSoundMulawCodec::GetPreferredFormat(int WXUNUSED(no)) const
{
wxSoundDataFormat format;
format.SetCodecNo(WXSOUND_PCM);
format.SetSampleRate(m_srate);
format.SetBps(16);
format.SetChannels(1);
format.SetSign(wxSND_SAMPLE_SIGNED);
#ifdef USE_BE_MACH
format.SetByteOrder(wxSND_SAMPLE_BE);
#else
format.SetByteOrder(wxSND_SAMPLE_LE);
#endif
return format;
}

28
utils/wxMMedia/sndmulaw.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef __MEDIA_SNDMULAW_H__
#define __MEDIA_SNDMULAW_H__
#ifdef __GNUG__
#pragma interface
#endif
#include "sndfrmt.h"
class wxSoundMulawCodec : public wxSoundCodec {
DECLARE_DYNAMIC_CLASS(wxSoundMulawCodec)
public:
wxSoundMulawCodec();
virtual ~wxSoundMulawCodec();
void SetSampleRate(int srate) { m_srate = srate; }
size_t GetByteRate() const;
wxSoundDataFormat GetPreferredFormat(int codec = 0) const;
void Decode();
void Encode();
protected:
int m_srate;
};
#endif

216
utils/wxMMedia/sndpcm.cpp Normal file
View File

@@ -0,0 +1,216 @@
#ifdef __GNUG__
#pragma implementation "sndpcm.h"
#endif
#include "sndsnd.h"
#include "sndpcm.h"
#include <dmalloc.h>
#define WX_BIG_ENDIAN 0
wxSoundPcmCodec::wxSoundPcmCodec()
: wxSoundCodec()
{
m_orig_format.SetCodecCreate(FALSE);
m_orig_format.SetCodecNo(1);
m_char_bool = FALSE;
}
wxSoundPcmCodec::~wxSoundPcmCodec()
{
}
size_t wxSoundPcmCodec::GetByteRate() const
{
return (m_orig_format.GetBps()/8)*
m_orig_format.GetSampleRate()*
m_orig_format.GetChannels();
}
wxSoundDataFormat wxSoundPcmCodec::GetPreferredFormat(int codec) const
{
wxSoundDataFormat prefFormat;
prefFormat = m_orig_format;
prefFormat.SetCodecNo(WXSOUND_PCM);
return prefFormat;
}
// ---------------------------------------------------------------------------
// Main part of the decoder
// ---------------------------------------------------------------------------
void wxSoundPcmCodec::Decode()
{
InitMode(DECODING);
if (m_io_format == m_orig_format) {
CopyToOutput();
ExitMode();
return;
}
// Swap bytes
switch (m_io_format.GetBps()) {
case 8:
InputSign8();
break;
case 16:
InputSwapAndSign16();
break;
case 32:
case 64:
default:
break;
}
ExitMode();
}
// ---------------------------------------------------------------------------
// Change the sign of a 8-bit sample.
#define GET() (m_in_sound->GetChar())
#define PUT(c) (m_out_sound->PutChar(c))
#define OUT_ERROR() (out->LastError() == wxStream_NOERROR)
#define IN_ERROR() (in->LastError() == wxStream_NOERROR)
void wxSoundPcmCodec::InputSign8()
{
unsigned char signer = 0;
wxStreamBase *in = m_out_sound->Stream(), *out = m_in_sound->Stream();
if (m_io_format.GetSign() != m_orig_format.GetSign())
signer = 128;
while (IN_ERROR() && OUT_ERROR())
PUT(GET() + signer);
}
// ---------------------------------------------------------------------------
// Swap bytes and change the sign of a 16-bit sample.
void wxSoundPcmCodec::InputSwapAndSign16()
{
unsigned short signer1 = 0, signer2 = 0;
wxStreamBase *in = m_out_sound->Stream(), *out = m_in_sound->Stream();
bool swap = (m_io_format.GetByteOrder() != m_orig_format.GetByteOrder());
char temp;
if (m_io_format.GetSign() != m_orig_format.GetSign()) {
if (m_io_format.GetByteOrder() == wxSND_SAMPLE_LE)
signer2 = 0x80;
else
signer1 = 0x80;
}
if (swap) {
while (IN_ERROR() && OUT_ERROR()) {
temp = GET() ^ signer1;
PUT(GET() ^ signer2);
if (OUT_ERROR()) {
m_char_bool = TRUE;
m_char_stack = temp;
break;
}
PUT(temp);
}
} else {
while (IN_ERROR() && OUT_ERROR()) {
PUT(GET() ^ signer1);
if (OUT_ERROR()) {
m_char_bool = TRUE;
m_char_stack = temp;
break;
}
PUT(GET() ^ signer2);
}
}
}
// ---------------------------------------------------------------------------
// Encoder part.
// ---------------------------------------------------------------------------
void wxSoundPcmCodec::OutputSign8()
{
wxStreamBase *in = m_out_sound->Stream(), *out = m_in_sound->Stream();
unsigned char signer = 0;
if (m_io_format.GetSign() != m_orig_format.GetSign())
signer = 128;
while (IN_ERROR() && OUT_ERROR())
PUT((char)(GET() + signer));
}
// ---------------------------------------------------------------------------
void wxSoundPcmCodec::OutputSwapAndSign16()
{
bool swap = (m_io_format.GetByteOrder() != m_orig_format.GetByteOrder());
unsigned short signer1 = 0, signer2 = 0;
char temp;
wxStreamBase *in = m_out_sound->Stream(), *out = m_in_sound->Stream();
if (m_char_bool) {
PUT(GET());
PUT(m_char_stack);
m_char_bool = FALSE;
}
if (m_io_format.GetSign() != m_orig_format.GetSign())
if (m_io_format.GetByteOrder() == wxSND_SAMPLE_LE)
signer1 = 0x80;
else
signer2 = 0x80;
if (swap) {
while (IN_ERROR()) {
temp = GET();
PUT(GET() ^ signer1);
if (OUT_ERROR()) {
m_char_stack = temp ^ signer2;
m_char_bool = TRUE;
break;
}
PUT(temp ^ signer2);
}
} else {
while (IN_ERROR()) {
PUT(GET() ^ signer1);
if (!OUT_ERROR()) {
m_char_stack = GET() ^ signer2;
m_char_bool = TRUE;
break;
}
PUT(GET() ^ signer2);
}
}
}
// ---------------------------------------------------------------------------
void wxSoundPcmCodec::Encode()
{
InitMode(ENCODING);
if (m_io_format == m_orig_format) {
CopyToOutput();
ExitMode();
return;
}
// Swap bytes
switch (m_io_format.GetBps()) {
case 8:
OutputSign8();
break;
case 16:
OutputSwapAndSign16();
break;
case 32:
case 64:
default:
break;
}
ExitMode();
}

39
utils/wxMMedia/sndpcm.h Normal file
View File

@@ -0,0 +1,39 @@
#ifndef __SNDPCM_H__
#define __SNDPCM_H__
#ifdef __GNUG__
#pragma interface
#endif
#include "sndfrmt.h"
class wxSoundPcmCodec : public wxSoundCodec {
DECLARE_DYNAMIC_CLASS(wxSoundPcmCodec)
public:
wxSoundPcmCodec();
virtual ~wxSoundPcmCodec();
void SetSampleRate(int srate) { m_orig_format.SetSampleRate(srate); }
void SetBits(int bits) { m_orig_format.SetBps(bits); }
void SetByteOrder(int order) { m_orig_format.SetByteOrder(order); }
void SetSign(int sample_sign) { m_orig_format.SetSign(sample_sign); }
size_t GetByteRate() const;
wxSoundDataFormat GetPreferredFormat(int codec = 0) const;
void Decode();
void Encode();
protected:
void InputSign8();
void InputSwapAndSign16();
void OutputSign8();
void OutputSwapAndSign16();
protected:
wxSoundDataFormat m_orig_format;
char m_char_stack;
bool m_char_bool;
};
#endif

264
utils/wxMMedia/sndsnd.cpp Normal file
View File

@@ -0,0 +1,264 @@
////////////////////////////////////////////////////////////////////////////////
// Name: sndsnd.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "sndsnd.h"
#endif
#ifdef WX_PRECOMP
#include "wx_prec.h"
#else
#include "wx/wx.h"
#endif
#include "sndsnd.h"
#include "sndfrmt.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#define PROCESS_EVENT() wxYield()
// #define PROCESS_EVENT()
// ----------------------------------------------------------------------------
// wxSndBuffer: base sound buffer class
// ----------------------------------------------------------------------------
wxSndBuffer::wxSndBuffer()
: m_sndmode(wxSND_OUTPUT), m_sndflags(0), m_sndoutput(NULL), m_sndcodec(NULL)
{
}
wxSndBuffer::~wxSndBuffer()
{
}
void wxSndBuffer::Set(wxSndFlags flags)
{
m_sndflags |= flags;
if ((m_sndflags & wxSND_BUFAUTO) && (flags & wxSND_BUFREADY))
m_sndoutput->QueueBuffer(*this);
}
void wxSndBuffer::SetError(wxSndError error)
{
if (error == wxSND_NOERROR)
Clear(wxSND_BUFERR);
else
Set(wxSND_BUFERR);
m_snderror = error;
}
wxSndError wxSndBuffer::GetError()
{
if (IsNotSet(wxSND_BUFERR))
return wxSND_NOERROR;
Clear(wxSND_BUFERR);
return m_snderror;
}
void wxSndBuffer::OnPlayFinished()
{
}
void wxSndBuffer::OnBufferOutFinished()
{
}
void wxSndBuffer::OnBufferInFinished(char *WXUNUSED(iobuf),
wxUint32& WXUNUSED(size))
{
}
bool wxSndBuffer::Wait()
{
if (IsNotSet(wxSND_BUFLOCKED))
return FALSE;
while (IsSet(wxSND_BUFLOCKED))
PROCESS_EVENT();
return IsNotSet(wxSND_BUFERR);
}
void wxSndBuffer::HardLock()
{
m_mutex.Lock();
}
void wxSndBuffer::HardUnlock()
{
m_mutex.Unlock();
}
void wxSndBuffer::ChangeCodec(int no)
{
wxDELETE(m_sndcodec);
m_sndformat.SetCodecNo(no);
m_sndcodec = m_sndformat.GetCodec();
m_sndcodec->SetIOBuffer(this);
}
// ----------------------------------------------------------------------------
// wxSndSimpleBuffer: the simplest sound buffer
// ----------------------------------------------------------------------------
wxSndSimpleBuffer::wxSndSimpleBuffer(char *buffer, wxUint32 bufsize,
wxSndMode mode)
: wxSndBuffer()
{
m_sndbuf = buffer;
m_sndsize = bufsize;
m_sndmode = mode;
m_sndptr = 0;
}
wxSndSimpleBuffer::~wxSndSimpleBuffer()
{
}
void wxSndSimpleBuffer::OnNeedOutputData(char *iobuf, wxUint32& size)
{
char *buf = m_sndbuf + m_sndptr;
wxUint32 nbdata_left = m_sndsize - m_sndptr;
if (m_sndptr >= m_sndsize) {
size = 0;
return;
}
if (size > nbdata_left)
size = nbdata_left;
m_sndptr += size;
memcpy(iobuf, buf, size);
}
void wxSndSimpleBuffer::OnBufferOutFinished()
{
if (m_sndptr >= m_sndsize)
OnPlayFinished();
}
void wxSndSimpleBuffer::OnBufferInFinished(char *iobuf, wxUint32& size)
{
char *raw_buf = m_sndbuf + m_sndptr;
wxUint32 data_left = m_sndsize - m_sndptr;
if (!data_left) {
size = 0;
return;
}
if (size > data_left)
size = data_left;
memcpy(raw_buf, iobuf, size);
m_sndptr += size;
}
void wxSndSimpleBuffer::SetData(char *buffer, wxUint32 bufsize,
wxSndMode mode)
{
m_sndbuf = buffer;
m_sndsize = bufsize;
m_sndmode = mode;
}
bool wxSndSimpleBuffer::RestartBuffer(wxSndMode mode)
{
m_sndptr = 0;
return TRUE;
}
wxUint32 wxSndSimpleBuffer::GetSize() const
{
return m_sndsize;
}
wxUint32 wxSndSimpleBuffer::Available() const
{
return m_sndsize - m_sndptr;
}
// ----------------------------------------------------------------------------
// wxSound: base sound driver implementation
// ----------------------------------------------------------------------------
wxSound::wxSound()
: wxObject(),
m_lastbuf(NULL), m_sndcbk(NULL), m_snderror(wxSND_NOERROR)
{
m_buffers.Clear();
}
wxSound::~wxSound()
{
wxNode *node = m_buffers.First();
while (node) {
wxSndBuffer *buf = (wxSndBuffer *)node->Data();
buf->Clear(wxSND_BUFLOCKED);
}
}
bool wxSound::QueueBuffer(wxSndBuffer& buf)
{
if (buf.IsSet(wxSND_BUFLOCKED) || buf.IsNotSet(wxSND_BUFREADY))
return FALSE;
buf.Set(wxSND_BUFLOCKED);
buf.SetOutput(*this);
m_buffers.Append(&buf);
return Wakeup(buf);
}
bool wxSound::UnqueueBuffer(wxSndBuffer& buf)
{
wxNode *node;
if (buf.IsNotSet(wxSND_BUFLOCKED))
return FALSE;
node = m_buffers.Member(&buf);
if (!node)
return FALSE;
StopBuffer(buf);
node = m_buffers.Member(&buf);
if (node)
delete node;
return TRUE;
}
void wxSound::Callback(wxSndCallback cbk)
{
m_sndcbk = cbk;
}
void wxSound::SetClientData(char *cdata)
{
m_cdata = cdata;
}
void wxSound::OnPlayBuffer(wxSndBuffer& buf)
{
m_lastbuf = &buf;
if (m_sndcbk)
m_sndcbk(*this, buf, m_cdata);
}

275
utils/wxMMedia/sndsnd.h Normal file
View File

@@ -0,0 +1,275 @@
/* Real -*- C++ -*- */
// /////////////////////////////////////////////////////////////////////////////
// Name: sndsnd.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
#ifndef __WX_SND_SOUND_H__
#define __WX_SND_SOUND_H__
#ifdef __GNUG__
#pragma interface
#endif
#ifdef WX_PRECOMP
#include "wx_prec.h"
#else
#include "wx/wx.h"
#endif
#include <wx/thread.h>
#include "sndfrmt.h"
#include "mmtype.h"
class wxSound;
class wxSndBuffer;
typedef enum {
wxSND_OUTPUT,
wxSND_INPUT,
wxSND_DUPLEX,
wxSND_OTHER_IO
} /// The possible sound output modes
wxSndMode;
typedef enum {
wxSND_NOERROR = 0,
wxSND_NOCAPS,
wxSND_CANTOPEN,
wxSND_NOMEM,
wxSND_READERR,
wxSND_WRITEERR,
wxSND_CANTSET
} /// Sound errors
wxSndError;
/// Sound callback
typedef void (*wxSndCallback)(wxSound&, wxSndBuffer&, char *);
/// Sound flags
typedef wxUint16 wxSndFlags;
/** @name Sound buffer flags */
/// buffer ready
#define wxSND_BUFREADY 0x0001
/// an error occured
#define wxSND_BUFERR 0x0002
/// buffer is in use
#define wxSND_BUFLOCKED 0x0004
/// the driver mustn't unqueue it
#define wxSND_KEEPQUEUED 0x0008
/// automatic: when BUFREADY is set play the buffer
#define wxSND_BUFAUTO 0x0010
///
#define wxSND_UNFINISHED 0x0020
/// buffer is nearly being unqueued
#define wxSND_UNQUEUEING 0x0040
/// driver wants the buffer stop
#define wxSND_BUFSTOP 0x0080
/// buffer will loop
#define wxSND_LOOP 0x0100
/** @name Sound data format */
/// little endian
#define wxSND_SAMPLE_LE 0
/// big endian
#define wxSND_SAMPLE_BE 1
/// unsigned samples
#define wxSND_SAMPLE_UNSIGNED 0
/// signed samples
#define wxSND_SAMPLE_SIGNED 1
/** @name wxSndBuffer
* @memo wxSndBuffer is the basic class for all the sound codec.
* @author Guilhem Lavaux
*/
class wxSndBuffer : public wxObject {
/// It is an abstract class
DECLARE_ABSTRACT_CLASS(wxSndBuffer)
protected:
wxMutex m_mutex;
/// output mode
wxSndMode m_sndmode;
/// last error
wxSndError m_snderror;
/// some flag
wxSndFlags m_sndflags;
/// last sound driver used
wxSound *m_sndoutput;
/// sound data format
wxSoundDataFormat m_sndformat;
/// current sound codec
wxSoundCodec *m_sndcodec;
public:
/** @name constructor and destructor */
//@{
/// Construct an uninitialized wxSndBuffer
wxSndBuffer();
/// Destroy
virtual ~wxSndBuffer();
//@}
/** @name Functions returning the current state */
//@{
/// @return current mode
inline wxSndMode GetMode() const { return m_sndmode; }
/// @return sound data format
inline wxSoundDataFormat& GetFormat() { return m_sndformat; }
/// @return the size of the buffer
virtual wxUint32 GetSize() const = 0;
/// @return bytes left
virtual wxUint32 Available() const = 0;
/** enable the specified flags
* @param flags
*/
void Set(wxSndFlags flags);
/** disable the specified flags
* @param flags
*/
inline void Clear(wxSndFlags flags)
{ m_sndflags &= ~flags; }
/** Check if the specified flags is set
* @param flags
* @return TRUE if all flags is set
*/
inline bool IsSet(wxSndFlags flags) const
{ return ((m_sndflags & flags) == flags); }
/** Check if the specified flags is not set
* @param flags
* @return TRUE if at least one flag is not set
*/
inline bool IsNotSet(wxSndFlags flags) const
{ return ((m_sndflags & flags) != flags); }
/** Check if the buffer is currently being played
* @return TRUE
if the buffer is being played
*/
inline bool IsPlaying() const
{ return IsSet(wxSND_BUFLOCKED); }
//@}
///
inline void SetOutput(wxSound& snd)
{ m_sndoutput = &snd; }
///
inline wxSoundCodec *GetCurrentCodec() const
{ return m_sndcodec; }
///
void HardLock();
///
void HardUnlock();
///
wxSndError GetError();
///
void SetError(wxSndError err);
///
virtual bool Wait();
///
virtual bool RestartBuffer(wxSndMode mode) = 0;
///
virtual bool Abort() { return TRUE; }
///
virtual void OnPlayFinished();
/** Data exchanging functions */
//@{
///
virtual void OnNeedOutputData(char *io_buf, wxUint32& size) = 0;
///
virtual void OnBufferOutFinished();
///
virtual void OnBufferInFinished(char *iobuf, wxUint32& size);
//@}
protected:
void ChangeCodec(int no);
};
class wxSndSimpleBuffer : public wxSndBuffer {
DECLARE_DYNAMIC_CLASS(wxSndSimpleBuffer)
protected:
/// sound buffer
char *m_sndbuf;
/// size of the sound buffer
wxUint32 m_sndsize;
/// current position in the sound buffer
wxUint32 m_sndptr;
public:
wxSndSimpleBuffer(char *buffer = NULL, wxUint32 bufsize = 0,
wxSndMode mode = wxSND_OUTPUT);
virtual ~wxSndSimpleBuffer();
void SetData(char *buffer, wxUint32 bufsize,
wxSndMode mode = wxSND_OUTPUT);
inline void SetSoundFormat(const wxSoundDataFormat& format);
void OnNeedOutputData(char *io_buf, wxUint32& size);
void OnNeedInputData(wxUint32& size);
void OnBufferOutFinished();
void OnBufferInFinished(char *iobuf, wxUint32& size);
bool RestartBuffer(wxSndMode mode);
wxUint32 GetSize() const;
wxUint32 Available() const;
};
///
class wxSound : public wxObject {
///
DECLARE_ABSTRACT_CLASS(wxSound)
protected:
friend class wxFragmentBuffer;
///
wxSndBuffer *m_lastbuf;
///
wxList m_buffers;
///
wxSndCallback m_sndcbk;
///
wxSndError m_snderror;
///
char *m_cdata;
public:
///
wxSound();
///
virtual ~wxSound();
///
virtual bool QueueBuffer(wxSndBuffer& buf);
///
virtual bool UnqueueBuffer(wxSndBuffer& buf);
///
inline wxSndBuffer *LastBufferPlayed()
{ return m_lastbuf; }
///
wxSndError GetError() { return m_snderror; }
///
void Callback(wxSndCallback cbk);
///
void SetClientData(char *cdata);
///
virtual void OnPlayBuffer(wxSndBuffer& buf);
protected:
///
virtual bool Wakeup(wxSndBuffer& buf) = 0;
///
virtual void StopBuffer(wxSndBuffer& buf) = 0;
///
virtual inline bool OnSetupDriver(wxSndBuffer& WXUNUSED(buf),
wxSndMode WXUNUSED(mode))
{ return TRUE; }
};
#endif

268
utils/wxMMedia/snduss.cpp Normal file
View File

@@ -0,0 +1,268 @@
////////////////////////////////////////////////////////////////////////////////
// Name: snduss.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "snduss.h"
#endif
#include <sys/soundcard.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <dmalloc.h>
#include "wx/app.h"
#include "wx/utils.h"
#define WXMMEDIA_INTERNAL
#include "snduss.h"
#include "sndfrmt.h"
wxUssSound::wxUssSound()
: wxSound(),
m_srate(0), m_bps(0), m_stereo(0),
m_mode(wxSND_OTHER_IO),
m_stop_thrd(TRUE), m_sleeping(FALSE)
{
m_fd = -1;
m_ussformat.SetCodecNo(WXSOUND_PCM);
m_ussformat.SetSign(wxSND_SAMPLE_SIGNED);
m_ussformat.SetByteOrder(wxSND_SAMPLE_LE);
m_sndbuf = new wxStreamBuffer(wxStreamBuffer::read_write);
m_sndbuf->Flushable(FALSE);
m_sndbuf->Fixed(TRUE);
}
wxUssSound::~wxUssSound()
{
if (!m_stop_thrd) {
m_stop_thrd = TRUE;
if (m_sleeping) {
m_sleep_mtx.Lock();
m_sleep_cond.Signal();
m_sleep_mtx.Unlock();
}
Join();
}
if (m_fd != -1)
close(m_fd);
}
bool wxUssSound::Wakeup(wxSndBuffer& WXUNUSED(buf))
{
printf("Waking up (wxUssSound::Wakeup) ...\n");
if (m_stop_thrd) {
m_stop_thrd = FALSE;
Entry();
// wxThread::Create();
}
if (m_sleeping) {
m_sleep_mtx.Lock();
m_sleep_cond.Signal();
m_sleep_mtx.Unlock();
}
return TRUE;
}
void wxUssSound::StopBuffer(wxSndBuffer& buf)
{
buf.HardLock();
buf.Set(wxSND_BUFSTOP);
buf.HardUnlock();
while (buf.IsSet(wxSND_BUFSTOP))
wxYield();
// usleep(0);
}
void wxUssSound::USS_Sleep()
{
bool ret;
printf("Asleeping ...\n");
m_sleeping = TRUE;
m_sleep_mtx.Lock();
ret = m_sleep_cond.Wait(m_sleep_mtx, 10, 0);
m_sleep_mtx.Unlock();
m_sleeping = FALSE;
printf("Waking up ...\n");
if (!ret)
m_stop_thrd = TRUE;
}
bool wxUssSound::DoInput(wxSndBuffer *buf)
{
wxUint32 bufsize;
wxSoundCodec *codec = buf->GetFormat().GetCodec();
m_sndbuf->ResetBuffer();
codec->SetInStream(m_sndbuf);
codec->InitIO(m_ussformat);
bufsize = codec->Available();
if (bufsize > m_max_bufsize)
bufsize = m_max_bufsize;
if (!bufsize) {
buf->Clear(wxSND_BUFLOCKED | wxSND_BUFREADY);
return false;
}
read(m_fd, m_sndbuf, bufsize);
codec->Encode();
return true;
}
bool wxUssSound::DoOutput(wxSndBuffer *buf)
{
wxSoundCodec *codec = buf->GetCurrentCodec();
m_sndbuf->ResetBuffer();
codec->SetOutStream(m_sndbuf);
codec->InitIO(m_ussformat);
if (!codec->Available()) {
buf->Clear(wxSND_BUFLOCKED | wxSND_BUFREADY);
return false;
}
codec->Decode();
write(m_fd, m_sndbuf, m_sndbuf->GetIntPosition());
// Well ... it's not accurate ! :-|
buf->OnBufferOutFinished();
return true;
}
void *wxUssSound::Entry()
{
wxNode *node;
wxSndBuffer *buf;
while (!m_stop_thrd) {
node = m_buffers.First();
if (!node) {
USS_Sleep();
continue;
}
buf = (wxSndBuffer *)node->Data();
if (!OnSetupDriver(*buf, buf->GetMode()))
continue;
buf->HardLock();
if (buf->IsSet(wxSND_BUFSTOP)) {
buf->HardUnlock();
delete node;
continue;
}
switch(m_mode) {
case wxSND_INPUT:
if (!DoInput(buf))
delete node;
break;
case wxSND_OUTPUT:
if (!DoOutput(buf))
delete node;
break;
case wxSND_DUPLEX:
case wxSND_OTHER_IO:
break;
}
buf->HardUnlock();
}
return NULL;
}
bool wxUssSound::OnSetupDriver(wxSndBuffer& buf, wxSndMode WXUNUSED(mode))
{
wxSoundDataFormat format;
wxSoundCodec *codec;
codec = buf.GetFormat().GetCodec();
format = codec->GetPreferredFormat(WXSOUND_PCM);
if ((format.GetSampleRate() != m_srate) ||
(format.GetBps() != m_bps) ||
(format.GetStereo() != m_stereo)) {
if (!SetupSound(format.GetSampleRate(), format.GetBps(),
format.GetStereo())) {
m_buffers.DeleteObject(&buf);
buf.Clear(wxSND_BUFLOCKED | wxSND_BUFREADY);
buf.SetError(wxSND_CANTSET);
return false;
}
m_mode = wxSND_OTHER_IO;
}
if (buf.GetMode() != m_mode) {
m_mode = buf.GetMode();
return false;
}
return true;
}
wxUint32 wxUssSound::GetNbFragments()
{
struct audio_buf_info frag_info;
ioctl(m_fd, SNDCTL_DSP_GETOSPACE, &frag_info);
return frag_info.fragstotal;
}
wxUint32 wxUssSound::GetFragmentSize()
{
return m_max_bufsize;
}
bool wxUssSound::SetupSound(wxUint16 srate, wxUint8 bps, bool stereo)
{
int tmp;
unsigned long tmp_ul;
if (m_fd != -1) {
delete m_sndbuf;
fsync(m_fd);
close(m_fd);
}
m_fd = open("/dev/dsp", O_RDWR);
tmp = stereo;
if (ioctl(m_fd, SNDCTL_DSP_STEREO, &tmp) < 0)
return FALSE;
m_stereo = tmp;
tmp_ul = srate;
if (ioctl(m_fd, SNDCTL_DSP_SPEED, &tmp_ul) < 0)
return FALSE;
m_srate = tmp_ul;
tmp = bps;
if (ioctl(m_fd, SNDCTL_DSP_SAMPLESIZE, &tmp) < 0)
return FALSE;
m_bps = tmp;
ioctl(m_fd, SNDCTL_DSP_GETBLKSIZE, &tmp);
m_max_bufsize = tmp;
m_sndbuf->SetBufferIO(m_max_bufsize);
m_ussformat.SetBps(m_bps);
m_ussformat.SetChannels((m_stereo) ? 2 : 1);
m_ussformat.SetSampleRate(m_srate);
return TRUE;
}

85
utils/wxMMedia/snduss.h Normal file
View File

@@ -0,0 +1,85 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: snduss.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
/* Real -*- C++ -*- */
#ifndef __SND_ussnd_H__
#define __SND_ussnd_H__
#ifdef __GNUG__
#pragma interface
#endif
#include <wx/thread.h>
#include "sndsnd.h"
#include "sndfrag.h"
#include "sndfrmt.h"
///
class wxUssSound : public wxSound, public wxThread {
///
DECLARE_DYNAMIC_CLASS(wxUssSound)
public:
wxUssSound();
///
virtual ~wxUssSound();
///
void OnNeedBuffer();
protected:
///
virtual bool Wakeup(wxSndBuffer& buf);
///
void USS_Sleep();
///
virtual void StopBuffer(wxSndBuffer& buf);
///
bool OnSetupDriver(wxSndBuffer& buf, wxSndMode mode);
///
bool SetupSound(wxUint16 srate, wxUint8 bps, bool stereo);
///
wxUint32 GetNbFragments();
///
wxUint32 GetFragmentSize();
///
void ThreadEntryPoint();
protected:
///
wxUint16 m_srate;
///
wxUint8 m_bps;
///
wxUint32 m_max_bufsize;
///
bool m_stereo;
///
wxSndMode m_mode;
///
wxSoundDataFormat m_ussformat;
///
wxStreamBuffer *m_sndbuf;
///
bool m_stop_thrd, m_sleeping;
/// Sound file descriptor.
int m_fd;
/// Thread sleep mutexes and conditions.
wxMutex m_sleep_mtx;
wxCondition m_sleep_cond;
///
bool DoInput(wxSndBuffer *buf);
bool DoOutput(wxSndBuffer *buf);
///
virtual void *Entry();
};
#endif

186
utils/wxMMedia/sndwav.cpp Normal file
View File

@@ -0,0 +1,186 @@
////////////////////////////////////////////////////////////////////////////////
// Name: sndwav.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: February 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "sndwav.h"
#endif
#ifdef WX_PRECOMP
#include "wx_prec.h"
#else
#include "wx/wx.h"
#endif
#include "sndwav.h"
#include "sndfrmt.h"
#include "sndpcm.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
wxSndWavCodec::wxSndWavCodec()
: wxSndFileCodec(), riff_codec()
{
m_sndtime.hours = -1;
}
wxSndWavCodec::wxSndWavCodec(wxOutputStream& s, bool seekable)
: wxSndFileCodec(s, seekable)
{
if (!seekable)
CacheIO();
riff_codec = wxRiffCodec(*m_ostream);
m_sndtime.hours = -1;
}
wxSndWavCodec::wxSndWavCodec(wxInputStream& s, bool preload, bool seekable)
: wxSndFileCodec(s, preload, seekable)
{
if (!seekable)
CacheIO();
riff_codec = wxRiffCodec(*m_istream);
m_sndtime.hours = -1;
}
wxSndWavCodec::wxSndWavCodec(const wxString& fname)
: wxSndFileCodec(fname)
{
riff_codec = wxRiffCodec(*m_istream);
m_sndtime.hours = -1;
}
wxUint32 wxSndWavCodec::PrepareToPlay()
{
if (!riff_codec.RiffReset(RIFF_READ))
return 0;
if (!riff_codec.FindChunk("RIFF", TRUE)) {
wxSndFileCodec::m_mmerror = wxMMFILE_INVALID;
return 0;
}
char tmp_buf[5];
riff_codec.ReadData(tmp_buf, 4);
tmp_buf[4] = 0;
if (wxString("WAVE") != tmp_buf) {
wxSndFileCodec::m_mmerror = wxMMFILE_INVALID;
return 0;
}
if (!riff_codec.FindChunk("fmt ", TRUE))
return 0;
riff_codec.Read16(wav_hdr.format);
riff_codec.Read16(wav_hdr.channels);
riff_codec.Read32(wav_hdr.sample_fq);
riff_codec.Read32(wav_hdr.byte_p_sec);
riff_codec.Read16(wav_hdr.byte_p_spl);
riff_codec.Read16(wav_hdr.bits_p_spl);
if (!riff_codec.FindChunk("data"))
return 0;
m_sndformat.SetSampleRate(wav_hdr.sample_fq);
m_sndformat.SetBps(wav_hdr.bits_p_spl);
m_sndformat.SetChannels(wav_hdr.channels);
m_sndmode = wxSND_OUTPUT;
ChangeCodec(wav_hdr.format);
m_sndformat.SetSampleRate(wav_hdr.sample_fq);
m_sndformat.SetBps(wav_hdr.bits_p_spl);
m_sndformat.SetChannels(wav_hdr.channels);
if (wav_hdr.format == WXSOUND_PCM) {
m_sndformat.SetSign(wxSND_SAMPLE_SIGNED);
m_sndformat.SetByteOrder(wxSND_SAMPLE_LE);
}
wxUint32 sec1 = riff_codec.GetChunkLength() / wav_hdr.byte_p_sec,
sec2 = sec1 % 3600;
m_sndtime.hours = sec1 / 3600;
m_sndtime.minutes = sec2 / 60;
m_sndtime.seconds = sec2 % 60;
wxSndFileCodec::m_mmerror = wxMMFILE_NOERROR;
return riff_codec.GetChunkLength();
}
wxSndWavCodec::~wxSndWavCodec()
{
}
bool wxSndWavCodec::OnNeedData(char *buf, wxUint32 size)
{
return riff_codec.ReadData(buf, size);
}
bool wxSndWavCodec::OnWriteData(char *buf, wxUint32 size)
{
return riff_codec.WriteData(buf, size);
}
bool wxSndWavCodec::PrepareToRecord(wxUint32 m_fsize)
{
wxUint32 total_size;
if (!riff_codec.RiffReset(RIFF_WRITE))
return FALSE;
total_size = 16 + sizeof(wav_hdr) + m_fsize;
if (!riff_codec.CreateChunk("RIFF", total_size))
return FALSE;
riff_codec.WriteData("WAVE", 4);
if (!riff_codec.CreateChunk("fmt ", sizeof(wav_hdr)))
return FALSE;
wav_hdr.format = 1; // PCM_WAV_FORMAT
wav_hdr.channels = m_sndformat.GetChannels();
wav_hdr.sample_fq = m_sndformat.GetSampleRate();
wav_hdr.byte_p_spl = (m_sndformat.GetBps() / 8) * wav_hdr.channels;
wav_hdr.byte_p_sec = m_sndformat.GetCodec()->GetByteRate();
wav_hdr.bits_p_spl = m_sndformat.GetBps();
ChangeCodec(WXSOUND_PCM);
if (wav_hdr.format == WXSOUND_PCM) {
m_sndformat.SetSign(wxSND_SAMPLE_SIGNED);
m_sndformat.SetByteOrder(wxSND_SAMPLE_LE);
}
riff_codec.Write16(wav_hdr.format);
riff_codec.Write16(wav_hdr.channels);
riff_codec.Write32(wav_hdr.sample_fq);
riff_codec.Write32(wav_hdr.byte_p_sec);
riff_codec.Write16(wav_hdr.byte_p_spl);
riff_codec.Write16(wav_hdr.bits_p_spl);
if (!riff_codec.CreateChunk("data", m_fsize))
return FALSE;
return TRUE;
}
void wxSndWavCodec::SetFile(wxInputStream& s, bool preload, bool seekable)
{
wxMMediaFile::SetFile(s, preload, seekable);
if (!seekable)
CacheIO();
riff_codec.SetFile((seekable) ? s : *m_istream);
}
void wxSndWavCodec::SetFile(wxOutputStream& s, bool seekable)
{
wxMMediaFile::SetFile(s, seekable);
if (!seekable)
CacheIO();
riff_codec.SetFile((seekable) ? s : *m_ostream);
}

59
utils/wxMMedia/sndwav.h Normal file
View File

@@ -0,0 +1,59 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: sndwav.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: February 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
/* Real -*- C++ -*- */
#ifndef __SND_wav_H__
#define __SND_wav_H__
#ifdef __GNUG__
#pragma interface
#endif
#include "mmriff.h"
#include "sndfile.h"
///
class wxSndWavCodec : public wxSndFileCodec {
///
DECLARE_DYNAMIC_CLASS(wxSndWavCodec)
public:
///
wxSndWavCodec();
///
wxSndWavCodec(wxInputStream& s, bool preload = FALSE, bool seekable = TRUE);
///
wxSndWavCodec(wxOutputStream& s, bool seekable = TRUE);
///
wxSndWavCodec(const wxString& fname);
///
virtual ~wxSndWavCodec();
virtual bool OnNeedData(char *buf, wxUint32 size);
virtual bool OnWriteData(char *buf, wxUint32 size);
virtual wxUint32 PrepareToPlay();
virtual bool PrepareToRecord(wxUint32 file_size);
virtual void SetFile(wxInputStream& s, bool preload = FALSE,
bool seekable = FALSE);
virtual void SetFile(wxOutputStream& s,
bool seekable = FALSE);
protected:
wxRiffCodec riff_codec;
struct {
wxUint16 format;
wxUint16 channels;
wxUint32 sample_fq;
wxUint32 byte_p_sec;
wxUint16 byte_p_spl;
wxUint16 bits_p_spl;
} wav_hdr;
};
#endif

384
utils/wxMMedia/sndwin.cpp Normal file
View File

@@ -0,0 +1,384 @@
////////////////////////////////////////////////////////////////////////////////
// Name: sndwin.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef WX_PRECOMP
#include "wx/wxprec.h"
#else
#include "wx/wx.h"
#endif
#include <wx/msw/private.h>
#define WXMMEDIA_INTERNAL
#include "sndwin.h"
#define MMD_WIN_IO_BSIZE 16384
#include <mmsystem.h>
#ifdef __BORLANDC__
#pragma hdrstop
#endif
wxSndWinFragment::wxSndWinFragment(wxSound& io_drv)
: wxFragmentBuffer(io_drv)
{
}
wxSndWinFragment::~wxSndWinFragment(void)
{
}
void wxSndWinFragment::AllocIOBuffer(void)
{
wxWinSound *w_snd = (wxWinSound *) m_iodrv;
wxUint8 i;
m_maxoq = 5;
m_maxiq = 5;
m_lstoptrs = m_optrs = new wxFragBufPtr[m_maxoq];
m_lstiptrs = m_iptrs = new wxFragBufPtr[m_maxiq];
for (i=0;i<m_maxoq;i++) {
m_lstoptrs[i].size = MMD_WIN_IO_BSIZE;
m_lstoptrs[i].ptr = 0;
m_lstoptrs[i].buffers = new wxList();
m_lstoptrs[i].state = wxBUFFER_FREE;
w_snd->PrepareHeader(m_lstoptrs[i], wxSND_OUTPUT);
}
for (i=0;i<m_maxiq;i++) {
m_lstiptrs[i].size = MMD_WIN_IO_BSIZE;
m_lstiptrs[i].ptr = 0;
m_lstiptrs[i].buffers = new wxList();
m_lstiptrs[i].state = wxBUFFER_FREE;
w_snd->PrepareHeader(m_lstiptrs[i], wxSND_INPUT);
}
}
void wxSndWinFragment::FreeIOBuffer(void)
{
wxWinSound *w_snd = (wxWinSound *)m_iodrv;
wxUint8 i;
if (!m_lstoptrs && !m_lstiptrs)
return;
for (i=0;i<m_maxoq;i++) {
w_snd->UnprepareHeader(m_lstoptrs[i], wxSND_OUTPUT);
delete m_lstoptrs[i].buffers;
}
for (i=0;i<m_maxiq;i++) {
w_snd->UnprepareHeader(m_lstiptrs[i], wxSND_INPUT);
delete m_lstiptrs[i].buffers;
}
delete[] m_lstoptrs;
delete[] m_lstiptrs;
m_lstoptrs = m_lstiptrs = NULL;
m_maxoq = m_maxiq = 0;
}
void wxSndWinFragment::WaitForAll()
{
bool buf_busy = TRUE;
int i;
m_dontq = TRUE;
while (buf_busy) {
buf_busy = FALSE;
for (i=0;i<m_maxoq;i++) {
if (m_lstoptrs[i].state == wxBUFFER_FFILLED) {
buf_busy = TRUE;
break;
}
}
wxYield();
}
m_dontq = FALSE;
FreeBufToFree(TRUE);
}
bool wxSndWinFragment::OnBufferFilled(wxFragBufPtr *ptr, wxSndMode mode)
{
wxSndWinInfo *info = (wxSndWinInfo *)ptr->user_data;
wxWinSound *w_snd = (wxWinSound *)m_iodrv;
MMRESULT result;
switch (mode) {
case wxSND_INPUT:
result = waveInAddBuffer(w_snd->internal->devin_id, info->hdr,
sizeof(WAVEHDR));
break;
case wxSND_OUTPUT:
result = waveOutWrite(w_snd->internal->devout_id, info->hdr,
sizeof(WAVEHDR));
printf("WINOUT: result=%d\n", result);
break;
}
return TRUE;
}
wxWinSound::wxWinSound(void)
: wxSound(),
fragments(*this)
{
internal = new wxWinSoundInternal;
internal->devout_id = 0;
internal->devin_id = 0;
internal->sndWin = 0;
wout_opened = FALSE;
win_opened = FALSE;
curr_o_srate = (wxUint32)-1;
curr_o_bps = (wxUint8)-1;
curr_o_stereo = (bool)-1;
curr_i_srate = (wxUint32)-1;
curr_i_bps = (wxUint8)-1;
curr_i_stereo = (bool)-1;
}
wxWinSound::~wxWinSound(void)
{
int i;
fragments.WaitForAll();
if (wout_opened)
waveOutReset(internal->devout_id);
if (win_opened)
waveInReset(internal->devout_id);
fragments.FreeIOBuffer();
if (wout_opened)
waveOutClose(internal->devout_id);
if (win_opened)
waveInClose(internal->devin_id);
if (internal->sndWin)
::DestroyWindow(internal->sndWin);
delete internal;
}
bool wxWinSound::Wakeup(wxSndBuffer& buf)
{
if (!Reopen(buf, FALSE)) {
buf.Clear(wxSND_BUFLOCKED);
return FALSE;
}
fragments.OnBufferFinished(NULL);
return TRUE;
}
void wxWinSound::PrepareHeader(wxFragmentBuffer::wxFragBufPtr& frag,
wxSndMode mode)
{
wxSndWinInfo *info;
WAVEHDR *hdr;
if ((mode == wxSND_INPUT && !win_opened) ||
(mode == wxSND_OUTPUT && !wout_opened))
return;
info = new wxSndWinInfo;
info->h_data = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, frag.size);
info->h_hdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, sizeof(WAVEHDR));
info->data = (char *)GlobalLock(info->h_data);
hdr = info->hdr = (WAVEHDR *)GlobalLock(info->h_hdr);
memset(hdr, 0, sizeof(*hdr));
hdr->lpData = info->data;
hdr->dwBufferLength = frag.size;
hdr->dwUser = (DWORD)&frag;
hdr->dwFlags = WHDR_DONE;
if (mode == wxSND_INPUT) {
MMRESULT result = waveInPrepareHeader(internal->devin_id, hdr,
sizeof(WAVEHDR));
printf("prepareIn = %d\n", result);
if (result != MMSYSERR_NOERROR)
wxExit();
} else {
MMRESULT result = waveOutPrepareHeader(internal->devout_id, hdr,
sizeof(WAVEHDR));
printf("prepareOut = %d\n", result);
if (result != MMSYSERR_NOERROR)
wxExit();
}
frag.user_data = (char *)info;
frag.data = info->data;
}
void wxWinSound::UnprepareHeader(wxFragmentBuffer::wxFragBufPtr& frag,
wxSndMode mode)
{
wxSndWinInfo *info = (wxSndWinInfo *)frag.user_data;
if ((mode == wxSND_INPUT && !win_opened) ||
(mode == wxSND_OUTPUT && !wout_opened))
return;
MMRESULT result;
if (mode == wxSND_INPUT) {
result = waveInUnprepareHeader(internal->devin_id, info->hdr, sizeof(*info->hdr));
} else {
result = waveOutUnprepareHeader(internal->devout_id, info->hdr, sizeof(*info->hdr));
}
printf("unprepare = %d\n", result);
GlobalUnlock(info->h_hdr);
GlobalUnlock(info->h_data);
GlobalFree(info->h_hdr);
GlobalFree(info->h_data);
delete info;
}
extern char wxCanvasClassName[];
LRESULT APIENTRY _EXPORT wxSoundHandlerWndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch (message) {
case MM_WOM_DONE: {
wxWinSound *snd_drv = (wxWinSound *)GetWindowLong(hWnd, GWL_USERDATA);
WAVEHDR *hdr = (WAVEHDR *)lParam;
wxFragmentBuffer::wxFragBufPtr *buf =
(wxFragmentBuffer::wxFragBufPtr *)hdr->dwUser;
// To be sure ...
hdr->dwFlags |= WHDR_DONE;
snd_drv->fragments.OnBufferFinished(buf);
break;
}
case MM_WOM_OPEN:
printf("wave Open ack\n");
break;
case MM_WOM_CLOSE:
printf("wave Close ack\n");
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return (LRESULT)0;
}
void wxWinSound::StopBuffer(wxSndBuffer& buf)
{
buf.HardLock();
buf.Set(wxSND_BUFSTOP);
fragments.AbortBuffer(buf);
buf.HardUnlock();
while (buf.IsSet(wxSND_BUFSTOP))
wxYield();
}
bool wxWinSound::Reopen(wxSndBuffer& buf, bool force)
{
WAVEFORMATEX wformat;
if ((buf.GetSampleRate() != curr_o_srate) ||
(buf.GetBps() != curr_o_bps) ||
(buf.GetStereo() != curr_o_stereo) ||
(buf.GetMode() != curr_mode))
force = TRUE;
if (force) {
wxUint32 *curr_srate =
(buf.GetMode() == wxSND_OUTPUT) ? &curr_o_srate : &curr_i_srate;
wxUint8 *curr_bps =
(buf.GetMode() == wxSND_OUTPUT) ? &curr_o_bps : &curr_i_bps;
bool *curr_stereo =
(buf.GetMode() == wxSND_OUTPUT) ? &curr_o_stereo : &curr_i_stereo;
fragments.WaitForAll();
fragments.FreeIOBuffer();
if (!internal->sndWin) {
FARPROC proc = MakeProcInstance((FARPROC)wxSoundHandlerWndProc, wxGetInstance());
internal->sndWin = ::CreateWindow(wxCanvasClassName, NULL, 0,
0, 0, 0, 0, NULL, (HMENU) NULL,
wxGetInstance(), 0);
::SetWindowLong(internal->sndWin, GWL_WNDPROC,
(LONG)proc);
::SetWindowLong(internal->sndWin, GWL_USERDATA, (LONG) this);
}
if (wout_opened) {
waveOutClose(internal->devout_id);
wout_opened = FALSE;
}
if (win_opened) {
waveInClose(internal->devin_id);
win_opened = FALSE;
}
*curr_srate = buf.GetSampleRate();
*curr_bps = buf.GetBps();
*curr_stereo = buf.GetStereo();
wformat.wFormatTag = WAVE_FORMAT_PCM;
wformat.nChannels = curr_o_stereo+1;
wformat.nSamplesPerSec = curr_o_srate;
wformat.nBlockAlign = curr_o_bps / 8 * wformat.nChannels;
wformat.nAvgBytesPerSec =
wformat.nSamplesPerSec * wformat.nBlockAlign;
wformat.wBitsPerSample = curr_o_bps;
wformat.cbSize = 0;
if (buf.GetMode() == wxSND_OUTPUT) {
MMRESULT result = waveOutOpen(&internal->devout_id,
WAVE_MAPPER, &wformat,
(DWORD)internal->sndWin, (DWORD)this,
CALLBACK_WINDOW);
if (result != MMSYSERR_NOERROR)
return FALSE;
internal->devin_id = 0;
wout_opened = TRUE;
curr_mode = wxSND_OUTPUT;
fragments.AllocIOBuffer();
}
else {
MMRESULT result = waveInOpen(&internal->devin_id,
WAVE_MAPPER, &wformat,
(DWORD)internal->sndWin, (DWORD)this,
CALLBACK_FUNCTION);
if (result != MMSYSERR_NOERROR)
return FALSE;
internal->devout_id = 0;
win_opened = TRUE;
curr_mode = wxSND_INPUT;
fragments.AllocIOBuffer();
}
}
return TRUE;
}

108
utils/wxMMedia/sndwin.h Normal file
View File

@@ -0,0 +1,108 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: sndwin.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
/* Real -*- C++ -*- */
#ifndef __SND_win_H__
#define __SND_win_H__
#include "sndsnd.h"
#include "sndfrag.h"
#ifdef WXMMEDIA_INTERNAL
#include <wx/msw/private.h>
#include <windows.h>
#include <mmsystem.h>
typedef struct wxWinSoundInternal {
HWAVEOUT devout_id;
HWAVEIN devin_id;
HWND sndWin;
} wxWinSoundInternal;
typedef struct wxSndWinInfo {
HGLOBAL h_data, h_hdr;
char *data;
WAVEHDR *hdr;
} wxSndWinInfo;
#endif
/** Sound buffer fragmenter: windows specific implementation
* @author Guilhem Lavaux
*/
class wxSndWinFragment : public wxFragmentBuffer {
public:
wxSndWinFragment(wxSound& io_drv);
virtual ~wxSndWinFragment(void);
virtual void AllocIOBuffer(void);
virtual void FreeIOBuffer(void);
virtual bool OnBufferFilled(wxFragBufPtr *ptr, wxSndMode mode);
void WaitForAll();
};
///
class wxWinSound : public wxSound {
///
DECLARE_DYNAMIC_CLASS(wxWinSound)
protected:
struct wxWinSoundInternal *internal;
///
bool wout_opened, win_opened;
///
wxUint32 curr_o_srate, curr_i_srate;
///
wxUint8 curr_o_bps, curr_i_bps;
///
bool curr_o_stereo, curr_i_stereo;
///
wxSndMode curr_mode;
///
wxSndWinFragment fragments;
#ifdef WXMMEDIA_INTERNAL
///
friend LRESULT APIENTRY _EXPORT wxSoundHandlerWndProc(HWND win,
UINT message,
WPARAM wParam, LPARAM lParam);
#endif
public:
///
wxWinSound(void);
///
virtual ~wxWinSound(void);
///
void OnNeedBuffer(wxSndMode mode);
///
void StopBuffer(wxSndBuffer& buf);
protected:
///
virtual bool Wakeup(wxSndBuffer& buf);
///
bool Reopen(wxSndBuffer& buf, bool force);
///
friend class wxSndWinFragment;
///
void PrepareHeader(wxFragmentBuffer::wxFragBufPtr& frag, wxSndMode mode);
///
void UnprepareHeader(wxFragmentBuffer::wxFragBufPtr& frag, wxSndMode mode);
};
#endif

69
utils/wxMMedia/ulaw.h Normal file
View File

@@ -0,0 +1,69 @@
static unsigned char ulaw_dsp[] = {
3, 7, 11, 15, 19, 23, 27, 31,
35, 39, 43, 47, 51, 55, 59, 63,
66, 68, 70, 72, 74, 76, 78, 80,
82, 84, 86, 88, 90, 92, 94, 96,
98, 99, 100, 101, 102, 103, 104, 105,
106, 107, 108, 109, 110, 111, 112, 113,
113, 114, 114, 115, 115, 116, 116, 117,
117, 118, 118, 119, 119, 120, 120, 121,
121, 121, 122, 122, 122, 122, 123, 123,
123, 123, 124, 124, 124, 124, 125, 125,
125, 125, 125, 125, 126, 126, 126, 126,
126, 126, 126, 126, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127,
128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128,
253, 249, 245, 241, 237, 233, 229, 225,
221, 217, 213, 209, 205, 201, 197, 193,
190, 188, 186, 184, 182, 180, 178, 176,
174, 172, 170, 168, 166, 164, 162, 160,
158, 157, 156, 155, 154, 153, 152, 151,
150, 149, 148, 147, 146, 145, 144, 143,
143, 142, 142, 141, 141, 140, 140, 139,
139, 138, 138, 137, 137, 136, 136, 135,
135, 135, 134, 134, 134, 134, 133, 133,
133, 133, 132, 132, 132, 132, 131, 131,
131, 131, 131, 131, 130, 130, 130, 130,
130, 130, 130, 130, 129, 129, 129, 129,
129, 129, 129, 129, 129, 129, 129, 129,
128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128,
};
static unsigned char dsp_ulaw[] = {
0, 0, 0, 0, 0, 1, 1, 1,
1, 2, 2, 2, 2, 3, 3, 3,
3, 4, 4, 4, 4, 5, 5, 5,
5, 6, 6, 6, 6, 7, 7, 7,
7, 8, 8, 8, 8, 9, 9, 9,
9, 10, 10, 10, 10, 11, 11, 11,
11, 12, 12, 12, 12, 13, 13, 13,
13, 14, 14, 14, 14, 15, 15, 15,
15, 16, 16, 17, 17, 18, 18, 19,
19, 20, 20, 21, 21, 22, 22, 23,
23, 24, 24, 25, 25, 26, 26, 27,
27, 28, 28, 29, 29, 30, 30, 31,
31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46,
47, 49, 51, 53, 55, 57, 59, 61,
63, 66, 70, 74, 78, 84, 92, 104,
254, 231, 219, 211, 205, 201, 197, 193,
190, 188, 186, 184, 182, 180, 178, 176,
175, 174, 173, 172, 171, 170, 169, 168,
167, 166, 165, 164, 163, 162, 161, 160,
159, 159, 158, 158, 157, 157, 156, 156,
155, 155, 154, 154, 153, 153, 152, 152,
151, 151, 150, 150, 149, 149, 148, 148,
147, 147, 146, 146, 145, 145, 144, 144,
143, 143, 143, 143, 142, 142, 142, 142,
141, 141, 141, 141, 140, 140, 140, 140,
139, 139, 139, 139, 138, 138, 138, 138,
137, 137, 137, 137, 136, 136, 136, 136,
135, 135, 135, 135, 134, 134, 134, 134,
133, 133, 133, 133, 132, 132, 132, 132,
131, 131, 131, 131, 130, 130, 130, 130,
129, 129, 129, 129, 128, 128, 128, 128,
};

View File

@@ -0,0 +1,87 @@
////////////////////////////////////////////////////////////////////////////////
// Name: vidbdrv.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "vidbase.h"
#endif
#include <wx/fstream.h>
#include "vidbase.h"
#ifdef WX_PRECOMP
#include "wx_prec.h"
#else
#include "wx/wx.h"
#endif
#ifdef __BORLANDC__
#pragma hdrstop
#endif
wxVideoOutput::wxVideoOutput()
: wxWindow()
{
dyn_size = TRUE;
}
wxVideoOutput::wxVideoOutput(wxWindow *parent, const wxWindowID id, const wxPoint& position,
const wxSize& size, const long style,
const wxString& name)
: wxWindow(parent, id, position, size, style, name)
{
dyn_size = TRUE;
}
///
wxVideoOutput::~wxVideoOutput()
{
}
wxVideoBaseDriver::wxVideoBaseDriver()
: wxMMediaFile()
{
}
wxVideoBaseDriver::wxVideoBaseDriver(wxInputStream& str, bool seekable)
: wxMMediaFile(str, FALSE, seekable)
{
}
wxVideoBaseDriver::wxVideoBaseDriver(const wxString& fname)
: wxMMediaFile(fname)
{
}
wxVideoBaseDriver::~wxVideoBaseDriver()
{
}
bool wxVideoBaseDriver::AttachOutput(wxVideoOutput& output)
{
video_output = &output;
return TRUE;
}
void wxVideoBaseDriver::DetachOutput()
{
video_output = NULL;
}
// Use an external frame for video output
wxFrame *wxVideoCreateFrame(wxVideoBaseDriver *vid_drv)
{
wxFrame *frame = new wxFrame(NULL, -1, "Video Output", wxDefaultPosition, wxSize(100, 100));
wxVideoOutput *vid_out = new wxVideoOutput(frame, -1);
vid_out->DynamicSize(TRUE);
vid_drv->AttachOutput(*vid_out);
frame->Layout();
frame->Show(TRUE);
return frame;
}

105
utils/wxMMedia/vidbase.h Normal file
View File

@@ -0,0 +1,105 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: vidbase.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// CVS: $Id$
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
/* Real -*- C++ -*- */
#ifndef __VID_bdrv_H__
#define __VID_bdrv_H__
#ifdef __GNUG__
#pragma interface
#endif
#include "mmtype.h"
#include "mmfile.h"
#include "wx/string.h"
#include "wx/window.h"
///
typedef enum {
wxVIDEO_MSAVI,
wxVIDEO_MPEG,
wxVIDEO_QT,
wxVIDEO_GIF,
wxVIDEO_JMOV,
wxVIDEO_FLI,
wxVIDEO_IFF,
wxVIDEO_SGI,
wxVIDEO_MPEG2
} ///
wxVideoType;
///
class wxVideoBaseDriver;
class wxVideoOutput : public wxWindow {
///
DECLARE_DYNAMIC_CLASS(wxVideoOutput)
protected:
bool dyn_size;
public:
///
wxVideoOutput();
///
wxVideoOutput(wxWindow *parent, const wxWindowID id,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, const long style = 0,
const wxString& name = "video_output");
///
virtual ~wxVideoOutput();
///
bool DynamicSize() { return dyn_size; }
///
void DynamicSize(bool dyn) { dyn_size = dyn; }
};
///
class wxVideoBaseDriver : public wxObject, public wxMMediaFile {
///
DECLARE_ABSTRACT_CLASS(wxVideoBaseDriver)
protected:
wxVideoOutput *video_output;
public:
friend class wxVideoOutput;
///
wxVideoBaseDriver();
///
wxVideoBaseDriver(wxInputStream& str, bool seekable = FALSE);
///
wxVideoBaseDriver(const wxString& fname);
///
virtual ~wxVideoBaseDriver();
///
virtual bool Pause() = 0;
///
virtual bool Resume() = 0;
///
virtual bool SetVolume(wxUint8 vol) = 0;
///
virtual bool Resize(wxUint16 w, wxUint16 h) = 0;
///
virtual bool IsCapable(wxVideoType WXUNUSED(v_type)) { return FALSE; }
///
virtual void OnFinished() {}
///
virtual bool AttachOutput(wxVideoOutput& output);
///
virtual void DetachOutput();
};
extern wxFrame *wxVideoCreateFrame(wxVideoBaseDriver *vid_drv);
#endif

131
utils/wxMMedia/vidwin.cpp Normal file
View File

@@ -0,0 +1,131 @@
////////////////////////////////////////////////////////////////////////////////
// Name: vidwin.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: February 1998
// Updated:
// Copyright: (C) 1998, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "vidwin.h"
#endif
#if 0
#include "wx/wxprec.h"
#else
#include "wx/wx.h"
#endif
#define WXMMEDIA_INTERNAL
#include <windows.h>
#include <mmsystem.h>
#include <digitalv.h>
#include "mmtype.h"
#include "mmfile.h"
#include "vidwin.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
wxVideoWindows::wxVideoWindows(void)
{
}
wxVideoWindows::wxVideoWindows(wxInputStream& str, bool seekable)
: wxVideoBaseDriver(str, seekable)
{
OpenFile(GetCurrentFile());
}
wxVideoWindows::wxVideoWindows(const char *fname)
: wxVideoBaseDriver(fname)
{
OpenFile(fname);
}
wxVideoWindows::~wxVideoWindows(void)
{
mciSendCommand(internal->dev_id, MCI_CLOSE, 0, 0);
if (internal)
delete internal;
}
void wxVideoWindows::OpenFile(const char *fname)
{
MCI_DGV_OPEN_PARMS open_struct;
DWORD ret;
internal = new VIDW_Internal;
open_struct.lpstrDeviceType = "avivideo";
open_struct.lpstrElementName = (LPSTR)fname;
open_struct.hWndParent = 0;
ret = mciSendCommand(0, MCI_OPEN,
MCI_OPEN_ELEMENT|MCI_DGV_OPEN_PARENT|MCI_OPEN_TYPE|MCI_DGV_OPEN_32BIT,
(DWORD)(LPVOID)&open_struct);
internal->dev_id = open_struct.wDeviceID;
}
bool wxVideoWindows::Pause(void)
{
return (mciSendCommand(internal->dev_id, MCI_PAUSE, 0, 0) == 0);
}
bool wxVideoWindows::Resume(void)
{
return (mciSendCommand(internal->dev_id, MCI_PAUSE, 0, 0) == 0);
}
bool wxVideoWindows::SetVolume(wxUint8 vol)
{
return TRUE;
}
bool wxVideoWindows::Resize(wxUint16 w, wxUint16 h)
{
return TRUE;
}
bool wxVideoWindows::IsCapable(wxVideoType v_type)
{
return (v_type == wxVIDEO_MSAVI);
}
bool wxVideoWindows::AttachOutput(wxVideoOutput& output)
{
MCI_DGV_WINDOW_PARMS win_struct;
if (!wxVideoBaseDriver::AttachOutput(output))
return FALSE;
win_struct.hWnd = (HWND)output.GetHWND();
mciSendCommand(internal->dev_id, MCI_WINDOW,
MCI_DGV_WINDOW_HWND, (DWORD)(LPVOID)&win_struct);
return TRUE;
}
void wxVideoWindows::DetachOutput(void)
{
MCI_DGV_WINDOW_PARMS win_struct;
wxVideoBaseDriver::DetachOutput();
win_struct.hWnd = 0;
mciSendCommand(internal->dev_id, MCI_WINDOW,
MCI_DGV_WINDOW_HWND, (DWORD)(LPVOID)&win_struct);
}
bool wxVideoWindows::StartPlay(void)
{
return (mciSendCommand(internal->dev_id, MCI_PLAY, 0, NULL) == 0);
}
void wxVideoWindows::StopPlay(void)
{
mciSendCommand(internal->dev_id, MCI_STOP, 0, NULL);
}

62
utils/wxMMedia/vidwin.h Normal file
View File

@@ -0,0 +1,62 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: vidwin.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: February 1998
// Updated:
// Copyright: (C) 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
/* Real -*- C++ -*- */
#ifndef __VID_windows_H__
#define __VID_windows_H__
#ifdef __GNUG__
#pragma interface
#endif
#include "mmtype.h"
#include "mmfile.h"
#ifdef WX_PRECOMP
#include "wx/wxprec.h"
#else
#include "wx/wx.h"
#endif
#include "vidbase.h"
#ifdef WXMMEDIA_INTERNAL
#include <windows.h>
#include <mmsystem.h>
typedef struct VIDW_Internal {
MCIDEVICEID dev_id;
} VIDW_Internal;
#endif
class wxVideoWindows : public wxVideoBaseDriver {
DECLARE_DYNAMIC_CLASS(wxVideoWindows)
protected:
struct VIDW_Internal *internal;
void OpenFile(const char *fname);
public:
wxVideoWindows(void);
wxVideoWindows(wxInputStream& str, bool seekable = FALSE);
wxVideoWindows(const char *fname);
virtual ~wxVideoWindows(void);
virtual bool StartPlay(void);
virtual void StopPlay(void);
virtual bool Pause(void);
virtual bool Resume(void);
virtual bool SetVolume(wxUint8 vol);
virtual bool Resize(wxUint16 w, wxUint16 h);
virtual bool IsCapable(wxVideoType v_type);
virtual bool AttachOutput(wxVideoOutput& output);
virtual void DetachOutput(void);
};
#endif

231
utils/wxMMedia/vidxanm.cpp Normal file
View File

@@ -0,0 +1,231 @@
////////////////////////////////////////////////////////////////////////////////
// Name: vidxanm.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "vidxanm.h"
#endif
#define WXMMEDIA_INTERNAL
#ifdef __XT__
#define Uses_XLib
#define Uses_XtIntrinsic
#endif
#include "vidbase.h"
#include "vidxanm.h"
#ifdef WX_PRECOMP
#include "wx_prec.h"
#else
#include "wx/wx.h"
#endif
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#ifdef __WXGTK__
#include <gdk/gdk.h>
#include <gdk/gdkprivate.h>
#endif
wxVideoXANIM::wxVideoXANIM()
: wxVideoBaseDriver()
{
internal = new wxXANIMinternal;
xanim_started = false;
paused = false;
}
wxVideoXANIM::wxVideoXANIM(wxInputStream& str)
: wxVideoBaseDriver(str, false)
{
internal = new wxXANIMinternal;
xanim_started = false;
paused = false;
}
wxVideoXANIM::wxVideoXANIM(const wxString& fname)
: wxVideoBaseDriver(fname)
{
internal = new wxXANIMinternal;
xanim_started = false;
}
wxVideoXANIM::~wxVideoXANIM()
{
if (xanim_started)
StopPlay();
delete internal;
}
bool wxVideoXANIM::StartPlay()
{
if (!paused && xanim_started)
return true;
if (!video_output)
wxVideoCreateFrame(this);
if (SendCommand(" ")) {
paused = false;
return true;
}
return false;
}
bool wxVideoXANIM::Pause()
{
if (!paused && SendCommand(" ")) {
paused = TRUE;
return TRUE;
}
return FALSE;
}
bool wxVideoXANIM::Resume()
{
if (paused && SendCommand(" ")) {
paused = FALSE;
return TRUE;
}
return FALSE;
}
void wxVideoXANIM::StopPlay()
{
if (!xanim_started)
return;
SendCommand("q");
xanim_started = FALSE;
paused = FALSE;
}
bool wxVideoXANIM::SetVolume(wxUint8 vol)
{
if (vol > 100)
vol = 100;
wxString str_vol("v%d", vol);
return SendCommand(str_vol.GetData());
}
bool wxVideoXANIM::Resize(wxUint16 WXUNUSED(w), wxUint16 WXUNUSED(h))
{
// Not implemented
// Actually, I think that we just need to resize the output window ...
return FALSE;
}
bool wxVideoXANIM::IsCapable(wxVideoType v_type)
{
if (v_type == wxVIDEO_MSAVI || v_type == wxVIDEO_MPEG ||
v_type == wxVIDEO_QT || v_type == wxVIDEO_GIF || v_type == wxVIDEO_JMOV ||
v_type == wxVIDEO_FLI || v_type == wxVIDEO_IFF || v_type == wxVIDEO_SGI)
return true;
else
return false;
}
bool wxVideoXANIM::AttachOutput(wxVideoOutput& out)
{
if (!wxVideoBaseDriver::AttachOutput(out))
return false;
return RestartXANIM();
}
void wxVideoXANIM::DetachOutput()
{
SendCommand("q");
xanim_started = false;
paused = false;
wxVideoBaseDriver::DetachOutput();
}
bool wxVideoXANIM::SendCommand(const char *command, char **ret,
wxUint32 *size)
{
if (!xanim_started)
if (!RestartXANIM())
return false;
// Send a command to XAnim through X11 Property
XChangeProperty(internal->xanim_dpy, internal->xanim_window,
internal->xanim_atom,
XA_STRING, 8, PropModeReplace, (unsigned char *)command,
strlen(command));
XFlush(internal->xanim_dpy);
if (ret) {
int prop_format;
Atom prop_type;
unsigned long extra;
XGetWindowProperty(internal->xanim_dpy, internal->xanim_window,
internal->xanim_ret, 0, 16, True, AnyPropertyType,
&prop_type, &prop_format, (unsigned long *)size,
&extra, (unsigned char **)ret);
}
return true;
}
bool wxVideoXANIM::RestartXANIM()
{
wxString xanim_command;
int ret;
Atom prop_type;
int prop_format;
unsigned long nitems;
unsigned long extra;
char prop[4];
bool xanim_chg_size;
if (!video_output || xanim_started || !GetCurrentFile())
return false;
// Check if we can change the size of the window dynamicly
xanim_chg_size = video_output->DynamicSize();
// Get current display
#ifdef __XT__
internal->xanim_dpy = wxAPP_DISPLAY;
#endif
#ifdef __WXGTK__
internal->xanim_dpy = gdk_display;
#endif
// Get the window id
#ifdef __XT__
internal->xanim_window = XtWindow(video_output->FWidget());
#else
internal->xanim_window =
((GdkWindowPrivate *)video_output->m_widget->window)->xwindow;
#endif
// Get the XANIM atom
internal->xanim_atom = XInternAtom(internal->xanim_dpy,
"XANIM_PROPERTY", False);
// Build the command
xanim_command.sprintf(__XANIM_COMMAND__ " +W%d +Wp +f +B -Zr +q +Zpe +Ae "
"+Av70 %s %s", internal->xanim_window,
(xanim_chg_size == true) ? "+Sr" : "",
(const char *)GetCurrentFile());
// Execute it
if (!wxExecute(xanim_command, false))
return false;
// Wait for XAnim to be ready
nitems = 0;
while (nitems == 0) {
ret = XGetWindowProperty(internal->xanim_dpy, internal->xanim_window,
internal->xanim_atom,
0, 4, False, AnyPropertyType, &prop_type,
&prop_format, &nitems, &extra,
(unsigned char **)&prop);
// wxYield();
}
xanim_started = true;
return true;
}

69
utils/wxMMedia/vidxanm.h Normal file
View File

@@ -0,0 +1,69 @@
// /////////////////////////////////////////////////////////////////////////////
// Name: vidxanm.h
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1997
// Updated: 1998
// Copyright: (C) 1997, 1998, Guilhem Lavaux
// License: wxWindows license
// /////////////////////////////////////////////////////////////////////////////
/* Real -*- C++ -*- */
#ifndef __VID_xanim_H__
#define __VID_xanim_H__
#ifdef __GNUG__
#pragma interface
#endif
#if defined(WXMMEDIA_INTERNAL) && (defined(__X__) || defined(__WXGTK__))
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#endif
#include "vidbase.h"
#ifdef WXMMEDIA_INTERNAL
typedef struct wxXANIMinternal {
Display *xanim_dpy;
Window xanim_window;
Atom xanim_atom, xanim_ret;
} wxXANIMinternal;
#ifndef __XANIM_COMMAND__
#define __XANIM_COMMAND__ "/usr/X11R6/bin/xanim"
#endif
#endif
class wxVideoXANIM : public wxVideoBaseDriver {
DECLARE_DYNAMIC_CLASS(wxVideoXANIM)
protected:
bool xanim_started, paused;
struct wxXANIMinternal *internal;
public:
wxVideoXANIM();
wxVideoXANIM(wxInputStream& str);
wxVideoXANIM(const wxString& fname);
virtual ~wxVideoXANIM();
virtual bool StartPlay();
virtual bool Pause();
virtual bool Resume();
virtual void StopPlay();
virtual bool SetVolume(wxUint8 vol);
virtual bool Resize(wxUint16 w, wxUint16 h);
virtual bool IsCapable(wxVideoType v_type);
virtual bool AttachOutput(wxVideoOutput& output);
virtual void DetachOutput();
protected:
///
bool RestartXANIM();
///
bool SendCommand(const char *command, char **ret = NULL,
wxUint32 *size = NULL);
};
#endif

65
utils/wxMMedia/wave.cpp Normal file
View File

@@ -0,0 +1,65 @@
/////////////////////////////////////////////////////////////////////////////
// Name: wave.cpp
// Purpose: wxWave class
// Author: Guilhem Lavaux / API by Julian Smart
// Modified by:
// Created: 04/23/98
// RCS-ID: $Id$
// Copyright: (c) Guilhem Lavaux
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "wave.h"
#endif
#include <wx/fstream.h>
#include "wave.h"
wxWave::wxWave()
{
m_wave = NULL;
m_iowave = NULL;
}
wxWave::wxWave(const wxString& fileName, bool isResource = FALSE)
{
Create(fileName, isResource);
}
wxWave::~wxWave()
{
Free();
}
bool wxWave::Create(const wxString& sFileName, bool isResource = FALSE)
{
m_iowave = new wxFileInputStream(sFileName);
m_wave = new wxSndWavCodec(*m_iowave);
return TRUE;
}
bool wxWave::Play(bool async, bool looped) const
{
if (!m_wave)
return FALSE;
if (looped)
m_wave->Set(wxSND_LOOP);
if (!m_wave->StartPlay());
return FALSE;
if (!async)
m_wave->Wait();
m_wave->Clear(wxSND_LOOP);
return TRUE;
}
bool wxWave::Free()
{
if (m_wave) {
delete m_wave;
delete m_iowave;
}
return TRUE;
}

43
utils/wxMMedia/wave.h Normal file
View File

@@ -0,0 +1,43 @@
/////////////////////////////////////////////////////////////////////////////
// Name: wave.h
// Purpose: wxWave class
// Author: Julian Smart
// Modified by: Guilhem Lavaux for wxMMedia (02/05/1998)
// Created: 01/02/97
// RCS-ID: $Id$
// Copyright: (c) Julian Smart and Markus Holzem
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef __WAVEH__
#define __WAVEH__
#ifdef __GNUG__
#pragma interface
#endif
#include <wx/object.h>
#include <wx/string.h>
#include "sndwav.h"
class wxWave : public wxObject
{
public:
wxWave();
wxWave(const wxString& fileName, bool isResource = FALSE);
~wxWave();
public:
bool Create(const wxString& sFileName, bool isResource = FALSE);
bool IsOk() const { return (m_wave ? TRUE : FALSE); };
bool Play(bool async = TRUE, bool looped = FALSE) const;
protected:
bool Free();
protected:
wxInputStream *m_iowave;
wxSndWavCodec *m_wave;
};
#endif