--- a/SoundStr.st Thu Dec 17 14:24:26 1998 +0100
+++ b/SoundStr.st Mon Dec 21 12:43:58 1998 +0100
@@ -11,7 +11,9 @@
"
FileStream subclass:#SoundStream
- instanceVariableNames:'sampleRate numberOfChannels bitsPerSample audioFormat'
+ instanceVariableNames:'sampleRate numberOfChannels bitsPerSample audioFormat
+ alPort
+ pDirectSound pDSBuffer cbBufOffset cbBufSize'
classVariableNames:'UnsupportedOperationSignal'
poolDictionaries:''
category:'Streams-External'
@@ -27,7 +29,7 @@
#ifdef IRIS_AUDIO
# include <audio.h>
-# define _ALportVal(o) (ALport)(__externalAddressVal(o))
+# define __ALportVal(o) (ALport)(__externalAddressVal(o))
#endif
#ifdef LINUX
@@ -42,6 +44,67 @@
#ifdef DEV_AUDIO
# include <stdio.h>
#endif
+
+#ifdef WIN32
+
+# define _WIN32
+
+# undef INT
+# undef Array
+# undef Number
+# undef Method
+# undef Point
+# undef Rectangle
+# undef Block
+# undef String
+# undef Message
+# undef Object
+# undef Context
+
+/* # include <stdarg.h> /* */
+# include <stdio.h> /* */
+# include <windows.h>
+# define CINTERFACE
+# include "dsound.h"
+
+# ifdef __DEF_Array
+# define Array __DEF_Array
+# endif
+# ifdef __DEF_Number
+# define Number __DEF_Number
+# endif
+# ifdef __DEF_Method
+# define Method __DEF_Method
+# endif
+# ifdef __DEF_Point
+# define Point __DEF_Point
+# endif
+# ifdef __DEF_Block
+# define Block __DEF_Block
+# endif
+# ifdef __DEF_String
+# define String __DEF_String
+# endif
+# ifdef __DEF_Message
+# define Message __DEF_Message
+# endif
+# ifdef __DEF_Object
+# define Object __DEF_Object
+# endif
+# ifdef __DEF_Context
+# define Context __DEF_Context
+# endif
+
+# define INT int
+
+# define __DirectSoundVal(o) (LPDIRECTSOUND)(__externalAddressVal(o))
+# define __DSBufferVal(o) (LPDIRECTSOUNDBUFFER)(__externalAddressVal(o))
+
+# define RT_BUFFER_SIZE 4096
+# define NBUFS 4
+
+#endif
+
%}
! !
@@ -82,9 +145,9 @@
initialize
UnsupportedOperationSignal isNil ifTrue:[
- UnsupportedOperationSignal := StreamErrorSignal newSignalMayProceed:false.
- UnsupportedOperationSignal nameClass:self message:#unsupportedOperationSignal.
- UnsupportedOperationSignal notifierString:'unsupported operation'.
+ UnsupportedOperationSignal := StreamErrorSignal newSignalMayProceed:false.
+ UnsupportedOperationSignal nameClass:self message:#unsupportedOperationSignal.
+ UnsupportedOperationSignal notifierString:'unsupported operation'.
]
! !
@@ -124,7 +187,7 @@
"Modified: / 12.12.1997 / 16:51:38 / cg"
!
-writing16BitStero
+writing16BitStereo
"just an example, has never been tried (I also
have no samples for this ... leave it as an exercise)"
@@ -202,32 +265,10 @@
"/
"/ fallback for non-integral argument
"/
- sign := 0.
- (absVal := a16bitSignedValue asInteger) < 0 ifTrue:[
- (absVal <= -32256) ifTrue:[
- ^ 0
- ].
- absVal := absVal negated.
- sign := 16r80
- ] ifFalse:[
- absVal >= 32256 ifTrue:[
- ^ 128
- ]
+ a16bitSignedValue isInteger ifFalse:[
+ ^ self uLawToLinear16:a16bitSignedValue asInteger
].
-
- exp := #[
- 0 1 2 2 3 3 3 3 4 4 4 4 4 4 4 4
- 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
- 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
- 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
- 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
- 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
- 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
- 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
- ] at:(absVal bitShift:-1)+1.
- mantissa := (absVal bitShift:(exp+3) negated) bitAnd:16r0F.
- byte := ((sign bitOr:(exp bitShift:4)) bitOr:mantissa) bitInvert bitAnd:16rFF.
- ^ byte
+ ^ 0
"
SoundStream uLawToLinear16:(SoundStream linear16ToUlaw:0)
@@ -513,12 +554,18 @@
!SoundStream class methodsFor:'default values'!
defaultAudioFormat
+ OperatingSystem getOSType = 'win32' ifTrue:[
+ ^ #S16
+ ].
^ #U8
!
defaultBitsPerSample
"minimum, supported by all audio systems"
+ OperatingSystem getOSType = 'win32' ifTrue:[
+ ^ 16
+ ].
^ 8
!
@@ -642,8 +689,8 @@
fd := self fileDescriptor.
fd isNil ifTrue:[
- self error.
- ^ nil
+ self error.
+ ^ nil
].
%{
int f = __intVal(fd);
@@ -653,45 +700,43 @@
int __channels = 0;
#if defined(DEV_AUDIO)
-# if defined(LINUX)
-# if defined(SNDCTL_DSP_GETBLKSIZE)
- if (ioctl(f, SNDCTL_DSP_GETBLKSIZE, &__blockSize) >= 0) {
- blockSize = __MKSMALLINT(__blockSize);
- }
-# endif
-# if defined(SNDCTL_DSP_CHANNELS)
- if (ioctl(f, SNDCTL_DSP_CHANNELS, &__channels) >= 0) {
- channels = __MKSMALLINT(__channels);
- }
-# endif
-# if defined(SNDCTL_DSP_STEREO)
- if (ioctl(f, SNDCTL_DSP_STEREO, &__stereo) >= 0) {
- stereo = __MKSMALLINT(__stereo);
- }
-# endif
-# if defined(SNDCTL_DSP_SPEED)
- if (ioctl(f, SNDCTL_DSP_SPEED, &__speed) >= 0) {
- speed = __MKSMALLINT(__speed);
- }
-# endif
-# else
channels = __MKSMALLINT(1);
stereo = __MKSMALLINT(0);
speed = __MKSMALLINT(8000);
-# endif /* LINUX */
+
+# if defined(SNDCTL_DSP_GETBLKSIZE)
+ if (ioctl(f, SNDCTL_DSP_GETBLKSIZE, &__blockSize) >= 0) {
+ blockSize = __MKSMALLINT(__blockSize);
+ }
+# endif
+# if defined(SNDCTL_DSP_CHANNELS)
+ if (ioctl(f, SNDCTL_DSP_CHANNELS, &__channels) >= 0) {
+ channels = __MKSMALLINT(__channels);
+ }
+# endif
+# if defined(SNDCTL_DSP_STEREO)
+ if (ioctl(f, SNDCTL_DSP_STEREO, &__stereo) >= 0) {
+ stereo = __MKSMALLINT(__stereo);
+ }
+# endif
+# if defined(SNDCTL_DSP_SPEED)
+ if (ioctl(f, SNDCTL_DSP_SPEED, &__speed) >= 0) {
+ speed = __MKSMALLINT(__speed);
+ }
+# endif
#endif /* DEV_AUDIO */
%}.
blockSize notNil ifTrue:[
- Transcript show:'blockSize: '; showCR:blockSize
+ Transcript show:'blockSize: '; showCR:blockSize
].
speed notNil ifTrue:[
- Transcript show:'speed: '; showCR:speed
+ Transcript show:'speed: '; showCR:speed
].
channels notNil ifTrue:[
- Transcript show:'channels: '; showCR:channels
+ Transcript show:'channels: '; showCR:channels
].
stereo notNil ifTrue:[
- Transcript show:'stereo: '; showCR:stereo
+ Transcript show:'stereo: '; showCR:stereo
].
Transcript show:'audioFormats: '; showCR:(self supportedAudioFormats).
@@ -705,21 +750,19 @@
"initialize for least common mode"
buffered := false.
- bitsPerSample := 8.
- audioFormat := #U8.
- numberOfChannels := 1.
- sampleRate := 8000.
+ bitsPerSample := self class defaultBitsPerSample.
+ audioFormat := self class defaultAudioFormat.
+ numberOfChannels := self class defaultNumberOfChannels.
+ sampleRate := self class defaultSampleRate.
+ pathName := nil.
- '/dev/audio' asFilename exists ifTrue:[
- "/
- "/ sunos or linux
- "/
- pathName := '/dev/audio'.
- ].
-
- OperatingSystem getOSType = 'irix' ifTrue:[
- "no device, use special library calls"
- pathName := nil.
+ OperatingSystem getOSType ~= 'win32' ifTrue:[
+ '/dev/audio' asFilename exists ifTrue:[
+ "/
+ "/ sunos or linux
+ "/
+ pathName := '/dev/audio'.
+ ].
].
"Created: 17.11.1995 / 17:28:14 / cg"
@@ -730,21 +773,25 @@
|fd|
- fd := self fileDescriptor.
- fd isNil ifTrue:[
- self error.
- ^ nil
+ filePointer notNil ifTrue:[
+ fd := self fileDescriptor.
+ fd isNil ifTrue:[
+ self error.
+ ^ nil
+ ]
].
%{
int f = __intVal(fd);
int __dummy;
-#if defined(DEV_AUDIO) && defined(LINUX)
+#if defined(DEV_AUDIO)
+ if (__isSmallInteger(fd)) {
# if defined(SNDCTL_DSP_RESET)
- if (ioctl(f, SNDCTL_DSP_RESET, &__dummy) >= 0) {
- RETURN (self);
+ if (ioctl(f, SNDCTL_DSP_RESET, &__dummy) >= 0) {
+ RETURN (self);
+ }
+# endif
}
-# endif
#endif
%}.
^ UnsupportedOperationSignal raise
@@ -760,82 +807,111 @@
|fd|
- fd := self fileDescriptor.
- fd isNil ifTrue:[
- self error.
- ^ nil
+ filePointer notNil ifTrue:[
+ fd := self fileDescriptor.
+ fd isNil ifTrue:[
+ self error.
+ ^ nil
+ ]
].
%{
int f = __intVal(fd);
int __fmt = 0, __fmtWant;
union {
- unsigned short us;
- unsigned char ub[2];
+ unsigned short us;
+ unsigned char ub[2];
} u;
OBJ sym = aSymbol;
-#if defined(DEV_AUDIO) && defined(LINUX)
- if (__isSymbol(sym)) {
- if (sym == @symbol(U16)) {
- u.us = 0x1234;
- if (u.ub[0] == 0x34) {
+#if defined(DEV_AUDIO)
+ if (__isSmallInteger(fd)) {
+ if (__isSymbol(sym)) {
+ if (sym == @symbol(U16)) {
+ u.us = 0x1234;
+ if (u.ub[0] == 0x34) {
/* printf("U16_LE\n"); */
- sym = @symbol(U16_LE);
- } else {
+ sym = @symbol(U16_LE);
+ } else {
/* printf("U16_BE\n"); */
- sym = @symbol(U16_BE);
- }
- } else if (sym == @symbol(S16)) {
- u.us = 0x1234;
- if (u.ub[0] == 0x34) {
+ sym = @symbol(U16_BE);
+ }
+ } else if (sym == @symbol(S16)) {
+ u.us = 0x1234;
+ if (u.ub[0] == 0x34) {
/* printf("S16_LE\n"); */
- sym = @symbol(S16_LE);
- } else {
+ sym = @symbol(S16_LE);
+ } else {
/* printf("S16_BE\n"); */
- sym = @symbol(S16_BE);
- }
- }
+ sym = @symbol(S16_BE);
+ }
+ }
- if (sym == @symbol(MU_LAW)) {
- __fmt = AFMT_MU_LAW;
- } else if (sym == @symbol(A_LAW)) {
- __fmt = AFMT_A_LAW;
- } else if (sym == @symbol(IMA_ADPCM)) {
- __fmt = AFMT_IMA_ADPCM;
- } else if (sym == @symbol(U8)) {
- __fmt = AFMT_U8;
- } else if (sym == @symbol(S8)) {
- __fmt = AFMT_S8;
- } else if (sym == @symbol(U16_LE)) {
- __fmt = AFMT_U16_LE;
- } else if (sym == @symbol(U16_BE)) {
- __fmt = AFMT_U16_BE;
- } else if (sym == @symbol(S16_LE)) {
- __fmt = AFMT_S16_LE;
- } else if (sym == @symbol(S16_BE)) {
- __fmt = AFMT_S16_BE;
- } else if (sym == @symbol(MPEG)) {
- __fmt = AFMT_MPEG;
- } else {
- fprintf(stderr, "bad format: %s\n", __stringVal(sym));
- goto bad;
- }
+ if (0) {
+#ifdef AFMT_MU_LAW
+ } else if (sym == @symbol(MU_LAW)) {
+ __fmt = AFMT_MU_LAW;
+#endif
+#ifdef AFMT_A_LAW
+ } else if (sym == @symbol(A_LAW)) {
+ __fmt = AFMT_A_LAW;
+#endif
+#ifdef AFMT_IMA_ADPCM
+ } else if (sym == @symbol(IMA_ADPCM)) {
+ __fmt = AFMT_IMA_ADPCM;
+#endif
+#ifdef AFMT_U8
+ } else if (sym == @symbol(U8)) {
+ __fmt = AFMT_U8;
+#endif
+#ifdef AFMT_S8
+ } else if (sym == @symbol(S8)) {
+ __fmt = AFMT_S8;
+#endif
+#ifdef AFMT_U16_LE
+ } else if (sym == @symbol(U16_LE)) {
+ __fmt = AFMT_U16_LE;
+#endif
+#ifdef AFMT_U16_BE
+ } else if (sym == @symbol(U16_BE)) {
+ __fmt = AFMT_U16_BE;
+#endif
+#ifdef AFMT_S16_LE
+ } else if (sym == @symbol(S16_LE)) {
+ __fmt = AFMT_S16_LE;
+#endif
+#ifdef AFMT_S16_BE
+ } else if (sym == @symbol(S16_BE)) {
+ __fmt = AFMT_S16_BE;
+#endif
+#ifdef AFMT_MPEG
+ } else if (sym == @symbol(MPEG)) {
+ __fmt = AFMT_MPEG;
+#endif
+ } else {
+ fprintf(stderr, "bad format: %s\n", __stringVal(sym));
+ goto bad;
+ }
+ }
+
+ __fmtWant = __fmt;
+
+#ifdef SNDCTL_DSP_SETFMT
+ if (ioctl(f, SNDCTL_DSP_SETFMT, &__fmt) >= 0) {
+ if (__fmt == __fmtWant) {
+ __INST(audioFormat) = sym;
+ RETURN (self);
+ } else {
+ /* fprintf(stderr, "want: %x; got: %x\n", __fmtWant, __fmt); */
+ }
+ } else {
+ /* fprintf(stderr, "got err-return from setFmp %x\n", __fmt); */
+ }
+#endif /* SNDCTL_DSP_SETFMT */
+
+bad: ;
}
-
- __fmtWant = __fmt;
+#endif /* DEV_AUDIO */
- if (ioctl(f, SNDCTL_DSP_SETFMT, &__fmt) >= 0) {
- if (__fmt == __fmtWant) {
- __INST(audioFormat) = sym;
- RETURN (self);
- } else {
- /* fprintf(stderr, "want: %x; got: %x\n", __fmtWant, __fmt); */
- }
- } else {
- /* fprintf(stderr, "got err-return from setFmp %x\n", __fmt); */
- }
-bad: ;
-#endif
%}.
^ UnsupportedOperationSignal raise
@@ -852,17 +928,19 @@
|fd|
- fd := self fileDescriptor.
- fd isNil ifTrue:[
- self error.
- ^ nil
+ filePointer notNil ifTrue:[
+ fd := self fileDescriptor.
+ fd isNil ifTrue:[
+ self error.
+ ^ nil
+ ]
].
%{
int f = __intVal(fd);
int __nCh = 0;
-#if defined(DEV_AUDIO) && defined(LINUX)
- if (__isSmallInteger(nChannels)) {
+#if defined(DEV_AUDIO) && defined(SOUND_PCM_WRITE_CHANNELS)
+ if (__isSmallInteger(fd) && __isSmallInteger(nChannels)) {
__nCh = __intVal(nChannels);
if (ioctl(f, SOUND_PCM_WRITE_CHANNELS, &__nCh) >= 0) {
__INST(numberOfChannels) = nChannels;
@@ -886,17 +964,19 @@
|fd|
- fd := self fileDescriptor.
- fd isNil ifTrue:[
- self error.
- ^ nil
+ filePointer notNil ifTrue:[
+ fd := self fileDescriptor.
+ fd isNil ifTrue:[
+ self error.
+ ^ nil
+ ]
].
%{
int f = __intVal(fd);
int __blockSize = 0;
-#if defined(DEV_AUDIO) && defined(LINUX)
- if (__isSmallInteger(blockSize)) {
+#if defined(DEV_AUDIO) && defined(SNDCTL_DSP_SETFRAGMENT)
+ if (__isSmallInteger(fd) && __isSmallInteger(blockSize)) {
__blockSize = __intVal(blockSize);
if (ioctl(f, SNDCTL_DSP_SETFRAGMENT, &__blockSize) >= 0) {
/* __INST(blockSize) = blockSize; */
@@ -914,18 +994,20 @@
|fd|
- fd := self fileDescriptor.
- fd isNil ifTrue:[
- self error.
- ^ nil
+ filePointer notNil ifTrue:[
+ fd := self fileDescriptor.
+ fd isNil ifTrue:[
+ self error.
+ ^ nil
+ ]
].
%{
int f = __intVal(fd);
int __rate = 0;
int __rateWant;
-#if defined(DEV_AUDIO) && defined(LINUX)
- if (__isSmallInteger(hz)) {
+#if defined(DEV_AUDIO) && defined(SOUND_PCM_WRITE_RATE)
+ if (__isSmallInteger(fd) && __isSmallInteger(hz)) {
__rate = __rateWant = __intVal(hz);
if (ioctl(f, SOUND_PCM_WRITE_RATE, &__rate) >= 0) {
if (__rate != __rateWant) {
@@ -961,6 +1043,7 @@
S16_LE signed 16bit little endian samples
S16_BE signed 16bit big endian samples
MPEG audio mpeg encoded
+ PCM pcm
"
|fd audioFormatMask
@@ -969,7 +1052,7 @@
supports_IMA_ADPCM supports_U8
supports_S16_LE supports_S16_BE
supports_S8 supports_U16_LE
- supports_U16_BE supports_MPEG|
+ supports_U16_BE supports_MPEG supports_PCM|
fd := self fileDescriptor.
fd isNil ifTrue:[
@@ -981,23 +1064,43 @@
int __audioFormatMask = 0;
#if defined(DEV_AUDIO)
-# if defined(LINUX)
+ supports_MU_LAW = true;
+
+# if defined(SNDCTL_DSP_GETFMTS)
if (ioctl(f, SNDCTL_DSP_GETFMTS, &__audioFormatMask) >= 0) {
audioFormatMask = __MKSMALLINT(__audioFormatMask);
+# ifdef AFMT_MU_LAW
supports_MU_LAW = (__audioFormatMask & AFMT_MU_LAW) ? true : false;
+# endif
+# ifdef AFMT_A_LAW
supports_A_LAW = (__audioFormatMask & AFMT_A_LAW) ? true : false;
+# endif
+# ifdef AFMT_IMA_ADPCM
supports_IMA_ADPCM = (__audioFormatMask & AFMT_IMA_ADPCM) ? true : false;
+# endif
+# ifdef AFMT_U8
supports_U8 = (__audioFormatMask & AFMT_U8) ? true : false;
+# endif
+# ifdef AFMT_S16_LE
supports_S16_LE = (__audioFormatMask & AFMT_S16_LE) ? true : false;
+# endif
+# ifdef AFMT_S16_BE
supports_S16_BE = (__audioFormatMask & AFMT_S16_BE) ? true : false;
+# endif
+# ifdef AFMT_S8
supports_S8 = (__audioFormatMask & AFMT_S8) ? true : false;
+# endif
+# ifdef AFMT_U16_LE
supports_U16_LE = (__audioFormatMask & AFMT_U16_LE) ? true : false;
+# endif
+# ifdef AFMT_U16_BE
supports_U16_BE = (__audioFormatMask & AFMT_U16_BE) ? true : false;
+# endif
+# ifdef AFMT_MPEG
supports_MPEG = (__audioFormatMask & AFMT_MPEG) ? true : false;
+# endif
}
-# else
- supports_MU_LAW = true;
# endif
#endif /* DEV_AUDIO */
@@ -1007,6 +1110,10 @@
supports_U16_BE = true;
#endif
+#ifdef WIN32
+ supports_S16_LE = true;
+#endif
+
%}.
supportedFormats := IdentitySet new.
supports_MU_LAW ifTrue:[
@@ -1057,10 +1164,13 @@
!SoundStream methodsFor:'redefined'!
-close
+XXclose
OperatingSystem getOSType = 'irix' ifTrue:[
^ self closeFile
].
+ OperatingSystem getOSType = 'win32' ifTrue:[
+ ^ self closeFile
+ ].
super close
@@ -1075,9 +1185,32 @@
#ifdef IRIS_AUDIO
OBJ port;
- if ((port = __INST(filePointer)) != nil) {
- __INST(filePointer) = nil;
- ALcloseport(_ALportVal(port));
+ if ((port = __INST(alPort)) != nil) {
+ __INST(alPort) = nil;
+ ALcloseport(__ALportVal(port));
+ }
+ RETURN (self);
+#endif
+
+#ifdef WIN32
+ OBJ oDirectSound, oDSBuffer;
+ LPDIRECTSOUND t_pDirectSound;
+ LPDIRECTSOUNDBUFFER t_pDSBuffer;
+
+ if ((oDSBuffer = __INST(pDSBuffer)) != nil) {
+ __INST(pDSBuffer) = nil;
+ t_pDSBuffer = __DSBufferVal(oDSBuffer);
+ if (t_pDSBuffer) {
+ IDirectSoundBuffer_Stop(t_pDSBuffer);
+ IDirectSoundBuffer_Release(t_pDSBuffer);
+ }
+ }
+ if ((oDirectSound = __INST(pDirectSound)) != nil) {
+ __INST(pDirectSound) = nil;
+ t_pDirectSound = __DirectSoundVal(oDirectSound);
+ if (t_pDirectSound) {
+ IDirectSound_Release(t_pDirectSound);
+ }
}
RETURN (self);
#endif
@@ -1119,10 +1252,11 @@
fd := self fileDescriptor.
%{
#ifdef IRIS_AUDIO
+ OPJ port;
ALport p;
- if (__INST(filePointer) != nil) {
- p = _ALportVal(__INST(filePointer));
+ if ((port = __INST(alPort)) != nil) {
+ p = __ALportVal(port);
while (ALgetfilled(p) > 0) {
sginap(1);
}
@@ -1130,7 +1264,7 @@
RETURN(self);
#endif
-#if defined(DEV_AUDIO) && defined(LINUX)
+#if defined(DEV_AUDIO)
if (__isSmallInteger(fd)) {
int f = __intVal(fd);
/* ... */
@@ -1141,6 +1275,12 @@
^ self
!
+isOpen
+ alPort notNil ifTrue:[^ true].
+ pDirectSound notNil ifTrue:[^ true].
+ ^ filePointer notNil
+!
+
nextBytes:count into:anObject startingAt:start
"read the next count bytes into an object and return the number of
bytes read or nil on error.
@@ -1149,24 +1289,26 @@
%{
#ifdef IRIS_AUDIO
{
+ OBJ port;
ALport p;
- int cnt, offs;
+ int cnt, offs, nSamp;
int objSize;
char *cp;
- if (__INST(filePointer) != nil) {
+ if ((port = __INST(alPort)) != nil) {
if (__INST(mode) != _writeonly) {
if (__bothSmallInteger(count, start)) {
- cnt = _intVal(count);
- offs = _intVal(start) - 1;
- p = _ALportVal(__INST(filePointer));
+ cnt = __intVal(count);
+ offs = __intVal(start) - 1;
+ p = __ALportVal(port);
objSize = _Size(anObject) - OHDR_SIZE;
if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
cp = (char *)__InstPtr(anObject) + OHDR_SIZE + offs;
if (__INST(bitsPerSample) == __MKSMALLINT(16))
- ALreadsamps(p, cp, cnt / 2);
+ nSamp = cnt / 2;
else
- ALreadsamps(p, cp, cnt);
+ nSamp = cnt;
+ ALreadsamps(p, cp, nSamp);
RETURN ( __MKSMALLINT(cnt) );
}
}
@@ -1176,7 +1318,9 @@
#endif
%}.
OperatingSystem getOSType = 'irix' ifFalse:[
- ^ super nextPutBytes:count from:anObject startingAt:start
+ OperatingSystem getOSType = 'win32' ifFalse:[
+ ^ super nextPutBytes:count from:anObject startingAt:start
+ ].
].
filePointer isNil ifTrue:[^ self errorNotOpen].
(mode == #writeonly) ifTrue:[^ self errorWriteOnly].
@@ -1192,17 +1336,18 @@
%{
#ifdef IRIS_AUDIO
{
+ OBJ port;
ALport p;
- int cnt, offs;
+ int cnt, offs, nSamp;
int objSize;
char *cp;
- if (__INST(filePointer) != nil) {
+ if ((port = __INST(alPort)) != nil) {
if (__INST(mode) != @symbol(readonly)) {
if (__bothSmallInteger(count, start)) {
- cnt = _intVal(count);
- offs = _intVal(start) - 1;
- p = _ALportVal(__INST(filePointer));
+ cnt = __intVal(count);
+ offs = __intVal(start) - 1;
+ p = __ALportVal(port);
/*
* compute number of samples
@@ -1211,16 +1356,99 @@
if ( (offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs)) ) {
cp = (char *)__InstPtr(anObject) + OHDR_SIZE + offs;
if (__INST(bitsPerSample) == __MKSMALLINT(16))
- ALwritesamps(p, cp, cnt / 2);
+ nSamp = cnt / 2;
else
- ALwritesamps(p, cp, cnt);
+ nSamp = cnt;
+ ALwritesamps(p, cp, cnt);
RETURN ( count );
}
}
}
}
}
-#endif
+#endif /* SGI_AUDIO */
+
+#ifdef WIN32
+ {
+ HRESULT hr;
+ DWORD status;
+ LPVOID lpbuf1 = NULL;
+ LPVOID lpbuf2 = NULL;
+ DWORD dwsize1 = 0;
+ DWORD dwsize2 = 0;
+ DWORD playPos, safePos, endWrite;
+ DWORD millis;
+ OBJ oDirectSound, oDSBuffer;
+ LPDIRECTSOUND t_pDirectSound = (LPDIRECTSOUND)0;
+ LPDIRECTSOUNDBUFFER t_pDSBuffer = (LPDIRECTSOUNDBUFFER)0;
+ int t_cbBufOffset, t_cbBufSize;
+ short *buf;
+ int cnt, offs;
+
+ if ((oDSBuffer = __INST(pDSBuffer)) != nil) {
+ t_pDSBuffer = __DSBufferVal(oDSBuffer);
+ }
+ if ((oDirectSound = __INST(pDirectSound)) != nil) {
+ t_pDirectSound = __DirectSoundVal(oDirectSound);
+ }
+
+ if (!t_pDSBuffer || !t_pDirectSound) {
+ RETURN (0);
+ }
+ t_cbBufOffset = __intVal(__INST(cbBufOffset));
+ t_cbBufSize = __intVal(__INST(cbBufSize));
+
+ cnt = __intVal(count);
+ offs = __intVal(start) - 1;
+ buf = (short *)__InstPtr(anObject) + OHDR_SIZE + offs;
+
+ // Should be playing, right?
+ hr = IDirectSoundBuffer_GetStatus(t_pDSBuffer, &status );
+ if (!(status && DSBSTATUS_PLAYING)) {
+ printf("Buffer not playing!\n");
+ }
+
+ // Sleep until we have enough room in buffer.
+ hr = IDirectSoundBuffer_GetCurrentPosition(t_pDSBuffer, &playPos, &safePos );
+ if( hr != DS_OK ) {
+ RETURN (0);
+ }
+ if( playPos < t_cbBufOffset ) playPos += t_cbBufSize;
+
+ endWrite = t_cbBufOffset + RT_BUFFER_SIZE * sizeof(short);
+ while ( playPos < endWrite ) {
+ // Calculate number of milliseconds until we will have room, as
+ // time = distance * (milliseconds/second) / ((bytes/sample) * (samples/second)),
+ // rounded up.
+ millis = (DWORD) (1.0 + ((endWrite - playPos) * 1000.0) / ( sizeof(short) * __intVal(__INST(sampleRate))));
+
+ // Sleep for that long
+ Sleep( millis );
+
+ // Wake up, find out where we are now
+ hr = IDirectSoundBuffer_GetCurrentPosition(t_pDSBuffer, &playPos, &safePos );
+ if( hr != DS_OK ) {
+ RETURN (0);
+ }
+ if( playPos < t_cbBufOffset ) playPos += t_cbBufSize; // unwrap offset
+ }
+
+ // Lock free space in the DS
+ hr = IDirectSoundBuffer_Lock(t_pDSBuffer, t_cbBufOffset, RT_BUFFER_SIZE * sizeof(short), &lpbuf1, &dwsize1, &lpbuf2, &dwsize2, 0);
+ if (hr == DS_OK) {
+ // Copy the buffer into the DS
+ CopyMemory(lpbuf1, buf, dwsize1);
+ if(NULL != lpbuf2) CopyMemory(lpbuf2, buf+dwsize1, dwsize2);
+
+ // Update our buffer offset and unlock sound buffer
+ t_cbBufOffset = (t_cbBufOffset + dwsize1 + dwsize2) % t_cbBufSize;
+ IDirectSoundBuffer_Unlock(t_pDSBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);
+ }
+ __INST(cbBufOffset) = __MKSMALLINT(t_cbBufOffset);
+
+ RETURN (0);
+ }
+#endif /* WIN32 */
#if defined(DEV_AUDIO)
/*
@@ -1243,18 +1471,18 @@
f = __FILEVal(fp);
if (__INST(mode) != @symbol(readonly)) {
if (__bothSmallInteger(count, start)) {
- cnt = _intVal(count);
- offs = _intVal(start) - 1;
+ cnt = __intVal(count);
+ offs = __intVal(start) - 1;
objSize = _Size(anObject) - OHDR_SIZE;
if ( (offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs)) ) {
do {
- cp = (char *)__InstPtr(anObject) + OHDR_SIZE + offs;
+ cp = (char *)__InstPtr(anObject) + OHDR_SIZE + offs;
n = cnt;
if (n > 4096) n = 4096;
# ifdef LINUX
- sigsetmask(~0);
+ sigsetmask(~0);
# endif
if (__INST(buffered) == true) {
n = fwrite(cp, 1, n, f);
@@ -1263,7 +1491,7 @@
n = write(fd, cp, n);
}
# ifdef LINUX
- sigsetmask(0);
+ sigsetmask(0);
# endif
__BEGIN_INTERRUPTABLE__
__END_INTERRUPTABLE__
@@ -1283,23 +1511,35 @@
^ super nextPutBytes:count from:anObject startingAt:start
!
+openForReading
+ |rslt|
+
+ mode := #readonly.
+ didWrite := false.
+ (rslt := self openWithMode:ReadMode) notNil ifTrue:[
+ Lobby register:self
+ ].
+ ^ rslt
+!
+
openForWriting
"open the file writeonly.
If the file does not exist its an error, return nil;
otherwise return the receiver."
+ |rslt|
+
mode := #writeonly.
didWrite := true.
- ^ self openWithMode:WriteMode
+ (rslt := self openWithMode:WriteMode) notNil ifTrue:[
+ Lobby register:self
+ ].
+ ^ rslt
"Created: / 15.12.1997 / 13:13:56 / cg"
!
openWithMode:aMode
- ((aMode = 'r') or:[aMode = 'w']) ifFalse:[
- self error:'invalid mode'.
- ^ nil
- ].
%{
#ifdef IRIS_AUDIO
{
@@ -1322,14 +1562,16 @@
ALsetwidth(config, AL_SAMPLE_8);
if (__isSmallInteger(__INST(sampleRate)))
- params[3] = params[5] = _intVal(__INST(sampleRate));
+ params[3] = params[5] = __intVal(__INST(sampleRate));
ALsetparams(AL_DEFAULT_DEVICE, params, 6);
p = ALopenport("smallchat", (char *)_stringVal(aMode), config);
if (p) {
- __INST(filePointer) = __MKEXTERNALADDRESS(p);
+ OBJ t;
+
+ __INST(alPort) = t = __MKEXTERNALADDRESS(p); __STORE(self, t);
} else {
- __INST(filePointer) = nil;
+ __INST(alPort) = nil;
RETURN (nil);
}
__INST(binary) = true;
@@ -1368,7 +1610,125 @@
ALfreeconfig(config);
RETURN (self);
}
+#endif /* SGI_AUDIO */
+
+#ifdef WIN32
+ {
+ HRESULT result;
+ LPDIRECTSOUND t_pDirectSound;
+ LPDIRECTSOUNDBUFFER t_pDSBuffer, t_pDSPrimeBuffer;
+ WAVEFORMATEX wfFormat;
+ DSBUFFERDESC dsbdDesc, primarydsbDesc;
+ BYTE *pDSBuffData;
+ int t_cbBufSize;
+ int dwDataLen;
+
+ /* Create the DS object */
+ if ((result = DirectSoundCreate(NULL, &t_pDirectSound, NULL)) != DS_OK) {
+ fprintf(stderr,"SoundStream: Cannot open default sound device!!\n");
+ RETURN (nil);
+ }
+
+ /* Define the wave format structure */
+ wfFormat.wFormatTag = WAVE_FORMAT_PCM;
+ wfFormat.nChannels = __intVal(__INST(numberOfChannels));
+ wfFormat.nSamplesPerSec = __intVal(__INST(sampleRate));
+ wfFormat.wBitsPerSample = __intVal(__INST(bitsPerSample));
+ wfFormat.nBlockAlign = wfFormat.nChannels * wfFormat.wBitsPerSample / 8;
+ wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;
+ wfFormat.cbSize = 0;
+#if 0
+ /* Setup the primary DS buffer description */
+ ZeroMemory(&primarydsbDesc, sizeof(DSBUFFERDESC));
+ primarydsbDesc.dwSize = sizeof(DSBUFFERDESC);
+ primarydsbDesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
+ primarydsbDesc.dwBufferBytes = 0;
+ primarydsbDesc.lpwfxFormat = NULL;
+
+ /* Create the primary DS buffer */
+ if ((result = IDirectSound_CreateSoundBuffer(t_pDirectSound, &primarydsbDesc,
+ &t_pDSPrimeBuffer, NULL)) != DS_OK) {
+ fprintf(stderr,"SoundStream: Cannot get the primary DS buffer address!\n");
+ IDirectSound_Release(t_pDirectSound);
+ RETURN (nil);
+ }
+
+ /* Set the primary DS buffer sound format. We have to do this because
+ the default primary buffer is 8-bit, 22kHz! */
+ if ((result = IDirectSoundBuffer_SetFormat(t_pDSPrimeBuffer, &wfFormat)) != DS_OK) {
+ fprintf(stderr,"SoundStream: Cannot set the primary DS buffer to proper sound format (%x) (%d)!\n", result, result);
+ IDirectSoundBuffer_Stop(t_pDSPrimeBuffer);
+ IDirectSoundBuffer_Release(t_pDSPrimeBuffer);
+ IDirectSound_Release(t_pDirectSound);
+ RETURN (nil);
+ }
#endif
+
+ /* Setup the secondary DS buffer description */
+ t_cbBufSize = RT_BUFFER_SIZE * sizeof(short) * NBUFS;
+ __INST(cbBufSize) = __MKSMALLINT(t_cbBufSize);
+
+ ZeroMemory(&dsbdDesc, sizeof(DSBUFFERDESC));
+ dsbdDesc.dwSize = sizeof(DSBUFFERDESC);
+ dsbdDesc.dwFlags = DSBCAPS_GLOBALFOCUS;
+ dsbdDesc.dwBufferBytes = t_cbBufSize;
+ dsbdDesc.lpwfxFormat = &wfFormat;
+
+ /* Create the secondary DS buffer */
+ if ((result = IDirectSound_CreateSoundBuffer(t_pDirectSound, &dsbdDesc, &t_pDSBuffer, NULL)) != DS_OK) {
+ fprintf(stderr,"SoundStream: couldn't create sound buffer!\n");
+ IDirectSoundBuffer_Stop(t_pDSPrimeBuffer);
+ IDirectSoundBuffer_Release(t_pDSPrimeBuffer);
+ IDirectSound_Release(t_pDirectSound);
+ RETURN (nil);
+ }
+
+ /* Lock the DS buffer */
+ if ((result = IDirectSoundBuffer_Lock(t_pDSBuffer, 0, t_cbBufSize, (LPLPVOID)&pDSBuffData,
+ &dwDataLen, NULL, NULL, 0)) != DS_OK) {
+ fprintf(stderr,"SoundStream: couldn't lock sound buffer!\n");
+ IDirectSoundBuffer_Stop(t_pDSBuffer);
+ IDirectSoundBuffer_Stop(t_pDSPrimeBuffer);
+ IDirectSoundBuffer_Release(t_pDSPrimeBuffer);
+ IDirectSound_Release(t_pDirectSound);
+ RETURN (nil);
+ }
+
+ /* Zero the DS buffer */
+ ZeroMemory(pDSBuffData, dwDataLen);
+
+ /* Unlock the DS buffer */
+ if ((result = IDirectSoundBuffer_Unlock(t_pDSBuffer, pDSBuffData, dwDataLen, NULL, 0)) != DS_OK) {
+ fprintf(stderr,"SoundStream: couldn't unlock sound buffer!\n");
+ IDirectSoundBuffer_Stop(t_pDSBuffer);
+ IDirectSoundBuffer_Stop(t_pDSPrimeBuffer);
+ IDirectSoundBuffer_Release(t_pDSPrimeBuffer);
+ IDirectSound_Release(t_pDirectSound);
+ RETURN (nil);
+ }
+
+ __INST(cbBufOffset) = __MKSMALLINT(0); // reset last write position to start of buffer
+
+ /* Start the buffer playback */
+ if ((result = IDirectSoundBuffer_Play(t_pDSBuffer, 0, 0, DSBPLAY_LOOPING ) != DS_OK)) {
+ fprintf(stderr,"SoundStream: couldn't play sound buffer!\n");
+ IDirectSoundBuffer_Stop(t_pDSBuffer);
+ IDirectSoundBuffer_Stop(t_pDSPrimeBuffer);
+ IDirectSoundBuffer_Release(t_pDSPrimeBuffer);
+ IDirectSound_Release(t_pDirectSound);
+ RETURN (nil);
+ }
+
+ {
+ OBJ t;
+
+ __INST(pDSBuffer) = t = __MKEXTERNALADDRESS(t_pDSBuffer); __STORE(self, t);
+ __INST(pDirectSound) = t = __MKEXTERNALADDRESS(t_pDirectSound); __STORE(self, t);
+ }
+ RETURN (self);
+ }
+#endif /* WIN32 */
+
%}.
"its a regular file open (i.e. /dev/audio) "
^ super openWithMode:aMode
@@ -1405,15 +1765,15 @@
scale := freq * 2 * (Float pi).
1 to:numSamples do:[:i |
- val := (scale * i / numSamples) sin.
- val := (val * 16r7FFF) rounded bitAnd:16rFFFF.
- buffer at:i put:val
+ val := (scale * i / numSamples) sin.
+ val := (val * 16r7FFF) rounded bitAnd:16rFFFF.
+ buffer at:i put:val
].
oldFormat := audioFormat.
self setAudioFormat:#S16.
1 to:3 do:[:s |
- self nextPutBytes:(numSamples*2) from:buffer startingAt:1
+ self nextPutBytes:(numSamples*2) from:buffer startingAt:1
].
self setAudioFormat:oldFormat.
@@ -1443,15 +1803,15 @@
scale := freq * 2 * (Float pi).
1 to:numSamples do:[:i |
- val := (scale * i / numSamples) sin.
- val := (val * 127 + 128) rounded.
- buffer at:i put:val
+ val := (scale * i / numSamples) sin.
+ val := (val * 127 + 128) rounded.
+ buffer at:i put:val
].
oldFormat := audioFormat.
self setAudioFormat:#U8.
1 to:3 do:[:s |
- self nextPutBytes:numSamples from:buffer startingAt:1
+ self nextPutBytes:numSamples from:buffer startingAt:1
].
self setAudioFormat:oldFormat.
@@ -1494,15 +1854,15 @@
scale := freq * 2 * (Float pi).
1 to:numSamples do:[:i |
- val := (scale * i / numSamples) sin.
- val := (val * 16r7FFF) rounded.
- buffer at:i put:(self class linear16ToUlaw:val)
+ val := (scale * i / numSamples) sin.
+ val := (val * 16r7FFF) rounded.
+ buffer at:i put:(self class linear16ToUlaw:val)
].
oldFormat := audioFormat.
self setAudioFormat:#MU_LAW.
1 to:3 do:[:s |
- self nextPutBytes:numSamples from:buffer startingAt:1
+ self nextPutBytes:numSamples from:buffer startingAt:1
].
self setAudioFormat:oldFormat.
@@ -1521,5 +1881,5 @@
!SoundStream class methodsFor:'documentation'!
version
-^ '$Header: /cvs/stx/stx/libbasic2/Attic/SoundStr.st,v 1.33 1998-02-08 00:45:12 cg Exp $'! !
+^ '$Header: /cvs/stx/stx/libbasic2/Attic/SoundStr.st,v 1.34 1998-12-21 11:43:58 cg Exp $'! !
SoundStream initialize!
--- a/SoundStream.st Thu Dec 17 14:24:26 1998 +0100
+++ b/SoundStream.st Mon Dec 21 12:43:58 1998 +0100
@@ -11,7 +11,9 @@
"
FileStream subclass:#SoundStream
- instanceVariableNames:'sampleRate numberOfChannels bitsPerSample audioFormat'
+ instanceVariableNames:'sampleRate numberOfChannels bitsPerSample audioFormat
+ alPort
+ pDirectSound pDSBuffer cbBufOffset cbBufSize'
classVariableNames:'UnsupportedOperationSignal'
poolDictionaries:''
category:'Streams-External'
@@ -27,7 +29,7 @@
#ifdef IRIS_AUDIO
# include <audio.h>
-# define _ALportVal(o) (ALport)(__externalAddressVal(o))
+# define __ALportVal(o) (ALport)(__externalAddressVal(o))
#endif
#ifdef LINUX
@@ -42,6 +44,67 @@
#ifdef DEV_AUDIO
# include <stdio.h>
#endif
+
+#ifdef WIN32
+
+# define _WIN32
+
+# undef INT
+# undef Array
+# undef Number
+# undef Method
+# undef Point
+# undef Rectangle
+# undef Block
+# undef String
+# undef Message
+# undef Object
+# undef Context
+
+/* # include <stdarg.h> /* */
+# include <stdio.h> /* */
+# include <windows.h>
+# define CINTERFACE
+# include "dsound.h"
+
+# ifdef __DEF_Array
+# define Array __DEF_Array
+# endif
+# ifdef __DEF_Number
+# define Number __DEF_Number
+# endif
+# ifdef __DEF_Method
+# define Method __DEF_Method
+# endif
+# ifdef __DEF_Point
+# define Point __DEF_Point
+# endif
+# ifdef __DEF_Block
+# define Block __DEF_Block
+# endif
+# ifdef __DEF_String
+# define String __DEF_String
+# endif
+# ifdef __DEF_Message
+# define Message __DEF_Message
+# endif
+# ifdef __DEF_Object
+# define Object __DEF_Object
+# endif
+# ifdef __DEF_Context
+# define Context __DEF_Context
+# endif
+
+# define INT int
+
+# define __DirectSoundVal(o) (LPDIRECTSOUND)(__externalAddressVal(o))
+# define __DSBufferVal(o) (LPDIRECTSOUNDBUFFER)(__externalAddressVal(o))
+
+# define RT_BUFFER_SIZE 4096
+# define NBUFS 4
+
+#endif
+
%}
! !
@@ -82,9 +145,9 @@
initialize
UnsupportedOperationSignal isNil ifTrue:[
- UnsupportedOperationSignal := StreamErrorSignal newSignalMayProceed:false.
- UnsupportedOperationSignal nameClass:self message:#unsupportedOperationSignal.
- UnsupportedOperationSignal notifierString:'unsupported operation'.
+ UnsupportedOperationSignal := StreamErrorSignal newSignalMayProceed:false.
+ UnsupportedOperationSignal nameClass:self message:#unsupportedOperationSignal.
+ UnsupportedOperationSignal notifierString:'unsupported operation'.
]
! !
@@ -124,7 +187,7 @@
"Modified: / 12.12.1997 / 16:51:38 / cg"
!
-writing16BitStero
+writing16BitStereo
"just an example, has never been tried (I also
have no samples for this ... leave it as an exercise)"
@@ -202,32 +265,10 @@
"/
"/ fallback for non-integral argument
"/
- sign := 0.
- (absVal := a16bitSignedValue asInteger) < 0 ifTrue:[
- (absVal <= -32256) ifTrue:[
- ^ 0
- ].
- absVal := absVal negated.
- sign := 16r80
- ] ifFalse:[
- absVal >= 32256 ifTrue:[
- ^ 128
- ]
+ a16bitSignedValue isInteger ifFalse:[
+ ^ self uLawToLinear16:a16bitSignedValue asInteger
].
-
- exp := #[
- 0 1 2 2 3 3 3 3 4 4 4 4 4 4 4 4
- 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
- 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
- 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
- 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
- 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
- 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
- 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
- ] at:(absVal bitShift:-1)+1.
- mantissa := (absVal bitShift:(exp+3) negated) bitAnd:16r0F.
- byte := ((sign bitOr:(exp bitShift:4)) bitOr:mantissa) bitInvert bitAnd:16rFF.
- ^ byte
+ ^ 0
"
SoundStream uLawToLinear16:(SoundStream linear16ToUlaw:0)
@@ -513,12 +554,18 @@
!SoundStream class methodsFor:'default values'!
defaultAudioFormat
+ OperatingSystem getOSType = 'win32' ifTrue:[
+ ^ #S16
+ ].
^ #U8
!
defaultBitsPerSample
"minimum, supported by all audio systems"
+ OperatingSystem getOSType = 'win32' ifTrue:[
+ ^ 16
+ ].
^ 8
!
@@ -642,8 +689,8 @@
fd := self fileDescriptor.
fd isNil ifTrue:[
- self error.
- ^ nil
+ self error.
+ ^ nil
].
%{
int f = __intVal(fd);
@@ -653,45 +700,43 @@
int __channels = 0;
#if defined(DEV_AUDIO)
-# if defined(LINUX)
-# if defined(SNDCTL_DSP_GETBLKSIZE)
- if (ioctl(f, SNDCTL_DSP_GETBLKSIZE, &__blockSize) >= 0) {
- blockSize = __MKSMALLINT(__blockSize);
- }
-# endif
-# if defined(SNDCTL_DSP_CHANNELS)
- if (ioctl(f, SNDCTL_DSP_CHANNELS, &__channels) >= 0) {
- channels = __MKSMALLINT(__channels);
- }
-# endif
-# if defined(SNDCTL_DSP_STEREO)
- if (ioctl(f, SNDCTL_DSP_STEREO, &__stereo) >= 0) {
- stereo = __MKSMALLINT(__stereo);
- }
-# endif
-# if defined(SNDCTL_DSP_SPEED)
- if (ioctl(f, SNDCTL_DSP_SPEED, &__speed) >= 0) {
- speed = __MKSMALLINT(__speed);
- }
-# endif
-# else
channels = __MKSMALLINT(1);
stereo = __MKSMALLINT(0);
speed = __MKSMALLINT(8000);
-# endif /* LINUX */
+
+# if defined(SNDCTL_DSP_GETBLKSIZE)
+ if (ioctl(f, SNDCTL_DSP_GETBLKSIZE, &__blockSize) >= 0) {
+ blockSize = __MKSMALLINT(__blockSize);
+ }
+# endif
+# if defined(SNDCTL_DSP_CHANNELS)
+ if (ioctl(f, SNDCTL_DSP_CHANNELS, &__channels) >= 0) {
+ channels = __MKSMALLINT(__channels);
+ }
+# endif
+# if defined(SNDCTL_DSP_STEREO)
+ if (ioctl(f, SNDCTL_DSP_STEREO, &__stereo) >= 0) {
+ stereo = __MKSMALLINT(__stereo);
+ }
+# endif
+# if defined(SNDCTL_DSP_SPEED)
+ if (ioctl(f, SNDCTL_DSP_SPEED, &__speed) >= 0) {
+ speed = __MKSMALLINT(__speed);
+ }
+# endif
#endif /* DEV_AUDIO */
%}.
blockSize notNil ifTrue:[
- Transcript show:'blockSize: '; showCR:blockSize
+ Transcript show:'blockSize: '; showCR:blockSize
].
speed notNil ifTrue:[
- Transcript show:'speed: '; showCR:speed
+ Transcript show:'speed: '; showCR:speed
].
channels notNil ifTrue:[
- Transcript show:'channels: '; showCR:channels
+ Transcript show:'channels: '; showCR:channels
].
stereo notNil ifTrue:[
- Transcript show:'stereo: '; showCR:stereo
+ Transcript show:'stereo: '; showCR:stereo
].
Transcript show:'audioFormats: '; showCR:(self supportedAudioFormats).
@@ -705,21 +750,19 @@
"initialize for least common mode"
buffered := false.
- bitsPerSample := 8.
- audioFormat := #U8.
- numberOfChannels := 1.
- sampleRate := 8000.
+ bitsPerSample := self class defaultBitsPerSample.
+ audioFormat := self class defaultAudioFormat.
+ numberOfChannels := self class defaultNumberOfChannels.
+ sampleRate := self class defaultSampleRate.
+ pathName := nil.
- '/dev/audio' asFilename exists ifTrue:[
- "/
- "/ sunos or linux
- "/
- pathName := '/dev/audio'.
- ].
-
- OperatingSystem getOSType = 'irix' ifTrue:[
- "no device, use special library calls"
- pathName := nil.
+ OperatingSystem getOSType ~= 'win32' ifTrue:[
+ '/dev/audio' asFilename exists ifTrue:[
+ "/
+ "/ sunos or linux
+ "/
+ pathName := '/dev/audio'.
+ ].
].
"Created: 17.11.1995 / 17:28:14 / cg"
@@ -730,21 +773,25 @@
|fd|
- fd := self fileDescriptor.
- fd isNil ifTrue:[
- self error.
- ^ nil
+ filePointer notNil ifTrue:[
+ fd := self fileDescriptor.
+ fd isNil ifTrue:[
+ self error.
+ ^ nil
+ ]
].
%{
int f = __intVal(fd);
int __dummy;
-#if defined(DEV_AUDIO) && defined(LINUX)
+#if defined(DEV_AUDIO)
+ if (__isSmallInteger(fd)) {
# if defined(SNDCTL_DSP_RESET)
- if (ioctl(f, SNDCTL_DSP_RESET, &__dummy) >= 0) {
- RETURN (self);
+ if (ioctl(f, SNDCTL_DSP_RESET, &__dummy) >= 0) {
+ RETURN (self);
+ }
+# endif
}
-# endif
#endif
%}.
^ UnsupportedOperationSignal raise
@@ -760,82 +807,111 @@
|fd|
- fd := self fileDescriptor.
- fd isNil ifTrue:[
- self error.
- ^ nil
+ filePointer notNil ifTrue:[
+ fd := self fileDescriptor.
+ fd isNil ifTrue:[
+ self error.
+ ^ nil
+ ]
].
%{
int f = __intVal(fd);
int __fmt = 0, __fmtWant;
union {
- unsigned short us;
- unsigned char ub[2];
+ unsigned short us;
+ unsigned char ub[2];
} u;
OBJ sym = aSymbol;
-#if defined(DEV_AUDIO) && defined(LINUX)
- if (__isSymbol(sym)) {
- if (sym == @symbol(U16)) {
- u.us = 0x1234;
- if (u.ub[0] == 0x34) {
+#if defined(DEV_AUDIO)
+ if (__isSmallInteger(fd)) {
+ if (__isSymbol(sym)) {
+ if (sym == @symbol(U16)) {
+ u.us = 0x1234;
+ if (u.ub[0] == 0x34) {
/* printf("U16_LE\n"); */
- sym = @symbol(U16_LE);
- } else {
+ sym = @symbol(U16_LE);
+ } else {
/* printf("U16_BE\n"); */
- sym = @symbol(U16_BE);
- }
- } else if (sym == @symbol(S16)) {
- u.us = 0x1234;
- if (u.ub[0] == 0x34) {
+ sym = @symbol(U16_BE);
+ }
+ } else if (sym == @symbol(S16)) {
+ u.us = 0x1234;
+ if (u.ub[0] == 0x34) {
/* printf("S16_LE\n"); */
- sym = @symbol(S16_LE);
- } else {
+ sym = @symbol(S16_LE);
+ } else {
/* printf("S16_BE\n"); */
- sym = @symbol(S16_BE);
- }
- }
+ sym = @symbol(S16_BE);
+ }
+ }
- if (sym == @symbol(MU_LAW)) {
- __fmt = AFMT_MU_LAW;
- } else if (sym == @symbol(A_LAW)) {
- __fmt = AFMT_A_LAW;
- } else if (sym == @symbol(IMA_ADPCM)) {
- __fmt = AFMT_IMA_ADPCM;
- } else if (sym == @symbol(U8)) {
- __fmt = AFMT_U8;
- } else if (sym == @symbol(S8)) {
- __fmt = AFMT_S8;
- } else if (sym == @symbol(U16_LE)) {
- __fmt = AFMT_U16_LE;
- } else if (sym == @symbol(U16_BE)) {
- __fmt = AFMT_U16_BE;
- } else if (sym == @symbol(S16_LE)) {
- __fmt = AFMT_S16_LE;
- } else if (sym == @symbol(S16_BE)) {
- __fmt = AFMT_S16_BE;
- } else if (sym == @symbol(MPEG)) {
- __fmt = AFMT_MPEG;
- } else {
- fprintf(stderr, "bad format: %s\n", __stringVal(sym));
- goto bad;
- }
+ if (0) {
+#ifdef AFMT_MU_LAW
+ } else if (sym == @symbol(MU_LAW)) {
+ __fmt = AFMT_MU_LAW;
+#endif
+#ifdef AFMT_A_LAW
+ } else if (sym == @symbol(A_LAW)) {
+ __fmt = AFMT_A_LAW;
+#endif
+#ifdef AFMT_IMA_ADPCM
+ } else if (sym == @symbol(IMA_ADPCM)) {
+ __fmt = AFMT_IMA_ADPCM;
+#endif
+#ifdef AFMT_U8
+ } else if (sym == @symbol(U8)) {
+ __fmt = AFMT_U8;
+#endif
+#ifdef AFMT_S8
+ } else if (sym == @symbol(S8)) {
+ __fmt = AFMT_S8;
+#endif
+#ifdef AFMT_U16_LE
+ } else if (sym == @symbol(U16_LE)) {
+ __fmt = AFMT_U16_LE;
+#endif
+#ifdef AFMT_U16_BE
+ } else if (sym == @symbol(U16_BE)) {
+ __fmt = AFMT_U16_BE;
+#endif
+#ifdef AFMT_S16_LE
+ } else if (sym == @symbol(S16_LE)) {
+ __fmt = AFMT_S16_LE;
+#endif
+#ifdef AFMT_S16_BE
+ } else if (sym == @symbol(S16_BE)) {
+ __fmt = AFMT_S16_BE;
+#endif
+#ifdef AFMT_MPEG
+ } else if (sym == @symbol(MPEG)) {
+ __fmt = AFMT_MPEG;
+#endif
+ } else {
+ fprintf(stderr, "bad format: %s\n", __stringVal(sym));
+ goto bad;
+ }
+ }
+
+ __fmtWant = __fmt;
+
+#ifdef SNDCTL_DSP_SETFMT
+ if (ioctl(f, SNDCTL_DSP_SETFMT, &__fmt) >= 0) {
+ if (__fmt == __fmtWant) {
+ __INST(audioFormat) = sym;
+ RETURN (self);
+ } else {
+ /* fprintf(stderr, "want: %x; got: %x\n", __fmtWant, __fmt); */
+ }
+ } else {
+ /* fprintf(stderr, "got err-return from setFmp %x\n", __fmt); */
+ }
+#endif /* SNDCTL_DSP_SETFMT */
+
+bad: ;
}
-
- __fmtWant = __fmt;
+#endif /* DEV_AUDIO */
- if (ioctl(f, SNDCTL_DSP_SETFMT, &__fmt) >= 0) {
- if (__fmt == __fmtWant) {
- __INST(audioFormat) = sym;
- RETURN (self);
- } else {
- /* fprintf(stderr, "want: %x; got: %x\n", __fmtWant, __fmt); */
- }
- } else {
- /* fprintf(stderr, "got err-return from setFmp %x\n", __fmt); */
- }
-bad: ;
-#endif
%}.
^ UnsupportedOperationSignal raise
@@ -852,17 +928,19 @@
|fd|
- fd := self fileDescriptor.
- fd isNil ifTrue:[
- self error.
- ^ nil
+ filePointer notNil ifTrue:[
+ fd := self fileDescriptor.
+ fd isNil ifTrue:[
+ self error.
+ ^ nil
+ ]
].
%{
int f = __intVal(fd);
int __nCh = 0;
-#if defined(DEV_AUDIO) && defined(LINUX)
- if (__isSmallInteger(nChannels)) {
+#if defined(DEV_AUDIO) && defined(SOUND_PCM_WRITE_CHANNELS)
+ if (__isSmallInteger(fd) && __isSmallInteger(nChannels)) {
__nCh = __intVal(nChannels);
if (ioctl(f, SOUND_PCM_WRITE_CHANNELS, &__nCh) >= 0) {
__INST(numberOfChannels) = nChannels;
@@ -886,17 +964,19 @@
|fd|
- fd := self fileDescriptor.
- fd isNil ifTrue:[
- self error.
- ^ nil
+ filePointer notNil ifTrue:[
+ fd := self fileDescriptor.
+ fd isNil ifTrue:[
+ self error.
+ ^ nil
+ ]
].
%{
int f = __intVal(fd);
int __blockSize = 0;
-#if defined(DEV_AUDIO) && defined(LINUX)
- if (__isSmallInteger(blockSize)) {
+#if defined(DEV_AUDIO) && defined(SNDCTL_DSP_SETFRAGMENT)
+ if (__isSmallInteger(fd) && __isSmallInteger(blockSize)) {
__blockSize = __intVal(blockSize);
if (ioctl(f, SNDCTL_DSP_SETFRAGMENT, &__blockSize) >= 0) {
/* __INST(blockSize) = blockSize; */
@@ -914,18 +994,20 @@
|fd|
- fd := self fileDescriptor.
- fd isNil ifTrue:[
- self error.
- ^ nil
+ filePointer notNil ifTrue:[
+ fd := self fileDescriptor.
+ fd isNil ifTrue:[
+ self error.
+ ^ nil
+ ]
].
%{
int f = __intVal(fd);
int __rate = 0;
int __rateWant;
-#if defined(DEV_AUDIO) && defined(LINUX)
- if (__isSmallInteger(hz)) {
+#if defined(DEV_AUDIO) && defined(SOUND_PCM_WRITE_RATE)
+ if (__isSmallInteger(fd) && __isSmallInteger(hz)) {
__rate = __rateWant = __intVal(hz);
if (ioctl(f, SOUND_PCM_WRITE_RATE, &__rate) >= 0) {
if (__rate != __rateWant) {
@@ -961,6 +1043,7 @@
S16_LE signed 16bit little endian samples
S16_BE signed 16bit big endian samples
MPEG audio mpeg encoded
+ PCM pcm
"
|fd audioFormatMask
@@ -969,7 +1052,7 @@
supports_IMA_ADPCM supports_U8
supports_S16_LE supports_S16_BE
supports_S8 supports_U16_LE
- supports_U16_BE supports_MPEG|
+ supports_U16_BE supports_MPEG supports_PCM|
fd := self fileDescriptor.
fd isNil ifTrue:[
@@ -981,23 +1064,43 @@
int __audioFormatMask = 0;
#if defined(DEV_AUDIO)
-# if defined(LINUX)
+ supports_MU_LAW = true;
+
+# if defined(SNDCTL_DSP_GETFMTS)
if (ioctl(f, SNDCTL_DSP_GETFMTS, &__audioFormatMask) >= 0) {
audioFormatMask = __MKSMALLINT(__audioFormatMask);
+# ifdef AFMT_MU_LAW
supports_MU_LAW = (__audioFormatMask & AFMT_MU_LAW) ? true : false;
+# endif
+# ifdef AFMT_A_LAW
supports_A_LAW = (__audioFormatMask & AFMT_A_LAW) ? true : false;
+# endif
+# ifdef AFMT_IMA_ADPCM
supports_IMA_ADPCM = (__audioFormatMask & AFMT_IMA_ADPCM) ? true : false;
+# endif
+# ifdef AFMT_U8
supports_U8 = (__audioFormatMask & AFMT_U8) ? true : false;
+# endif
+# ifdef AFMT_S16_LE
supports_S16_LE = (__audioFormatMask & AFMT_S16_LE) ? true : false;
+# endif
+# ifdef AFMT_S16_BE
supports_S16_BE = (__audioFormatMask & AFMT_S16_BE) ? true : false;
+# endif
+# ifdef AFMT_S8
supports_S8 = (__audioFormatMask & AFMT_S8) ? true : false;
+# endif
+# ifdef AFMT_U16_LE
supports_U16_LE = (__audioFormatMask & AFMT_U16_LE) ? true : false;
+# endif
+# ifdef AFMT_U16_BE
supports_U16_BE = (__audioFormatMask & AFMT_U16_BE) ? true : false;
+# endif
+# ifdef AFMT_MPEG
supports_MPEG = (__audioFormatMask & AFMT_MPEG) ? true : false;
+# endif
}
-# else
- supports_MU_LAW = true;
# endif
#endif /* DEV_AUDIO */
@@ -1007,6 +1110,10 @@
supports_U16_BE = true;
#endif
+#ifdef WIN32
+ supports_S16_LE = true;
+#endif
+
%}.
supportedFormats := IdentitySet new.
supports_MU_LAW ifTrue:[
@@ -1057,10 +1164,13 @@
!SoundStream methodsFor:'redefined'!
-close
+XXclose
OperatingSystem getOSType = 'irix' ifTrue:[
^ self closeFile
].
+ OperatingSystem getOSType = 'win32' ifTrue:[
+ ^ self closeFile
+ ].
super close
@@ -1075,9 +1185,32 @@
#ifdef IRIS_AUDIO
OBJ port;
- if ((port = __INST(filePointer)) != nil) {
- __INST(filePointer) = nil;
- ALcloseport(_ALportVal(port));
+ if ((port = __INST(alPort)) != nil) {
+ __INST(alPort) = nil;
+ ALcloseport(__ALportVal(port));
+ }
+ RETURN (self);
+#endif
+
+#ifdef WIN32
+ OBJ oDirectSound, oDSBuffer;
+ LPDIRECTSOUND t_pDirectSound;
+ LPDIRECTSOUNDBUFFER t_pDSBuffer;
+
+ if ((oDSBuffer = __INST(pDSBuffer)) != nil) {
+ __INST(pDSBuffer) = nil;
+ t_pDSBuffer = __DSBufferVal(oDSBuffer);
+ if (t_pDSBuffer) {
+ IDirectSoundBuffer_Stop(t_pDSBuffer);
+ IDirectSoundBuffer_Release(t_pDSBuffer);
+ }
+ }
+ if ((oDirectSound = __INST(pDirectSound)) != nil) {
+ __INST(pDirectSound) = nil;
+ t_pDirectSound = __DirectSoundVal(oDirectSound);
+ if (t_pDirectSound) {
+ IDirectSound_Release(t_pDirectSound);
+ }
}
RETURN (self);
#endif
@@ -1119,10 +1252,11 @@
fd := self fileDescriptor.
%{
#ifdef IRIS_AUDIO
+ OPJ port;
ALport p;
- if (__INST(filePointer) != nil) {
- p = _ALportVal(__INST(filePointer));
+ if ((port = __INST(alPort)) != nil) {
+ p = __ALportVal(port);
while (ALgetfilled(p) > 0) {
sginap(1);
}
@@ -1130,7 +1264,7 @@
RETURN(self);
#endif
-#if defined(DEV_AUDIO) && defined(LINUX)
+#if defined(DEV_AUDIO)
if (__isSmallInteger(fd)) {
int f = __intVal(fd);
/* ... */
@@ -1141,6 +1275,12 @@
^ self
!
+isOpen
+ alPort notNil ifTrue:[^ true].
+ pDirectSound notNil ifTrue:[^ true].
+ ^ filePointer notNil
+!
+
nextBytes:count into:anObject startingAt:start
"read the next count bytes into an object and return the number of
bytes read or nil on error.
@@ -1149,24 +1289,26 @@
%{
#ifdef IRIS_AUDIO
{
+ OBJ port;
ALport p;
- int cnt, offs;
+ int cnt, offs, nSamp;
int objSize;
char *cp;
- if (__INST(filePointer) != nil) {
+ if ((port = __INST(alPort)) != nil) {
if (__INST(mode) != _writeonly) {
if (__bothSmallInteger(count, start)) {
- cnt = _intVal(count);
- offs = _intVal(start) - 1;
- p = _ALportVal(__INST(filePointer));
+ cnt = __intVal(count);
+ offs = __intVal(start) - 1;
+ p = __ALportVal(port);
objSize = _Size(anObject) - OHDR_SIZE;
if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
cp = (char *)__InstPtr(anObject) + OHDR_SIZE + offs;
if (__INST(bitsPerSample) == __MKSMALLINT(16))
- ALreadsamps(p, cp, cnt / 2);
+ nSamp = cnt / 2;
else
- ALreadsamps(p, cp, cnt);
+ nSamp = cnt;
+ ALreadsamps(p, cp, nSamp);
RETURN ( __MKSMALLINT(cnt) );
}
}
@@ -1176,7 +1318,9 @@
#endif
%}.
OperatingSystem getOSType = 'irix' ifFalse:[
- ^ super nextPutBytes:count from:anObject startingAt:start
+ OperatingSystem getOSType = 'win32' ifFalse:[
+ ^ super nextPutBytes:count from:anObject startingAt:start
+ ].
].
filePointer isNil ifTrue:[^ self errorNotOpen].
(mode == #writeonly) ifTrue:[^ self errorWriteOnly].
@@ -1192,17 +1336,18 @@
%{
#ifdef IRIS_AUDIO
{
+ OBJ port;
ALport p;
- int cnt, offs;
+ int cnt, offs, nSamp;
int objSize;
char *cp;
- if (__INST(filePointer) != nil) {
+ if ((port = __INST(alPort)) != nil) {
if (__INST(mode) != @symbol(readonly)) {
if (__bothSmallInteger(count, start)) {
- cnt = _intVal(count);
- offs = _intVal(start) - 1;
- p = _ALportVal(__INST(filePointer));
+ cnt = __intVal(count);
+ offs = __intVal(start) - 1;
+ p = __ALportVal(port);
/*
* compute number of samples
@@ -1211,16 +1356,99 @@
if ( (offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs)) ) {
cp = (char *)__InstPtr(anObject) + OHDR_SIZE + offs;
if (__INST(bitsPerSample) == __MKSMALLINT(16))
- ALwritesamps(p, cp, cnt / 2);
+ nSamp = cnt / 2;
else
- ALwritesamps(p, cp, cnt);
+ nSamp = cnt;
+ ALwritesamps(p, cp, cnt);
RETURN ( count );
}
}
}
}
}
-#endif
+#endif /* SGI_AUDIO */
+
+#ifdef WIN32
+ {
+ HRESULT hr;
+ DWORD status;
+ LPVOID lpbuf1 = NULL;
+ LPVOID lpbuf2 = NULL;
+ DWORD dwsize1 = 0;
+ DWORD dwsize2 = 0;
+ DWORD playPos, safePos, endWrite;
+ DWORD millis;
+ OBJ oDirectSound, oDSBuffer;
+ LPDIRECTSOUND t_pDirectSound = (LPDIRECTSOUND)0;
+ LPDIRECTSOUNDBUFFER t_pDSBuffer = (LPDIRECTSOUNDBUFFER)0;
+ int t_cbBufOffset, t_cbBufSize;
+ short *buf;
+ int cnt, offs;
+
+ if ((oDSBuffer = __INST(pDSBuffer)) != nil) {
+ t_pDSBuffer = __DSBufferVal(oDSBuffer);
+ }
+ if ((oDirectSound = __INST(pDirectSound)) != nil) {
+ t_pDirectSound = __DirectSoundVal(oDirectSound);
+ }
+
+ if (!t_pDSBuffer || !t_pDirectSound) {
+ RETURN (0);
+ }
+ t_cbBufOffset = __intVal(__INST(cbBufOffset));
+ t_cbBufSize = __intVal(__INST(cbBufSize));
+
+ cnt = __intVal(count);
+ offs = __intVal(start) - 1;
+ buf = (short *)__InstPtr(anObject) + OHDR_SIZE + offs;
+
+ // Should be playing, right?
+ hr = IDirectSoundBuffer_GetStatus(t_pDSBuffer, &status );
+ if (!(status && DSBSTATUS_PLAYING)) {
+ printf("Buffer not playing!\n");
+ }
+
+ // Sleep until we have enough room in buffer.
+ hr = IDirectSoundBuffer_GetCurrentPosition(t_pDSBuffer, &playPos, &safePos );
+ if( hr != DS_OK ) {
+ RETURN (0);
+ }
+ if( playPos < t_cbBufOffset ) playPos += t_cbBufSize;
+
+ endWrite = t_cbBufOffset + RT_BUFFER_SIZE * sizeof(short);
+ while ( playPos < endWrite ) {
+ // Calculate number of milliseconds until we will have room, as
+ // time = distance * (milliseconds/second) / ((bytes/sample) * (samples/second)),
+ // rounded up.
+ millis = (DWORD) (1.0 + ((endWrite - playPos) * 1000.0) / ( sizeof(short) * __intVal(__INST(sampleRate))));
+
+ // Sleep for that long
+ Sleep( millis );
+
+ // Wake up, find out where we are now
+ hr = IDirectSoundBuffer_GetCurrentPosition(t_pDSBuffer, &playPos, &safePos );
+ if( hr != DS_OK ) {
+ RETURN (0);
+ }
+ if( playPos < t_cbBufOffset ) playPos += t_cbBufSize; // unwrap offset
+ }
+
+ // Lock free space in the DS
+ hr = IDirectSoundBuffer_Lock(t_pDSBuffer, t_cbBufOffset, RT_BUFFER_SIZE * sizeof(short), &lpbuf1, &dwsize1, &lpbuf2, &dwsize2, 0);
+ if (hr == DS_OK) {
+ // Copy the buffer into the DS
+ CopyMemory(lpbuf1, buf, dwsize1);
+ if(NULL != lpbuf2) CopyMemory(lpbuf2, buf+dwsize1, dwsize2);
+
+ // Update our buffer offset and unlock sound buffer
+ t_cbBufOffset = (t_cbBufOffset + dwsize1 + dwsize2) % t_cbBufSize;
+ IDirectSoundBuffer_Unlock(t_pDSBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);
+ }
+ __INST(cbBufOffset) = __MKSMALLINT(t_cbBufOffset);
+
+ RETURN (0);
+ }
+#endif /* WIN32 */
#if defined(DEV_AUDIO)
/*
@@ -1243,18 +1471,18 @@
f = __FILEVal(fp);
if (__INST(mode) != @symbol(readonly)) {
if (__bothSmallInteger(count, start)) {
- cnt = _intVal(count);
- offs = _intVal(start) - 1;
+ cnt = __intVal(count);
+ offs = __intVal(start) - 1;
objSize = _Size(anObject) - OHDR_SIZE;
if ( (offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs)) ) {
do {
- cp = (char *)__InstPtr(anObject) + OHDR_SIZE + offs;
+ cp = (char *)__InstPtr(anObject) + OHDR_SIZE + offs;
n = cnt;
if (n > 4096) n = 4096;
# ifdef LINUX
- sigsetmask(~0);
+ sigsetmask(~0);
# endif
if (__INST(buffered) == true) {
n = fwrite(cp, 1, n, f);
@@ -1263,7 +1491,7 @@
n = write(fd, cp, n);
}
# ifdef LINUX
- sigsetmask(0);
+ sigsetmask(0);
# endif
__BEGIN_INTERRUPTABLE__
__END_INTERRUPTABLE__
@@ -1283,23 +1511,35 @@
^ super nextPutBytes:count from:anObject startingAt:start
!
+openForReading
+ |rslt|
+
+ mode := #readonly.
+ didWrite := false.
+ (rslt := self openWithMode:ReadMode) notNil ifTrue:[
+ Lobby register:self
+ ].
+ ^ rslt
+!
+
openForWriting
"open the file writeonly.
If the file does not exist its an error, return nil;
otherwise return the receiver."
+ |rslt|
+
mode := #writeonly.
didWrite := true.
- ^ self openWithMode:WriteMode
+ (rslt := self openWithMode:WriteMode) notNil ifTrue:[
+ Lobby register:self
+ ].
+ ^ rslt
"Created: / 15.12.1997 / 13:13:56 / cg"
!
openWithMode:aMode
- ((aMode = 'r') or:[aMode = 'w']) ifFalse:[
- self error:'invalid mode'.
- ^ nil
- ].
%{
#ifdef IRIS_AUDIO
{
@@ -1322,14 +1562,16 @@
ALsetwidth(config, AL_SAMPLE_8);
if (__isSmallInteger(__INST(sampleRate)))
- params[3] = params[5] = _intVal(__INST(sampleRate));
+ params[3] = params[5] = __intVal(__INST(sampleRate));
ALsetparams(AL_DEFAULT_DEVICE, params, 6);
p = ALopenport("smallchat", (char *)_stringVal(aMode), config);
if (p) {
- __INST(filePointer) = __MKEXTERNALADDRESS(p);
+ OBJ t;
+
+ __INST(alPort) = t = __MKEXTERNALADDRESS(p); __STORE(self, t);
} else {
- __INST(filePointer) = nil;
+ __INST(alPort) = nil;
RETURN (nil);
}
__INST(binary) = true;
@@ -1368,7 +1610,125 @@
ALfreeconfig(config);
RETURN (self);
}
+#endif /* SGI_AUDIO */
+
+#ifdef WIN32
+ {
+ HRESULT result;
+ LPDIRECTSOUND t_pDirectSound;
+ LPDIRECTSOUNDBUFFER t_pDSBuffer, t_pDSPrimeBuffer;
+ WAVEFORMATEX wfFormat;
+ DSBUFFERDESC dsbdDesc, primarydsbDesc;
+ BYTE *pDSBuffData;
+ int t_cbBufSize;
+ int dwDataLen;
+
+ /* Create the DS object */
+ if ((result = DirectSoundCreate(NULL, &t_pDirectSound, NULL)) != DS_OK) {
+ fprintf(stderr,"SoundStream: Cannot open default sound device!!\n");
+ RETURN (nil);
+ }
+
+ /* Define the wave format structure */
+ wfFormat.wFormatTag = WAVE_FORMAT_PCM;
+ wfFormat.nChannels = __intVal(__INST(numberOfChannels));
+ wfFormat.nSamplesPerSec = __intVal(__INST(sampleRate));
+ wfFormat.wBitsPerSample = __intVal(__INST(bitsPerSample));
+ wfFormat.nBlockAlign = wfFormat.nChannels * wfFormat.wBitsPerSample / 8;
+ wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;
+ wfFormat.cbSize = 0;
+#if 0
+ /* Setup the primary DS buffer description */
+ ZeroMemory(&primarydsbDesc, sizeof(DSBUFFERDESC));
+ primarydsbDesc.dwSize = sizeof(DSBUFFERDESC);
+ primarydsbDesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
+ primarydsbDesc.dwBufferBytes = 0;
+ primarydsbDesc.lpwfxFormat = NULL;
+
+ /* Create the primary DS buffer */
+ if ((result = IDirectSound_CreateSoundBuffer(t_pDirectSound, &primarydsbDesc,
+ &t_pDSPrimeBuffer, NULL)) != DS_OK) {
+ fprintf(stderr,"SoundStream: Cannot get the primary DS buffer address!\n");
+ IDirectSound_Release(t_pDirectSound);
+ RETURN (nil);
+ }
+
+ /* Set the primary DS buffer sound format. We have to do this because
+ the default primary buffer is 8-bit, 22kHz! */
+ if ((result = IDirectSoundBuffer_SetFormat(t_pDSPrimeBuffer, &wfFormat)) != DS_OK) {
+ fprintf(stderr,"SoundStream: Cannot set the primary DS buffer to proper sound format (%x) (%d)!\n", result, result);
+ IDirectSoundBuffer_Stop(t_pDSPrimeBuffer);
+ IDirectSoundBuffer_Release(t_pDSPrimeBuffer);
+ IDirectSound_Release(t_pDirectSound);
+ RETURN (nil);
+ }
#endif
+
+ /* Setup the secondary DS buffer description */
+ t_cbBufSize = RT_BUFFER_SIZE * sizeof(short) * NBUFS;
+ __INST(cbBufSize) = __MKSMALLINT(t_cbBufSize);
+
+ ZeroMemory(&dsbdDesc, sizeof(DSBUFFERDESC));
+ dsbdDesc.dwSize = sizeof(DSBUFFERDESC);
+ dsbdDesc.dwFlags = DSBCAPS_GLOBALFOCUS;
+ dsbdDesc.dwBufferBytes = t_cbBufSize;
+ dsbdDesc.lpwfxFormat = &wfFormat;
+
+ /* Create the secondary DS buffer */
+ if ((result = IDirectSound_CreateSoundBuffer(t_pDirectSound, &dsbdDesc, &t_pDSBuffer, NULL)) != DS_OK) {
+ fprintf(stderr,"SoundStream: couldn't create sound buffer!\n");
+ IDirectSoundBuffer_Stop(t_pDSPrimeBuffer);
+ IDirectSoundBuffer_Release(t_pDSPrimeBuffer);
+ IDirectSound_Release(t_pDirectSound);
+ RETURN (nil);
+ }
+
+ /* Lock the DS buffer */
+ if ((result = IDirectSoundBuffer_Lock(t_pDSBuffer, 0, t_cbBufSize, (LPLPVOID)&pDSBuffData,
+ &dwDataLen, NULL, NULL, 0)) != DS_OK) {
+ fprintf(stderr,"SoundStream: couldn't lock sound buffer!\n");
+ IDirectSoundBuffer_Stop(t_pDSBuffer);
+ IDirectSoundBuffer_Stop(t_pDSPrimeBuffer);
+ IDirectSoundBuffer_Release(t_pDSPrimeBuffer);
+ IDirectSound_Release(t_pDirectSound);
+ RETURN (nil);
+ }
+
+ /* Zero the DS buffer */
+ ZeroMemory(pDSBuffData, dwDataLen);
+
+ /* Unlock the DS buffer */
+ if ((result = IDirectSoundBuffer_Unlock(t_pDSBuffer, pDSBuffData, dwDataLen, NULL, 0)) != DS_OK) {
+ fprintf(stderr,"SoundStream: couldn't unlock sound buffer!\n");
+ IDirectSoundBuffer_Stop(t_pDSBuffer);
+ IDirectSoundBuffer_Stop(t_pDSPrimeBuffer);
+ IDirectSoundBuffer_Release(t_pDSPrimeBuffer);
+ IDirectSound_Release(t_pDirectSound);
+ RETURN (nil);
+ }
+
+ __INST(cbBufOffset) = __MKSMALLINT(0); // reset last write position to start of buffer
+
+ /* Start the buffer playback */
+ if ((result = IDirectSoundBuffer_Play(t_pDSBuffer, 0, 0, DSBPLAY_LOOPING ) != DS_OK)) {
+ fprintf(stderr,"SoundStream: couldn't play sound buffer!\n");
+ IDirectSoundBuffer_Stop(t_pDSBuffer);
+ IDirectSoundBuffer_Stop(t_pDSPrimeBuffer);
+ IDirectSoundBuffer_Release(t_pDSPrimeBuffer);
+ IDirectSound_Release(t_pDirectSound);
+ RETURN (nil);
+ }
+
+ {
+ OBJ t;
+
+ __INST(pDSBuffer) = t = __MKEXTERNALADDRESS(t_pDSBuffer); __STORE(self, t);
+ __INST(pDirectSound) = t = __MKEXTERNALADDRESS(t_pDirectSound); __STORE(self, t);
+ }
+ RETURN (self);
+ }
+#endif /* WIN32 */
+
%}.
"its a regular file open (i.e. /dev/audio) "
^ super openWithMode:aMode
@@ -1405,15 +1765,15 @@
scale := freq * 2 * (Float pi).
1 to:numSamples do:[:i |
- val := (scale * i / numSamples) sin.
- val := (val * 16r7FFF) rounded bitAnd:16rFFFF.
- buffer at:i put:val
+ val := (scale * i / numSamples) sin.
+ val := (val * 16r7FFF) rounded bitAnd:16rFFFF.
+ buffer at:i put:val
].
oldFormat := audioFormat.
self setAudioFormat:#S16.
1 to:3 do:[:s |
- self nextPutBytes:(numSamples*2) from:buffer startingAt:1
+ self nextPutBytes:(numSamples*2) from:buffer startingAt:1
].
self setAudioFormat:oldFormat.
@@ -1443,15 +1803,15 @@
scale := freq * 2 * (Float pi).
1 to:numSamples do:[:i |
- val := (scale * i / numSamples) sin.
- val := (val * 127 + 128) rounded.
- buffer at:i put:val
+ val := (scale * i / numSamples) sin.
+ val := (val * 127 + 128) rounded.
+ buffer at:i put:val
].
oldFormat := audioFormat.
self setAudioFormat:#U8.
1 to:3 do:[:s |
- self nextPutBytes:numSamples from:buffer startingAt:1
+ self nextPutBytes:numSamples from:buffer startingAt:1
].
self setAudioFormat:oldFormat.
@@ -1494,15 +1854,15 @@
scale := freq * 2 * (Float pi).
1 to:numSamples do:[:i |
- val := (scale * i / numSamples) sin.
- val := (val * 16r7FFF) rounded.
- buffer at:i put:(self class linear16ToUlaw:val)
+ val := (scale * i / numSamples) sin.
+ val := (val * 16r7FFF) rounded.
+ buffer at:i put:(self class linear16ToUlaw:val)
].
oldFormat := audioFormat.
self setAudioFormat:#MU_LAW.
1 to:3 do:[:s |
- self nextPutBytes:numSamples from:buffer startingAt:1
+ self nextPutBytes:numSamples from:buffer startingAt:1
].
self setAudioFormat:oldFormat.
@@ -1521,5 +1881,5 @@
!SoundStream class methodsFor:'documentation'!
version
-^ '$Header: /cvs/stx/stx/libbasic2/SoundStream.st,v 1.33 1998-02-08 00:45:12 cg Exp $'! !
+^ '$Header: /cvs/stx/stx/libbasic2/SoundStream.st,v 1.34 1998-12-21 11:43:58 cg Exp $'! !
SoundStream initialize!