*** empty log message ***
authorClaus Gittinger <cg@exept.de>
Fri, 03 Jan 2020 22:18:23 +0100
changeset 5409 36e736c349b6
parent 5408 909d03dd2329
child 5410 24114a427d3d
*** empty log message ***
SoundStream.st
--- a/SoundStream.st	Fri Jan 03 22:10:34 2020 +0100
+++ b/SoundStream.st	Fri Jan 03 22:18:23 2020 +0100
@@ -15,7 +15,8 @@
 
 FileStream subclass:#SoundStream
 	instanceVariableNames:'sampleRate numberOfChannels bitsPerSample audioFormat handle1
-		handle2 bufferOffset bufferSize lastErrorString fragmentSize'
+		handle2 bufferOffset bufferSize lastErrorString fragmentSize
+		openMode openAttributes'
 	classVariableNames:'IsInitialized UnsupportedOperationSignal ConcreteClass'
 	poolDictionaries:''
 	category:'Streams-External'
@@ -1512,7 +1513,7 @@
     |buffer numSamples val scale restSamples numChannels|
 
     (audioFormat == #F32) ifFalse:[
-        self error:'must be in float mode' mayProceed:true.
+	self error:'must be in float mode' mayProceed:true.
     ].
 
     numSamples := self sampleRate.
@@ -1523,24 +1524,24 @@
 
     scale := freq * 2 * (Float pi).
     numChannels == 2 ifTrue:[
-        1 to:numSamples do:[:i |
-            val := (scale * i / self sampleRate) sin.
-            buffer at:(i-1)*2 put:val.
-            buffer at:(i-1)*2+1 put:0.
-        ].
+	1 to:numSamples do:[:i |
+	    val := (scale * i / self sampleRate) sin.
+	    buffer at:(i-1)*2 put:val.
+	    buffer at:(i-1)*2+1 put:0.
+	].
     ] ifFalse:[
-        1 to:numSamples do:[:i |
-            val := (scale * i / self sampleRate) sin.
-            buffer at:i put:val
-        ].
+	1 to:numSamples do:[:i |
+	    val := (scale * i / self sampleRate) sin.
+	    buffer at:i put:val
+	].
     ].
 
     1 to:nSeconds truncated do:[:s |
-        self nextPutBytes:(numSamples*4) from:buffer startingAt:1
+	self nextPutBytes:(numSamples*4) from:buffer startingAt:1
     ].
     restSamples := ((nSeconds - nSeconds truncated) * numSamples) truncated.
     restSamples > 0 ifTrue:[
-        self nextPutBytes:(restSamples*4) from:buffer startingAt:1
+	self nextPutBytes:(restSamples*4) from:buffer startingAt:1
     ].
 
     "
@@ -1594,10 +1595,10 @@
     |buffer numSamples val scale restSamples|
 
     (audioFormat startsWith:#U16) ifFalse:[
-        (audioFormat startsWith:#S16) ifFalse:[
-            self error:'must be in 16bit mode' mayProceed:true.
-            ^ self
-        ]
+	(audioFormat startsWith:#S16) ifFalse:[
+	    self error:'must be in 16bit mode' mayProceed:true.
+	    ^ self
+	]
     ].
 
     "allocate memory for 1 sec playing time"
@@ -1608,20 +1609,20 @@
 
     scale := freq * 2 * (Float pi).
     1 to:numSamples do:[:i |
-        val := (scale * i / numSamples) sin.
-        val := (val * 16r7FFF) rounded.
-        audioFormat == #U16 ifTrue:[
-            val := val + 16r8000
-        ].
-        buffer at:i put:(val bitAnd:16rFFFF)
+	val := (scale * i / numSamples) sin.
+	val := (val * 16r7FFF) rounded.
+	audioFormat == #U16 ifTrue:[
+	    val := val + 16r8000
+	].
+	buffer at:i put:(val bitAnd:16rFFFF)
     ].
 
     1 to:nSeconds truncated do:[:s |
-        self nextPutBytes:(numSamples*2) from:buffer startingAt:1
+	self nextPutBytes:(numSamples*2) from:buffer startingAt:1
     ].
     restSamples := ((nSeconds - nSeconds truncated) * numSamples) truncated.
     restSamples > 0 ifTrue:[
-        self nextPutBytes:(restSamples*2) from:buffer startingAt:1
+	self nextPutBytes:(restSamples*2) from:buffer startingAt:1
     ].
 
     "of course, the frequency should be below half the
@@ -3320,6 +3321,8 @@
 openWithMode:aMode attributes:attributeSpec
     |ok error errorStringOrNil|
 
+    openMode := aMode.
+    openAttributes := attributeSpec.
 %{
 #ifdef SUPPORT_PORTAUDIO
     static PaStreamParameters outputParameters;
@@ -3450,126 +3453,9 @@
 !
 
 reopenStream
-    |ok errorStringOrNil error|
-
     handle1 isNil ifTrue:[^ self].
-
-%{
-#ifdef SUPPORT_PORTAUDIO
-    static PaStreamParameters outputParameters;
-    PaStream *stream;
-    PaError paErr;
-    struct paStreamData* paStreamData;
-    int nChannels, sampleRate, bytesPerSample;
-#   define FRAMES_PER_BUFFER 128
-    OBJ str;
-
-    ok = false;
-
-    str = __INST(handle1);
-    paStreamData = (struct paStreamData*)__externalAddressVal(str);
-    Pa_CloseStream( paStreamData->stream );
-
-    /* default output device */
-    outputParameters.device = Pa_GetDefaultOutputDevice();
-    if (outputParameters.device == paNoDevice) {
-        fprintf(stderr, "SoundStream [warning]: No default output device.\n");
-        errorStringOrNil = __MKSTRING("No default output device");
-        goto out;
-    }
-
-    if (__isSmallInteger(__INST(numberOfChannels))) {
-        nChannels = __intVal(__INST(numberOfChannels));
-    } else {
-        nChannels = 1;
-    }
-    outputParameters.channelCount = nChannels;
-    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
-    outputParameters.hostApiSpecificStreamInfo = NULL;
-
-    // The standard formats paFloat32, paInt16, paInt32, paInt24, paInt8
-    // and aUInt8 are usually implemented by all implementations.
-    // The floating point representation (paFloat32) uses +1.0 and -1.0 as the
-    // maximum and minimum respectively.
-    // paUInt8 is an unsigned 8 bit format where 128 is considered "ground"
-
-    if (__INST(audioFormat) == @symbol(S16)) {
-        outputParameters.sampleFormat = paInt16;
-        bytesPerSample = 2;
-    } else if (__INST(audioFormat) == @symbol(S32)) {
-        outputParameters.sampleFormat = paInt32;
-        bytesPerSample = 4;
-    } else if (__INST(audioFormat) == @symbol(S24)) {
-        outputParameters.sampleFormat = paInt24;
-        bytesPerSample = 3;
-    } else if (__INST(audioFormat) == @symbol(S8)) {
-        outputParameters.sampleFormat = paInt8;
-        bytesPerSample = 1;
-    } else if (__INST(audioFormat) == @symbol(F32)) {
-        outputParameters.sampleFormat = paFloat32;
-        bytesPerSample = 4;
-    } else if (__INST(audioFormat) == @symbol(U8)) {
-        outputParameters.sampleFormat = paUInt8;
-        bytesPerSample = 1;
-    } else {
-        fprintf(stderr, "SoundStream [warning]: unknown format - using U8\n");
-        outputParameters.sampleFormat = paUInt8;
-        bytesPerSample = 1;
-    }
-
-    if (__isSmallInteger(__INST(sampleRate))) {
-        sampleRate = __intVal(__INST(sampleRate));
-    } else {
-        fprintf(stderr, "SoundStream [warning]: using default sampleRate 8000\n");
-        sampleRate = 8000;
-    }
-
-    paStreamData = (struct paStreamData*)malloc(sizeof(struct paStreamData));
-    if (paStreamData == NULL) {
-        fprintf(stderr, "SoundStream [warning]: failed to allocate paStream\n");
-        errorStringOrNil = __MKSTRING("failed to allocate paStream");
-        goto out;
-    }
-
-    paErr = Pa_OpenStream(
-              &stream,
-              NULL, /* no input */
-              &outputParameters,
-              sampleRate,
-              FRAMES_PER_BUFFER,
-              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
-              paCallback,
-              paStreamData );
-
-    if (paErr != paNoError) {
-        fprintf(stderr, "SoundStream [warning]: openStream: %s\n", Pa_GetErrorText( paErr ));
-        free(paStreamData);
-        errorStringOrNil = __MKSTRING(Pa_GetErrorText( paErr ));
-        goto out;
-    }
-    paStreamData->stream = stream;
-
-    paStreamData->readOffset = 0;
-    paStreamData->bytesPerSample = bytesPerSample;
-    paStreamData->nChannels = nChannels;
-
-    paStreamData->currentBuffer = NULL;
-    paStreamData->lastBuffer = NULL;
-    paStreamData->freeList = NULL;
-    paStreamData->hasFinished = 0;
-
-    ok = true;
-out:;
-#endif /* SUPPORT_PORTAUDIO */
-
-%}.
-    ok == false ifTrue:[
-        lastErrorString := errorStringOrNil.
-        lastErrorNumber := error ? -1.
-        self openError:error.
-        "normally not reached"
-        ^ nil.
-    ].
+    self closeFile.
+    self openWithMode:openMode attributes:openAttributes
 ! !
 
 !SoundStream::PortAudio methodsFor:'private'!
@@ -3611,25 +3497,25 @@
 supportedAudioFormats
     "return a collection of supported audio formats.
      possibly returned symbols are:
-        U8        unsigned 8bit samples
-        S8        signed 8bit samples
-        U16       unsigned 16bit samples in native format
-        U16_LE    unsigned 16bit big endian samples
-        U16_BE    unsigned 16bit big endian samples
-        S16       signed 16bit little endian samples in native format
-        S16_LE    signed 16bit little endian samples
-        S16_BE    signed 16bit big endian samples
-        S24       signed 24bit little endian samples in native format
-        S24_LE    signed 24bit little endian samples
-        S24_BE    signed 24bit big endian samples
-        S32       signed 32bit little endian samples in native format
-        S32_LE    signed 32bit little endian samples
-        S32_BE    signed 32bit big endian samples
-        F32       float samples
-        MPEG      audio mpeg encoded
-        MU_LAW    u-law encoded 8bit samples
-        A_LAW     a-law encoded 8bit samples
-        IMA_ADPCM adpcm encoded
+	U8        unsigned 8bit samples
+	S8        signed 8bit samples
+	U16       unsigned 16bit samples in native format
+	U16_LE    unsigned 16bit big endian samples
+	U16_BE    unsigned 16bit big endian samples
+	S16       signed 16bit little endian samples in native format
+	S16_LE    signed 16bit little endian samples
+	S16_BE    signed 16bit big endian samples
+	S24       signed 24bit little endian samples in native format
+	S24_LE    signed 24bit little endian samples
+	S24_BE    signed 24bit big endian samples
+	S32       signed 32bit little endian samples in native format
+	S32_LE    signed 32bit little endian samples
+	S32_BE    signed 32bit big endian samples
+	F32       float samples
+	MPEG      audio mpeg encoded
+	MU_LAW    u-law encoded 8bit samples
+	A_LAW     a-law encoded 8bit samples
+	IMA_ADPCM adpcm encoded
      the set of returned symbols depends on the underlying sound hardware.
     "