--- a/SoundStream.st Mon Nov 20 19:03:51 2000 +0100
+++ b/SoundStream.st Mon Nov 20 22:12:19 2000 +0100
@@ -1081,12 +1081,6 @@
]
].
%{
- int f = __intVal(fd);
- int __fmt = 0, __fmtWant;
- union {
- unsigned short us;
- unsigned char ub[2];
- } u;
OBJ sym = aSymbol;
if (__INST(audioFormat) == sym) {
@@ -1095,6 +1089,13 @@
#if defined(DEV_AUDIO)
if (__isSmallInteger(fd)) {
+ int f = __intVal(fd);
+ int __fmt = 0, __fmtWant;
+ union {
+ unsigned short us;
+ unsigned char ub[2];
+ } u;
+
if (__isSymbol(sym)) {
if (sym == @symbol(U16)) {
u.us = 0x1234;
@@ -1227,19 +1228,22 @@
]
].
%{
- int f = __intVal(fd);
- int __nCh = 0;
#if defined(DEV_AUDIO)
if (__isSmallInteger(fd) && __isSmallInteger(nChannels)) {
- __nCh = __intVal(nChannels);
+ int f = __intVal(fd);
+ int __nCh = __intVal(nChannels);
# if defined(SNDCTL_DSP_STEREO)
if ((__nCh == 1) || (__nCh == 2)) {
int __stereo = (__nCh == 2) ? 1 : 0;
if (ioctl(f, SNDCTL_DSP_STEREO, &__stereo) >= 0) {
- __INST(numberOfChannels) = nChannels;
+ if (__stereo == 0) {
+ __INST(numberOfChannels) = __MKSMALLINT(1);
+ } else {
+ __INST(numberOfChannels) = __MKSMALLINT(2);
+ }
RETURN (self);
}
}
@@ -1324,16 +1328,13 @@
]
].
%{
- int f = __intVal(fd);
- int __rate = 0;
- int __rateWant;
-
#if defined(DEV_AUDIO)
if (__isSmallInteger(fd) && __isSmallInteger(hz)) {
- __rate = __intVal(hz);
+ int f = __intVal(fd);
+ int __rate = __intVal(hz);
+ int __rateWant = __rate;
# if defined(SNDCTL_DSP_SPEED)
- __rateWant = __rate;
if (ioctl(f, SNDCTL_DSP_SPEED, &__rate) >= 0) {
if (__rate != __rateWant) {
fprintf(stderr, "SoundStream [warning]: actual rate is %d\n", __rate);
@@ -1344,7 +1345,6 @@
}
# else
# if defined(SOUND_PCM_WRITE_RATE)
- __rateWant = __rate;
if (ioctl(f, SOUND_PCM_WRITE_RATE, &__rate) >= 0) {
if (__rate != __rateWant) {
fprintf(stderr, "SoundStream [warning]: actual rate is %d\n", __rate);
@@ -1748,27 +1748,27 @@
char *cp;
if ((port = __INST(alPort)) != nil) {
- if (__INST(mode) != @symbol(readonly)) {
- if (__bothSmallInteger(count, start)) {
- cnt = __intVal(count);
- offs = __intVal(start) - 1;
- p = __ALportVal(port);
+ if (__INST(mode) != @symbol(readonly)) {
+ if (__bothSmallInteger(count, start)) {
+ cnt = __intVal(count);
+ offs = __intVal(start) - 1;
+ p = __ALportVal(port);
- /*
- * compute number of samples
- */
- 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))
- nSamp = cnt / 2;
- else
- nSamp = cnt;
- ALwritesamps(p, cp, cnt);
- RETURN ( count );
- }
- }
- }
+ /*
+ * compute number of samples
+ */
+ 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))
+ nSamp = cnt / 2;
+ else
+ nSamp = cnt;
+ ALwritesamps(p, cp, cnt);
+ RETURN ( count );
+ }
+ }
+ }
}
}
#endif /* SGI_AUDIO */
@@ -1792,15 +1792,15 @@
int cnt, offs;
if ((oDSBuffer = __INST(pDSBuffer)) != nil) {
- t_pDSBuffer = __DSBufferVal(oDSBuffer);
+ t_pDSBuffer = __DSBufferVal(oDSBuffer);
}
if ((oDirectSound = __INST(pDirectSound)) != nil) {
- t_pDirectSound = __DirectSoundVal(oDirectSound);
+ t_pDirectSound = __DirectSoundVal(oDirectSound);
}
if (!t_pDSBuffer || !t_pDirectSound) {
- fprintf(stderr, "SoundStream not open!\n");
- RETURN (0);
+ fprintf(stderr, "SoundStream not open!\n");
+ RETURN (0);
}
t_cbBufOffset = __intVal(__INST(bufferOffset));
t_cbBufSize = __intVal(__INST(bufferSize));
@@ -1812,47 +1812,47 @@
// Should be playing, right?
hr = IDirectSoundBuffer_GetStatus(t_pDSBuffer, &status );
if (!(status && DSBSTATUS_PLAYING)) {
- fprintf(stderr, "Buffer not playing!\n");
- RETURN (0);
+ fprintf(stderr, "Buffer not playing!\n");
+ RETURN (0);
}
// Sleep until we have enough room in buffer.
hr = IDirectSoundBuffer_GetCurrentPosition(t_pDSBuffer, &playPos, &safePos );
if( hr != DS_OK ) {
- fprintf(stderr, "Cannot get position!\n");
- RETURN (0);
+ fprintf(stderr, "Cannot get position!\n");
+ RETURN (0);
}
if( playPos < t_cbBufOffset ) playPos += t_cbBufSize;
endWrite = t_cbBufOffset + (cnt * 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))));
+ // 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 );
+ // 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 ) {
- fprintf(stderr, "Cannot get position!\n");
- RETURN (0);
- }
- if( playPos < t_cbBufOffset ) playPos += t_cbBufSize; // unwrap offset
+ // Wake up, find out where we are now
+ hr = IDirectSoundBuffer_GetCurrentPosition(t_pDSBuffer, &playPos, &safePos );
+ if( hr != DS_OK ) {
+ fprintf(stderr, "Cannot get position!\n");
+ RETURN (0);
+ }
+ if( playPos < t_cbBufOffset ) playPos += t_cbBufSize; // unwrap offset
}
// Lock free space in the DS
hr = IDirectSoundBuffer_Lock(t_pDSBuffer, t_cbBufOffset, cnt * 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);
+ // 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);
+ // 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(buffferOffset) = __MKSMALLINT(t_cbBufOffset);
@@ -1869,7 +1869,7 @@
OBJ oWaveHandle;
if ((oWaveHandle = __INST(waveHandle)) == nil) {
- RETURN(0);
+ RETURN(0);
}
t_waveHandle = __WaveHandleVal(oWaveHandle);
@@ -1878,50 +1878,50 @@
buf = (short *)__InstPtr(anObject) + OHDR_SIZE + offs;
while (dataLen > 0) {
- if (free_list == NULL && total_buffers < MAXBUF) {
- /* Expand available buffer space */
- bp = (struct buf *)malloc(sizeof(struct buf));
- total_buffers++;
- } else {
- if (free_list == NULL) {
- /* We must wait for a free buffer */
- while (free_list == NULL) {
- WaitForSingleObject(free_buffer_event, INFINITE);
- }
- }
- EnterCriticalSection(&free_list_lock);
- bp = free_list;
- free_list = free_list->next;
- --free_buffers;
- LeaveCriticalSection(&free_list_lock);
- r = waveOutUnprepareHeader(t_waveHandle, &bp->hdr, sizeof(WAVEHDR));
- if (r != 0) {
- printf("waveOutUnprepareHeader\n");
- RETURN(self);
- }
- }
- len = min(dataLen, DATALEN);
- bp->hdr.lpData = (char *)bp->data;
- bp->hdr.dwBufferLength = len;
- bp->hdr.dwBytesRecorded = len;
- bp->hdr.dwUser = (DWORD)bp;
- bp->hdr.dwFlags = 0;
- bp->hdr.dwLoops = 0;
- r = waveOutPrepareHeader(t_waveHandle, &bp->hdr, sizeof(WAVEHDR));
- if (r != 0) {
- printf("waveOutPrepareHeader\n");
- RETURN(self);
- }
- for (i = 0; i < len; i++) {
- bp->data[i] = buf[i];
- }
- r = waveOutWrite(t_waveHandle, &bp->hdr, sizeof(WAVEHDR));
- if (r != 0) {
- printf("waveOutWrite\n");
- RETURN(self);
- }
- buf += len;
- dataLen -= len;
+ if (free_list == NULL && total_buffers < MAXBUF) {
+ /* Expand available buffer space */
+ bp = (struct buf *)malloc(sizeof(struct buf));
+ total_buffers++;
+ } else {
+ if (free_list == NULL) {
+ /* We must wait for a free buffer */
+ while (free_list == NULL) {
+ WaitForSingleObject(free_buffer_event, INFINITE);
+ }
+ }
+ EnterCriticalSection(&free_list_lock);
+ bp = free_list;
+ free_list = free_list->next;
+ --free_buffers;
+ LeaveCriticalSection(&free_list_lock);
+ r = waveOutUnprepareHeader(t_waveHandle, &bp->hdr, sizeof(WAVEHDR));
+ if (r != 0) {
+ printf("waveOutUnprepareHeader\n");
+ RETURN(self);
+ }
+ }
+ len = min(dataLen, DATALEN);
+ bp->hdr.lpData = (char *)bp->data;
+ bp->hdr.dwBufferLength = len;
+ bp->hdr.dwBytesRecorded = len;
+ bp->hdr.dwUser = (DWORD)bp;
+ bp->hdr.dwFlags = 0;
+ bp->hdr.dwLoops = 0;
+ r = waveOutPrepareHeader(t_waveHandle, &bp->hdr, sizeof(WAVEHDR));
+ if (r != 0) {
+ printf("waveOutPrepareHeader\n");
+ RETURN(self);
+ }
+ for (i = 0; i < len; i++) {
+ bp->data[i] = buf[i];
+ }
+ r = waveOutWrite(t_waveHandle, &bp->hdr, sizeof(WAVEHDR));
+ if (r != 0) {
+ printf("waveOutWrite\n");
+ RETURN(self);
+ }
+ buf += len;
+ dataLen -= len;
}
RETURN (count);
}
@@ -1929,6 +1929,7 @@
#endif /* WIN32 */
#if defined(DEV_AUDIO)
+#include <errno.h>
/*
* redefine to work around a bug in the linux sound driver;
* if a write is interrupted (EINTR), it is not defined, how many
@@ -1946,42 +1947,47 @@
int fd;
if ((fp = __INST(filePointer)) != nil) {
- f = __FILEVal(fp);
- if (__INST(mode) != @symbol(readonly)) {
- if (__bothSmallInteger(count, start)) {
- cnt = __intVal(count);
- offs = __intVal(start) - 1;
+ f = __FILEVal(fp);
+ if (__INST(mode) != @symbol(readonly)) {
+ if (__bothSmallInteger(count, start)) {
+ 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;
+ objSize = _Size(anObject) - OHDR_SIZE;
+ if ( (offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs)) ) {
+ do {
+ cp = (char *)__InstPtr(anObject) + OHDR_SIZE + offs;
- n = cnt;
- if (n > 4096) n = 4096;
+ n = cnt;
+ if (n > 4096) n = 4096;
# ifdef LINUX
- sigsetmask(~0);
+ sigsetmask(~0);
# endif
- if (__INST(buffered) == true) {
- n = fwrite(cp, 1, n, f);
- } else {
- fd = fileno(f);
- n = write(fd, cp, n);
- }
+ if (__INST(buffered) == true) {
+ n = fwrite(cp, 1, n, f);
+ } else {
+ fd = fileno(f);
+ n = write(fd, cp, n);
+ }
# ifdef LINUX
- sigsetmask(0);
+ sigsetmask(0);
# endif
- __BEGIN_INTERRUPTABLE__
- __END_INTERRUPTABLE__
- if (n > 0) {
- offs += n;
- cnt -= n;
- }
- } while (cnt);
- }
- RETURN (count);
- }
- }
+ __BEGIN_INTERRUPTABLE__
+ __END_INTERRUPTABLE__
+ if (n > 0) {
+ offs += n;
+ cnt -= n;
+ } else {
+ if (n < 0) {
+ fprintf(stderr, "write error: %d\n", __threadErrno);
+ RETURN (count);
+ }
+ }
+ } while (cnt);
+ }
+ RETURN (count);
+ }
+ }
}
#endif
@@ -2292,7 +2298,7 @@
do {
__BEGIN_INTERRUPTABLE__
__threadErrno = 0;
- __fd = open((char *) __stringVal(__INST(pathName)), __mode|O_NDELAY);
+ __fd = open((char *) __stringVal(__INST(pathName)), __mode /* |O_NDELAY */);
__END_INTERRUPTABLE__
} while ((__fd < 0) && (__threadErrno == EINTR));
@@ -2328,27 +2334,43 @@
"output some tone for some time
in S16 audioFormat - a test method"
- |buffer numSamples val scale|
+ |buffer numSamples val scale isUnsigned|
+
+ (audioFormat startsWith:#U16) ifFalse:[
+ (audioFormat startsWith:#S16) ifFalse:[
+ self error:'must be in 16bit mode' mayProceed:true.
+ ^ self
+ ]
+ ].
numSamples := (self sampleRate * seconds) truncated.
buffer := WordArray new:numSamples.
"fill it with a sine wave"
+ isUnsigned := audioFormat startsWith:#U16.
+
scale := freq * 2 * (Float pi).
1 to:numSamples do:[:i |
- val := (scale * i / self sampleRate) sin.
- val := (val * 16r7FFF) rounded bitAnd:16rFFFF.
- audioFormat == #U16 ifTrue:[
- val := val + 32768
- ].
- buffer at:i put:val
+ val := (scale * i / self sampleRate) sin.
+ val := (val * 16r7FFF) rounded bitAnd:16rFFFF.
+ isUnsigned ifTrue:[
+ val := val + 32768
+ ].
+ buffer at:i put:val
].
self nextPutBytes:(numSamples*2) from:buffer startingAt:1
"
- SoundStream writing playSine16:440 forSeconds:3; close
+ SoundStream writing setAudioFormat:#S16; playSine16:440 forSeconds:2; close
+ SoundStream writing setAudioFormat:#S16; playSine16:880 forSeconds:2; close
+ SoundStream writing setAudioFormat:#S16; playSine16:1760 forSeconds:2; close
+ SoundStream writing setAudioFormat:#S16; playSine16:3520 forSeconds:2; close
+ SoundStream writing tuneTone:440; close
+
+ SoundStream writing setAudioFormat:#U16; playSine16:880 forSeconds:2; close
+ SoundStream writing setAudioFormat:#U16_LE; playSine16:880 forSeconds:2; close
"
"Modified: / 31.1.1999 / 12:12:41 / cg"
@@ -2381,6 +2403,8 @@
SoundStream writing setSampleRate:10000; tuneTone; close
SoundStream writing setSampleRate:20000; tuneTone; close
SoundStream writing setSampleRate:40000; tuneTone; close
+
+ SoundStream writing setSampleRate:40000; dumpSettings; close
SoundStream writing setSampleRate:20000; dumpSettings; close
"
@@ -2392,6 +2416,13 @@
|buffer numSamples val scale oldFormat|
+ (audioFormat startsWith:#U16) ifFalse:[
+ (audioFormat startsWith:#S16) ifFalse:[
+ self error:'must be in 16bit mode' mayProceed:true.
+ ^ self
+ ]
+ ].
+
"allocate memory for 1sec playing time"
numSamples := self sampleRate.
buffer := WordArray new:numSamples.
@@ -2400,18 +2431,18 @@
scale := freq * 2 * (Float pi).
1 to:numSamples do:[:i |
- val := (scale * i / numSamples) sin.
- val := (val * 16r7FFF) rounded bitAnd:16rFFFF.
- audioFormat == #U16 ifTrue:[
- val := val + 32768
- ].
- buffer at:i put:val
+ val := (scale * i / numSamples) sin.
+ val := (val * 16r7FFF) rounded bitAnd:16rFFFF.
+ audioFormat == #U16 ifTrue:[
+ val := val + 32768
+ ].
+ 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.
@@ -2433,6 +2464,13 @@
|buffer numSamples val scale oldFormat|
+ (audioFormat == #U8) ifFalse:[
+ (audioFormat == #S8) ifFalse:[
+ self error:'must be in 8bit mode' mayProceed:true.
+ ^ self
+ ]
+ ].
+
"allocate memory for 1sec playing time"
numSamples := self sampleRate.
buffer := ByteArray new:numSamples.
@@ -2441,15 +2479,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.
@@ -2481,24 +2519,41 @@
!
tuneTone:freq
- audioFormat == #S16 ifTrue:[
- ^ self tuneTone16:freq
- ].
- audioFormat == #U16 ifTrue:[
- ^ self tuneTone16:freq
+ ((audioFormat startsWith:#S16)
+ or:[audioFormat startsWith:#U16]) ifTrue:[
+ ^ self tuneTone16:freq
].
audioFormat == #MU_LAW ifTrue:[
- ^ self tuneToneMU:freq
+ ^ self tuneToneMU:freq
].
self tuneTone8:freq
"
SoundStream writing tuneTone:880; close
+ SoundStream writing setSampleRate:4000; tuneTone:440; close
SoundStream writing setSampleRate:4000; tuneTone:880; close
+ SoundStream writing setSampleRate:8000; tuneTone:440; close
SoundStream writing setSampleRate:8000; tuneTone:880; close
+ SoundStream writing setSampleRate:10000; tuneTone:440; close
SoundStream writing setSampleRate:10000; tuneTone:880; close
+
+ SoundStream writing setSampleRate:20000; tuneTone:440; close
SoundStream writing setSampleRate:20000; tuneTone:880; close
+
+ SoundStream writing setSampleRate:40000; tuneTone:440; close
SoundStream writing setSampleRate:40000; tuneTone:880; close
+ SoundStream writing setSampleRate:40000; tuneTone:1760; close
+ SoundStream writing setSampleRate:40000; tuneTone:3520; close
+ SoundStream writing setSampleRate:40000; tuneTone:7020; close
+ SoundStream writing setSampleRate:40000; tuneTone:14040; close
+
+ SoundStream writing setSampleRate:44100; tuneTone:440; close
+ SoundStream writing setSampleRate:44100; tuneTone:880; close
+ SoundStream writing setSampleRate:44100; tuneTone:1760; close
+ SoundStream writing setSampleRate:44100; tuneTone:3520; close
+ SoundStream writing setSampleRate:44100; tuneTone:7020; close
+ SoundStream writing setSampleRate:44100; tuneTone:14040; close
+
SoundStream writing setSampleRate:20000; dumpSettings; close
"
@@ -2545,6 +2600,6 @@
!SoundStream class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic2/SoundStream.st,v 1.52 2000-11-20 18:03:51 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic2/SoundStream.st,v 1.53 2000-11-20 21:12:19 cg Exp $'
! !
SoundStream initialize!