SoundStr.st
changeset 712 9e853d04f52b
parent 614 565ea4308322
child 713 85912db3ad19
equal deleted inserted replaced
711:487b2bff9d31 712:9e853d04f52b
     9  other person.  No title to or ownership of the software is
     9  other person.  No title to or ownership of the software is
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 
    12 
    13 FileStream subclass:#SoundStream
    13 FileStream subclass:#SoundStream
    14 	instanceVariableNames:'sampleRate numberOfChannels bitsPerSample audioFormat'
    14 	instanceVariableNames:'sampleRate numberOfChannels bitsPerSample audioFormat
       
    15 			       alPort 
       
    16 			       pDirectSound pDSBuffer cbBufOffset cbBufSize'
    15 	classVariableNames:'UnsupportedOperationSignal'
    17 	classVariableNames:'UnsupportedOperationSignal'
    16 	poolDictionaries:''
    18 	poolDictionaries:''
    17 	category:'Streams-External'
    19 	category:'Streams-External'
    18 !
    20 !
    19 
    21 
    25 # endif
    27 # endif
    26 #endif
    28 #endif
    27 
    29 
    28 #ifdef IRIS_AUDIO
    30 #ifdef IRIS_AUDIO
    29 # include <audio.h>
    31 # include <audio.h>
    30 # define _ALportVal(o)  (ALport)(__externalAddressVal(o))
    32 # define __ALportVal(o)  (ALport)(__externalAddressVal(o))
    31 #endif
    33 #endif
    32 
    34 
    33 #ifdef LINUX
    35 #ifdef LINUX
    34 # define DEV_AUDIO
    36 # define DEV_AUDIO
    35 # include <sys/soundcard.h>
    37 # include <sys/soundcard.h>
    40 #endif
    42 #endif
    41 
    43 
    42 #ifdef DEV_AUDIO
    44 #ifdef DEV_AUDIO
    43 # include <stdio.h>
    45 # include <stdio.h>
    44 #endif
    46 #endif
       
    47 
       
    48 #ifdef WIN32
       
    49 
       
    50 # define _WIN32
       
    51 
       
    52 # undef INT
       
    53 # undef Array
       
    54 # undef Number
       
    55 # undef Method
       
    56 # undef Point
       
    57 # undef Rectangle
       
    58 # undef Block
       
    59 # undef String
       
    60 # undef Message
       
    61 # undef Object
       
    62 # undef Context
       
    63 
       
    64 /* # include <stdarg.h> /* */
       
    65 # include <stdio.h> /* */
       
    66 # include <windows.h>
       
    67 # define CINTERFACE
       
    68 # include "dsound.h"
       
    69 
       
    70 # ifdef __DEF_Array
       
    71 #  define Array __DEF_Array
       
    72 # endif
       
    73 # ifdef __DEF_Number
       
    74 #  define Number __DEF_Number
       
    75 # endif
       
    76 # ifdef __DEF_Method
       
    77 #  define Method __DEF_Method
       
    78 # endif
       
    79 # ifdef __DEF_Point
       
    80 #  define Point __DEF_Point
       
    81 # endif
       
    82 # ifdef __DEF_Block
       
    83 #  define Block __DEF_Block
       
    84 # endif
       
    85 # ifdef __DEF_String
       
    86 #  define String __DEF_String
       
    87 # endif
       
    88 # ifdef __DEF_Message
       
    89 #  define Message __DEF_Message
       
    90 # endif
       
    91 # ifdef __DEF_Object
       
    92 #  define Object __DEF_Object
       
    93 # endif
       
    94 # ifdef __DEF_Context
       
    95 #  define Context __DEF_Context
       
    96 # endif
       
    97 
       
    98 # define INT int
       
    99 
       
   100 # define __DirectSoundVal(o) (LPDIRECTSOUND)(__externalAddressVal(o))
       
   101 # define __DSBufferVal(o)    (LPDIRECTSOUNDBUFFER)(__externalAddressVal(o))
       
   102 
       
   103 # define RT_BUFFER_SIZE 4096
       
   104 # define NBUFS          4
       
   105 
       
   106 #endif
       
   107 
    45 %}
   108 %}
    46 ! !
   109 ! !
    47 
   110 
    48 !SoundStream class methodsFor:'documentation'!
   111 !SoundStream class methodsFor:'documentation'!
    49 
   112 
    80 
   143 
    81 !SoundStream class methodsFor:'initialization'!
   144 !SoundStream class methodsFor:'initialization'!
    82 
   145 
    83 initialize
   146 initialize
    84     UnsupportedOperationSignal isNil ifTrue:[
   147     UnsupportedOperationSignal isNil ifTrue:[
    85         UnsupportedOperationSignal := StreamErrorSignal newSignalMayProceed:false.
   148 	UnsupportedOperationSignal := StreamErrorSignal newSignalMayProceed:false.
    86         UnsupportedOperationSignal nameClass:self message:#unsupportedOperationSignal.
   149 	UnsupportedOperationSignal nameClass:self message:#unsupportedOperationSignal.
    87         UnsupportedOperationSignal notifierString:'unsupported operation'.
   150 	UnsupportedOperationSignal notifierString:'unsupported operation'.
    88     ]
   151     ]
    89 ! !
   152 ! !
    90 
   153 
    91 !SoundStream class methodsFor:'instance creation'!
   154 !SoundStream class methodsFor:'instance creation'!
    92 
   155 
   122 
   185 
   123     "Created: / 17.11.1995 / 17:25:42 / cg"
   186     "Created: / 17.11.1995 / 17:25:42 / cg"
   124     "Modified: / 12.12.1997 / 16:51:38 / cg"
   187     "Modified: / 12.12.1997 / 16:51:38 / cg"
   125 !
   188 !
   126 
   189 
   127 writing16BitStero
   190 writing16BitStereo
   128     "just an example, has never been tried (I also
   191     "just an example, has never been tried (I also
   129      have no samples for this ... leave it as an exercise)"
   192      have no samples for this ... leave it as an exercise)"
   130 
   193 
   131     |newStream|
   194     |newStream|
   132 
   195 
   200     }
   263     }
   201 %}.
   264 %}.
   202     "/
   265     "/
   203     "/ fallback for non-integral argument
   266     "/ fallback for non-integral argument
   204     "/
   267     "/
   205     sign := 0.
   268     a16bitSignedValue isInteger ifFalse:[
   206     (absVal := a16bitSignedValue asInteger) < 0 ifTrue:[
   269 	^ self uLawToLinear16:a16bitSignedValue asInteger
   207 	(absVal <= -32256) ifTrue:[
   270     ].
   208 	    ^ 0
   271     ^ 0
   209 	].
       
   210 	absVal := absVal negated.
       
   211 	sign := 16r80
       
   212     ] ifFalse:[
       
   213 	absVal >= 32256 ifTrue:[
       
   214 	    ^ 128
       
   215 	]
       
   216     ].
       
   217 
       
   218     exp := #[
       
   219 	      0 1 2 2 3 3 3 3 4 4 4 4 4 4 4 4
       
   220 	      5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
       
   221 	      6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
       
   222 	      6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
       
   223 	      7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
       
   224 	      7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
       
   225 	      7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
       
   226 	      7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
       
   227 	   ] at:(absVal bitShift:-1)+1.
       
   228     mantissa := (absVal bitShift:(exp+3) negated) bitAnd:16r0F.
       
   229     byte := ((sign bitOr:(exp bitShift:4)) bitOr:mantissa) bitInvert bitAnd:16rFF.
       
   230     ^ byte
       
   231 
   272 
   232     "
   273     "
   233      SoundStream uLawToLinear16:(SoundStream linear16ToUlaw:0)    
   274      SoundStream uLawToLinear16:(SoundStream linear16ToUlaw:0)    
   234      SoundStream uLawToLinear16:(SoundStream linear16ToUlaw:32256)   
   275      SoundStream uLawToLinear16:(SoundStream linear16ToUlaw:32256)   
   235      SoundStream uLawToLinear16:(SoundStream linear16ToUlaw:-32256)  
   276      SoundStream uLawToLinear16:(SoundStream linear16ToUlaw:-32256)  
   511 ! !
   552 ! !
   512 
   553 
   513 !SoundStream class methodsFor:'default values'!
   554 !SoundStream class methodsFor:'default values'!
   514 
   555 
   515 defaultAudioFormat
   556 defaultAudioFormat
       
   557     OperatingSystem getOSType = 'win32' ifTrue:[
       
   558 	^ #S16 
       
   559     ].
   516     ^ #U8 
   560     ^ #U8 
   517 !
   561 !
   518 
   562 
   519 defaultBitsPerSample
   563 defaultBitsPerSample
   520     "minimum, supported by all audio systems"
   564     "minimum, supported by all audio systems"
   521 
   565 
       
   566     OperatingSystem getOSType = 'win32' ifTrue:[
       
   567 	^ 16 
       
   568     ].
   522     ^ 8
   569     ^ 8
   523 !
   570 !
   524 
   571 
   525 defaultNumberOfChannels
   572 defaultNumberOfChannels
   526     "minimum, supported by all audio systems"
   573     "minimum, supported by all audio systems"
   640 
   687 
   641     |fd blockSize speed channels stereo|
   688     |fd blockSize speed channels stereo|
   642 
   689 
   643     fd := self fileDescriptor.
   690     fd := self fileDescriptor.
   644     fd isNil ifTrue:[
   691     fd isNil ifTrue:[
   645         self error.
   692 	self error.
   646         ^ nil
   693 	^ nil
   647     ].
   694     ].
   648 %{
   695 %{
   649     int f = __intVal(fd);
   696     int f = __intVal(fd);
   650     int __blockSize = -1;
   697     int __blockSize = -1;
   651     int __speed = 0;
   698     int __speed = 0;
   652     int __stereo = 0;
   699     int __stereo = 0;
   653     int __channels = 0;
   700     int __channels = 0;
   654 
   701 
   655 #if defined(DEV_AUDIO) 
   702 #if defined(DEV_AUDIO) 
   656 # if defined(LINUX)
       
   657 #  if defined(SNDCTL_DSP_GETBLKSIZE)
       
   658     if (ioctl(f, SNDCTL_DSP_GETBLKSIZE, &__blockSize) >= 0) {
       
   659         blockSize = __MKSMALLINT(__blockSize);
       
   660     }
       
   661 #  endif
       
   662 #  if defined(SNDCTL_DSP_CHANNELS)
       
   663     if (ioctl(f, SNDCTL_DSP_CHANNELS, &__channels) >= 0) {
       
   664         channels = __MKSMALLINT(__channels);
       
   665     }
       
   666 #  endif
       
   667 #  if defined(SNDCTL_DSP_STEREO)
       
   668     if (ioctl(f, SNDCTL_DSP_STEREO, &__stereo) >= 0) {
       
   669         stereo = __MKSMALLINT(__stereo);
       
   670     }
       
   671 #  endif
       
   672 #  if defined(SNDCTL_DSP_SPEED)
       
   673     if (ioctl(f, SNDCTL_DSP_SPEED, &__speed) >= 0) {
       
   674         speed = __MKSMALLINT(__speed);
       
   675     }
       
   676 #  endif
       
   677 # else
       
   678     channels = __MKSMALLINT(1);
   703     channels = __MKSMALLINT(1);
   679     stereo = __MKSMALLINT(0);
   704     stereo = __MKSMALLINT(0);
   680     speed = __MKSMALLINT(8000);
   705     speed = __MKSMALLINT(8000);
   681 # endif /* LINUX */
   706 
       
   707 # if defined(SNDCTL_DSP_GETBLKSIZE)
       
   708     if (ioctl(f, SNDCTL_DSP_GETBLKSIZE, &__blockSize) >= 0) {
       
   709 	blockSize = __MKSMALLINT(__blockSize);
       
   710     }
       
   711 # endif
       
   712 # if defined(SNDCTL_DSP_CHANNELS)
       
   713     if (ioctl(f, SNDCTL_DSP_CHANNELS, &__channels) >= 0) {
       
   714 	channels = __MKSMALLINT(__channels);
       
   715     }
       
   716 # endif
       
   717 # if defined(SNDCTL_DSP_STEREO)
       
   718     if (ioctl(f, SNDCTL_DSP_STEREO, &__stereo) >= 0) {
       
   719 	stereo = __MKSMALLINT(__stereo);
       
   720     }
       
   721 # endif
       
   722 # if defined(SNDCTL_DSP_SPEED)
       
   723     if (ioctl(f, SNDCTL_DSP_SPEED, &__speed) >= 0) {
       
   724 	speed = __MKSMALLINT(__speed);
       
   725     }
       
   726 # endif
   682 #endif /* DEV_AUDIO */
   727 #endif /* DEV_AUDIO */
   683 %}.
   728 %}.
   684     blockSize notNil ifTrue:[
   729     blockSize notNil ifTrue:[
   685         Transcript show:'blockSize: '; showCR:blockSize
   730 	Transcript show:'blockSize: '; showCR:blockSize
   686     ].
   731     ].
   687     speed notNil ifTrue:[
   732     speed notNil ifTrue:[
   688         Transcript show:'speed: '; showCR:speed
   733 	Transcript show:'speed: '; showCR:speed
   689     ].
   734     ].
   690     channels notNil ifTrue:[
   735     channels notNil ifTrue:[
   691         Transcript show:'channels: '; showCR:channels
   736 	Transcript show:'channels: '; showCR:channels
   692     ].
   737     ].
   693     stereo notNil ifTrue:[
   738     stereo notNil ifTrue:[
   694         Transcript show:'stereo: '; showCR:stereo
   739 	Transcript show:'stereo: '; showCR:stereo
   695     ].
   740     ].
   696 
   741 
   697     Transcript show:'audioFormats: '; showCR:(self supportedAudioFormats).
   742     Transcript show:'audioFormats: '; showCR:(self supportedAudioFormats).
   698 
   743 
   699     "
   744     "
   703 
   748 
   704 initialize 
   749 initialize 
   705     "initialize for least common mode"
   750     "initialize for least common mode"
   706 
   751 
   707     buffered := false.
   752     buffered := false.
   708     bitsPerSample := 8.
   753     bitsPerSample := self class defaultBitsPerSample.
   709     audioFormat := #U8.
   754     audioFormat := self class defaultAudioFormat.
   710     numberOfChannels := 1.
   755     numberOfChannels := self class defaultNumberOfChannels.
   711     sampleRate := 8000.
   756     sampleRate := self class defaultSampleRate.
   712 
   757     pathName := nil.
   713     '/dev/audio' asFilename exists ifTrue:[
   758 
   714 	"/
   759     OperatingSystem getOSType ~= 'win32' ifTrue:[
   715 	"/ sunos or linux
   760 	'/dev/audio' asFilename exists ifTrue:[
   716 	"/
   761 	    "/
   717 	pathName := '/dev/audio'.
   762 	    "/ sunos or linux
   718     ].
   763 	    "/
   719 
   764 	    pathName := '/dev/audio'.
   720     OperatingSystem getOSType = 'irix' ifTrue:[
   765 	].
   721 	"no device, use special library calls"
       
   722 	pathName := nil.
       
   723     ].
   766     ].
   724 
   767 
   725     "Created: 17.11.1995 / 17:28:14 / cg"
   768     "Created: 17.11.1995 / 17:28:14 / cg"
   726 !
   769 !
   727 
   770 
   728 resetSoundCard
   771 resetSoundCard
   729     "debugging interface - reset the soundCard"
   772     "debugging interface - reset the soundCard"
   730 
   773 
   731     |fd|
   774     |fd|
   732 
   775 
   733     fd := self fileDescriptor.
   776     filePointer notNil ifTrue:[
   734     fd isNil ifTrue:[
   777 	fd := self fileDescriptor.
   735 	self error.
   778 	fd isNil ifTrue:[
   736 	^ nil
   779 	    self error.
       
   780 	    ^ nil
       
   781 	]
   737     ].
   782     ].
   738 %{
   783 %{
   739     int f = __intVal(fd);
   784     int f = __intVal(fd);
   740     int __dummy;
   785     int __dummy;
   741 
   786 
   742 #if defined(DEV_AUDIO) && defined(LINUX)
   787 #if defined(DEV_AUDIO)
       
   788     if (__isSmallInteger(fd)) {
   743 # if defined(SNDCTL_DSP_RESET)
   789 # if defined(SNDCTL_DSP_RESET)
   744     if (ioctl(f, SNDCTL_DSP_RESET, &__dummy) >= 0) {
   790 	if (ioctl(f, SNDCTL_DSP_RESET, &__dummy) >= 0) {
   745 	RETURN (self);
   791 	    RETURN (self);
   746     }
   792 	}
   747 # endif
   793 # endif
       
   794     }
   748 #endif
   795 #endif
   749 %}.
   796 %}.
   750     ^ UnsupportedOperationSignal raise
   797     ^ UnsupportedOperationSignal raise
   751 
   798 
   752     "
   799     "
   758     "set the format of the audio data as specified by aSymbol.
   805     "set the format of the audio data as specified by aSymbol.
   759      Returns true if sucessfull - may fail with some formats on many sound devices."
   806      Returns true if sucessfull - may fail with some formats on many sound devices."
   760 
   807 
   761     |fd|
   808     |fd|
   762 
   809 
   763     fd := self fileDescriptor.
   810     filePointer notNil ifTrue:[
   764     fd isNil ifTrue:[
   811 	fd := self fileDescriptor.
   765         self error.
   812 	fd isNil ifTrue:[
   766         ^ nil
   813 	    self error.
       
   814 	    ^ nil
       
   815 	]
   767     ].
   816     ].
   768 %{
   817 %{
   769     int f = __intVal(fd);
   818     int f = __intVal(fd);
   770     int __fmt = 0, __fmtWant;
   819     int __fmt = 0, __fmtWant;
   771     union {
   820     union {
   772         unsigned short us;
   821 	unsigned short us;
   773         unsigned char ub[2];
   822 	unsigned char ub[2];
   774     } u;
   823     } u;
   775     OBJ sym = aSymbol;
   824     OBJ sym = aSymbol;
   776 
   825 
   777 #if defined(DEV_AUDIO) && defined(LINUX)
   826 #if defined(DEV_AUDIO)
   778     if (__isSymbol(sym)) {
   827     if (__isSmallInteger(fd)) {
   779         if (sym == @symbol(U16)) {
   828 	if (__isSymbol(sym)) {
   780             u.us = 0x1234;
   829 	    if (sym == @symbol(U16)) {
   781             if (u.ub[0] == 0x34) {
   830 		u.us = 0x1234;
       
   831 		if (u.ub[0] == 0x34) {
   782 /* printf("U16_LE\n"); */
   832 /* printf("U16_LE\n"); */
   783                 sym = @symbol(U16_LE);
   833 		    sym = @symbol(U16_LE);
   784             } else {
   834 		} else {
   785 /* printf("U16_BE\n"); */
   835 /* printf("U16_BE\n"); */
   786                 sym = @symbol(U16_BE);
   836 		    sym = @symbol(U16_BE);
   787             }
   837 		}
   788         } else if (sym == @symbol(S16)) {
   838 	    } else if (sym == @symbol(S16)) {
   789             u.us = 0x1234;
   839 		u.us = 0x1234;
   790             if (u.ub[0] == 0x34) {
   840 		if (u.ub[0] == 0x34) {
   791 /* printf("S16_LE\n"); */
   841 /* printf("S16_LE\n"); */
   792                sym = @symbol(S16_LE);
   842 		   sym = @symbol(S16_LE);
   793             } else {
   843 		} else {
   794 /* printf("S16_BE\n"); */
   844 /* printf("S16_BE\n"); */
   795                sym = @symbol(S16_BE);
   845 		   sym = @symbol(S16_BE);
   796             }
   846 		}
   797         }
   847 	    }
   798 
   848 
   799         if (sym == @symbol(MU_LAW)) {
   849 	    if (0) {
   800             __fmt = AFMT_MU_LAW;
   850 #ifdef AFMT_MU_LAW
   801         } else if (sym == @symbol(A_LAW)) {
   851 	    } else if (sym == @symbol(MU_LAW)) {
   802             __fmt = AFMT_A_LAW;
   852 		__fmt = AFMT_MU_LAW;
   803         } else if (sym == @symbol(IMA_ADPCM)) {
   853 #endif
   804             __fmt = AFMT_IMA_ADPCM;
   854 #ifdef AFMT_A_LAW
   805         } else if (sym == @symbol(U8)) {
   855 	    } else if (sym == @symbol(A_LAW)) {
   806             __fmt = AFMT_U8;
   856 		__fmt = AFMT_A_LAW;
   807         } else if (sym == @symbol(S8)) {
   857 #endif
   808             __fmt = AFMT_S8;
   858 #ifdef AFMT_IMA_ADPCM
   809         } else if (sym == @symbol(U16_LE)) {
   859 	    } else if (sym == @symbol(IMA_ADPCM)) {
   810             __fmt = AFMT_U16_LE;
   860 		__fmt = AFMT_IMA_ADPCM;
   811         } else if (sym == @symbol(U16_BE)) {
   861 #endif
   812             __fmt = AFMT_U16_BE;
   862 #ifdef AFMT_U8
   813         } else if (sym == @symbol(S16_LE)) {
   863 	    } else if (sym == @symbol(U8)) {
   814             __fmt = AFMT_S16_LE;
   864 		__fmt = AFMT_U8;
   815         } else if (sym == @symbol(S16_BE)) {
   865 #endif
   816             __fmt = AFMT_S16_BE;
   866 #ifdef AFMT_S8
   817         } else if (sym == @symbol(MPEG)) {
   867 	    } else if (sym == @symbol(S8)) {
   818             __fmt = AFMT_MPEG;
   868 		__fmt = AFMT_S8;
   819         } else {
   869 #endif
   820             fprintf(stderr, "bad format: %s\n", __stringVal(sym));
   870 #ifdef AFMT_U16_LE
   821             goto bad;
   871 	    } else if (sym == @symbol(U16_LE)) {
   822         }
   872 		__fmt = AFMT_U16_LE;
   823     }
   873 #endif
   824 
   874 #ifdef AFMT_U16_BE
   825     __fmtWant = __fmt;
   875 	    } else if (sym == @symbol(U16_BE)) {
   826 
   876 		__fmt = AFMT_U16_BE;
   827     if (ioctl(f, SNDCTL_DSP_SETFMT, &__fmt) >= 0) {
   877 #endif
   828         if (__fmt == __fmtWant) {
   878 #ifdef AFMT_S16_LE
   829             __INST(audioFormat) = sym;
   879 	    } else if (sym == @symbol(S16_LE)) {
   830             RETURN (self);
   880 		__fmt = AFMT_S16_LE;
   831         } else {
   881 #endif
   832             /* fprintf(stderr, "want: %x; got: %x\n", __fmtWant, __fmt); */
   882 #ifdef AFMT_S16_BE
   833         }
   883 	    } else if (sym == @symbol(S16_BE)) {
   834     } else {
   884 		__fmt = AFMT_S16_BE;
   835             /* fprintf(stderr, "got err-return from setFmp %x\n", __fmt); */
   885 #endif
   836     }
   886 #ifdef AFMT_MPEG
       
   887 	    } else if (sym == @symbol(MPEG)) {
       
   888 		__fmt = AFMT_MPEG;
       
   889 #endif
       
   890 	    } else {
       
   891 		fprintf(stderr, "bad format: %s\n", __stringVal(sym));
       
   892 		goto bad;
       
   893 	    }
       
   894 	}
       
   895 
       
   896 	__fmtWant = __fmt;
       
   897 
       
   898 #ifdef SNDCTL_DSP_SETFMT
       
   899 	if (ioctl(f, SNDCTL_DSP_SETFMT, &__fmt) >= 0) {
       
   900 	    if (__fmt == __fmtWant) {
       
   901 		__INST(audioFormat) = sym;
       
   902 		RETURN (self);
       
   903 	    } else {
       
   904 		/* fprintf(stderr, "want: %x; got: %x\n", __fmtWant, __fmt); */
       
   905 	    }
       
   906 	} else {
       
   907 		/* fprintf(stderr, "got err-return from setFmp %x\n", __fmt); */
       
   908 	}
       
   909 #endif /* SNDCTL_DSP_SETFMT */
       
   910 
   837 bad: ;
   911 bad: ;
   838 #endif
   912     }
       
   913 #endif /* DEV_AUDIO */
       
   914 
   839 %}.
   915 %}.
   840     ^ UnsupportedOperationSignal raise
   916     ^ UnsupportedOperationSignal raise
   841 
   917 
   842     "
   918     "
   843      self writing setAudioFormat:#'MU_LAW'; close
   919      self writing setAudioFormat:#'MU_LAW'; close
   850     "set the number of channels (1 -> mono; 2 -> stereo).
   926     "set the number of channels (1 -> mono; 2 -> stereo).
   851      Returns true if sucessfull - may fail with many sound devices."
   927      Returns true if sucessfull - may fail with many sound devices."
   852 
   928 
   853     |fd|
   929     |fd|
   854 
   930 
   855     fd := self fileDescriptor.
   931     filePointer notNil ifTrue:[
   856     fd isNil ifTrue:[
   932 	fd := self fileDescriptor.
   857 	self error.
   933 	fd isNil ifTrue:[
   858 	^ nil
   934 	    self error.
       
   935 	    ^ nil
       
   936 	]
   859     ].
   937     ].
   860 %{
   938 %{
   861     int f = __intVal(fd);
   939     int f = __intVal(fd);
   862     int __nCh = 0;
   940     int __nCh = 0;
   863 
   941 
   864 #if defined(DEV_AUDIO) && defined(LINUX)
   942 #if defined(DEV_AUDIO) && defined(SOUND_PCM_WRITE_CHANNELS)
   865     if (__isSmallInteger(nChannels)) {
   943     if (__isSmallInteger(fd) && __isSmallInteger(nChannels)) {
   866 	__nCh = __intVal(nChannels);
   944 	__nCh = __intVal(nChannels);
   867 	if (ioctl(f, SOUND_PCM_WRITE_CHANNELS, &__nCh) >= 0) {
   945 	if (ioctl(f, SOUND_PCM_WRITE_CHANNELS, &__nCh) >= 0) {
   868 	    __INST(numberOfChannels) = nChannels;
   946 	    __INST(numberOfChannels) = nChannels;
   869 	    RETURN (self);
   947 	    RETURN (self);
   870 	}
   948 	}
   884     "set the soundDrivers fragmentSize.
   962     "set the soundDrivers fragmentSize.
   885      Returns true if sucessfull - may fail with many sound devices."
   963      Returns true if sucessfull - may fail with many sound devices."
   886 
   964 
   887     |fd|
   965     |fd|
   888 
   966 
   889     fd := self fileDescriptor.
   967     filePointer notNil ifTrue:[
   890     fd isNil ifTrue:[
   968 	fd := self fileDescriptor.
   891 	self error.
   969 	fd isNil ifTrue:[
   892 	^ nil
   970 	    self error.
       
   971 	    ^ nil
       
   972 	]
   893     ].
   973     ].
   894 %{
   974 %{
   895     int f = __intVal(fd);
   975     int f = __intVal(fd);
   896     int __blockSize = 0;
   976     int __blockSize = 0;
   897 
   977 
   898 #if defined(DEV_AUDIO) && defined(LINUX)
   978 #if defined(DEV_AUDIO) && defined(SNDCTL_DSP_SETFRAGMENT)
   899     if (__isSmallInteger(blockSize)) {
   979     if (__isSmallInteger(fd) && __isSmallInteger(blockSize)) {
   900 	__blockSize = __intVal(blockSize);
   980 	__blockSize = __intVal(blockSize);
   901 	if (ioctl(f, SNDCTL_DSP_SETFRAGMENT, &__blockSize) >= 0) {
   981 	if (ioctl(f, SNDCTL_DSP_SETFRAGMENT, &__blockSize) >= 0) {
   902 	    /* __INST(blockSize) = blockSize; */
   982 	    /* __INST(blockSize) = blockSize; */
   903 	    RETURN (self);
   983 	    RETURN (self);
   904 	}
   984 	}
   912     "set the sample rate.
   992     "set the sample rate.
   913      Returns true if sucessfull - may fail with many sound devices."
   993      Returns true if sucessfull - may fail with many sound devices."
   914 
   994 
   915     |fd|
   995     |fd|
   916 
   996 
   917     fd := self fileDescriptor.
   997     filePointer notNil ifTrue:[
   918     fd isNil ifTrue:[
   998 	fd := self fileDescriptor.
   919 	self error.
   999 	fd isNil ifTrue:[
   920 	^ nil
  1000 	    self error.
       
  1001 	    ^ nil
       
  1002 	]
   921     ].
  1003     ].
   922 %{
  1004 %{
   923     int f = __intVal(fd);
  1005     int f = __intVal(fd);
   924     int __rate = 0;
  1006     int __rate = 0;
   925     int __rateWant;
  1007     int __rateWant;
   926 
  1008 
   927 #if defined(DEV_AUDIO) && defined(LINUX)
  1009 #if defined(DEV_AUDIO) && defined(SOUND_PCM_WRITE_RATE)
   928     if (__isSmallInteger(hz)) {
  1010     if (__isSmallInteger(fd) && __isSmallInteger(hz)) {
   929 	__rate = __rateWant = __intVal(hz);
  1011 	__rate = __rateWant = __intVal(hz);
   930 	if (ioctl(f, SOUND_PCM_WRITE_RATE, &__rate) >= 0) {
  1012 	if (ioctl(f, SOUND_PCM_WRITE_RATE, &__rate) >= 0) {
   931 	    if (__rate != __rateWant) {
  1013 	    if (__rate != __rateWant) {
   932 		fprintf(stderr, "SoundStream [warning]: actual rate is %d\n", __rate);
  1014 		fprintf(stderr, "SoundStream [warning]: actual rate is %d\n", __rate);
   933 		hz = __MKSMALLINT(__rate);
  1015 		hz = __MKSMALLINT(__rate);
   959 	U16_BE    unsigned 16bit big endian samples
  1041 	U16_BE    unsigned 16bit big endian samples
   960 	S16       signed 16bit little endian samples
  1042 	S16       signed 16bit little endian samples
   961 	S16_LE    signed 16bit little endian samples
  1043 	S16_LE    signed 16bit little endian samples
   962 	S16_BE    signed 16bit big endian samples
  1044 	S16_BE    signed 16bit big endian samples
   963 	MPEG      audio mpeg encoded
  1045 	MPEG      audio mpeg encoded
       
  1046 	PCM       pcm
   964     "
  1047     "
   965 
  1048 
   966     |fd audioFormatMask
  1049     |fd audioFormatMask
   967      supportedFormats
  1050      supportedFormats
   968      supports_MU_LAW supports_A_LAW
  1051      supports_MU_LAW supports_A_LAW
   969      supports_IMA_ADPCM supports_U8
  1052      supports_IMA_ADPCM supports_U8
   970      supports_S16_LE supports_S16_BE
  1053      supports_S16_LE supports_S16_BE
   971      supports_S8 supports_U16_LE
  1054      supports_S8 supports_U16_LE
   972      supports_U16_BE supports_MPEG|
  1055      supports_U16_BE supports_MPEG supports_PCM|
   973 
  1056 
   974     fd := self fileDescriptor.
  1057     fd := self fileDescriptor.
   975     fd isNil ifTrue:[
  1058     fd isNil ifTrue:[
   976 	self error.
  1059 	self error.
   977 	^ nil
  1060 	^ nil
   979 %{
  1062 %{
   980     int f = __intVal(fd);
  1063     int f = __intVal(fd);
   981     int __audioFormatMask = 0;
  1064     int __audioFormatMask = 0;
   982 
  1065 
   983 #if defined(DEV_AUDIO)
  1066 #if defined(DEV_AUDIO)
   984 # if defined(LINUX)
  1067     supports_MU_LAW = true;
       
  1068 
       
  1069 # if defined(SNDCTL_DSP_GETFMTS)
   985     if (ioctl(f, SNDCTL_DSP_GETFMTS, &__audioFormatMask) >= 0) {
  1070     if (ioctl(f, SNDCTL_DSP_GETFMTS, &__audioFormatMask) >= 0) {
   986 	audioFormatMask = __MKSMALLINT(__audioFormatMask);
  1071 	audioFormatMask = __MKSMALLINT(__audioFormatMask);
   987 
  1072 
       
  1073 #  ifdef AFMT_MU_LAW
   988 	supports_MU_LAW = (__audioFormatMask & AFMT_MU_LAW) ? true : false;
  1074 	supports_MU_LAW = (__audioFormatMask & AFMT_MU_LAW) ? true : false;
       
  1075 #  endif
       
  1076 #  ifdef AFMT_A_LAW
   989 	supports_A_LAW = (__audioFormatMask & AFMT_A_LAW) ? true : false;
  1077 	supports_A_LAW = (__audioFormatMask & AFMT_A_LAW) ? true : false;
       
  1078 #  endif
       
  1079 #  ifdef AFMT_IMA_ADPCM
   990 	supports_IMA_ADPCM = (__audioFormatMask & AFMT_IMA_ADPCM) ? true : false;
  1080 	supports_IMA_ADPCM = (__audioFormatMask & AFMT_IMA_ADPCM) ? true : false;
       
  1081 #  endif
       
  1082 #  ifdef AFMT_U8
   991 	supports_U8 = (__audioFormatMask & AFMT_U8) ? true : false;
  1083 	supports_U8 = (__audioFormatMask & AFMT_U8) ? true : false;
       
  1084 #  endif
       
  1085 #  ifdef AFMT_S16_LE
   992 	supports_S16_LE = (__audioFormatMask & AFMT_S16_LE) ? true : false;
  1086 	supports_S16_LE = (__audioFormatMask & AFMT_S16_LE) ? true : false;
       
  1087 #  endif
       
  1088 #  ifdef AFMT_S16_BE
   993 	supports_S16_BE = (__audioFormatMask & AFMT_S16_BE) ? true : false;
  1089 	supports_S16_BE = (__audioFormatMask & AFMT_S16_BE) ? true : false;
       
  1090 #  endif
       
  1091 #  ifdef AFMT_S8
   994 	supports_S8 = (__audioFormatMask & AFMT_S8) ? true : false;
  1092 	supports_S8 = (__audioFormatMask & AFMT_S8) ? true : false;
       
  1093 #  endif
       
  1094 #  ifdef AFMT_U16_LE
   995 	supports_U16_LE = (__audioFormatMask & AFMT_U16_LE) ? true : false;
  1095 	supports_U16_LE = (__audioFormatMask & AFMT_U16_LE) ? true : false;
       
  1096 #  endif
       
  1097 #  ifdef AFMT_U16_BE
   996 	supports_U16_BE = (__audioFormatMask & AFMT_U16_BE) ? true : false;
  1098 	supports_U16_BE = (__audioFormatMask & AFMT_U16_BE) ? true : false;
       
  1099 #  endif
       
  1100 #  ifdef AFMT_MPEG
   997 	supports_MPEG = (__audioFormatMask & AFMT_MPEG) ? true : false;
  1101 	supports_MPEG = (__audioFormatMask & AFMT_MPEG) ? true : false;
   998     }
  1102 #  endif
   999 # else
  1103     }
  1000     supports_MU_LAW = true;
       
  1001 # endif
  1104 # endif
  1002 
  1105 
  1003 #endif /* DEV_AUDIO */
  1106 #endif /* DEV_AUDIO */
  1004 
  1107 
  1005 #ifdef IRIS_AUDIO
  1108 #ifdef IRIS_AUDIO
  1006     supports_U8 = true;
  1109     supports_U8 = true;
  1007     supports_U16_BE = true;
  1110     supports_U16_BE = true;
       
  1111 #endif
       
  1112 
       
  1113 #ifdef WIN32
       
  1114     supports_S16_LE = true;
  1008 #endif
  1115 #endif
  1009 
  1116 
  1010 %}.
  1117 %}.
  1011     supportedFormats := IdentitySet new.
  1118     supportedFormats := IdentitySet new.
  1012     supports_MU_LAW ifTrue:[
  1119     supports_MU_LAW ifTrue:[
  1055     "
  1162     "
  1056 ! !
  1163 ! !
  1057 
  1164 
  1058 !SoundStream methodsFor:'redefined'!
  1165 !SoundStream methodsFor:'redefined'!
  1059 
  1166 
  1060 close
  1167 XXclose
  1061     OperatingSystem getOSType = 'irix' ifTrue:[
  1168     OperatingSystem getOSType = 'irix' ifTrue:[
       
  1169 	^ self closeFile
       
  1170     ].
       
  1171     OperatingSystem getOSType = 'win32' ifTrue:[
  1062 	^ self closeFile
  1172 	^ self closeFile
  1063     ].
  1173     ].
  1064 
  1174 
  1065     super close
  1175     super close
  1066 
  1176 
  1073 
  1183 
  1074 %{
  1184 %{
  1075 #ifdef IRIS_AUDIO
  1185 #ifdef IRIS_AUDIO
  1076     OBJ port;
  1186     OBJ port;
  1077 
  1187 
  1078     if ((port = __INST(filePointer)) != nil) {
  1188     if ((port = __INST(alPort)) != nil) {
  1079         __INST(filePointer) = nil;
  1189 	__INST(alPort) = nil;
  1080         ALcloseport(_ALportVal(port));
  1190 	ALcloseport(__ALportVal(port));
       
  1191     }
       
  1192     RETURN (self);
       
  1193 #endif
       
  1194 
       
  1195 #ifdef WIN32
       
  1196     OBJ oDirectSound, oDSBuffer;
       
  1197     LPDIRECTSOUND       t_pDirectSound;
       
  1198     LPDIRECTSOUNDBUFFER t_pDSBuffer;
       
  1199 
       
  1200     if ((oDSBuffer = __INST(pDSBuffer)) != nil) {
       
  1201 	__INST(pDSBuffer) = nil;
       
  1202 	t_pDSBuffer = __DSBufferVal(oDSBuffer);
       
  1203 	if (t_pDSBuffer) {
       
  1204 	    IDirectSoundBuffer_Stop(t_pDSBuffer);
       
  1205 	    IDirectSoundBuffer_Release(t_pDSBuffer);
       
  1206 	}
       
  1207     }
       
  1208     if ((oDirectSound = __INST(pDirectSound)) != nil) {
       
  1209 	__INST(pDirectSound) = nil;
       
  1210 	t_pDirectSound = __DirectSoundVal(oDirectSound);
       
  1211 	if (t_pDirectSound) {
       
  1212 	    IDirectSound_Release(t_pDirectSound);
       
  1213 	}
  1081     }
  1214     }
  1082     RETURN (self);
  1215     RETURN (self);
  1083 #endif
  1216 #endif
  1084 
  1217 
  1085 #if defined(DEV_AUDIO)
  1218 #if defined(DEV_AUDIO)
  1117     |fd|
  1250     |fd|
  1118 
  1251 
  1119     fd := self fileDescriptor.
  1252     fd := self fileDescriptor.
  1120 %{ 
  1253 %{ 
  1121 #ifdef IRIS_AUDIO
  1254 #ifdef IRIS_AUDIO
       
  1255     OPJ port;
  1122     ALport p;
  1256     ALport p;
  1123 
  1257 
  1124     if (__INST(filePointer) != nil) {
  1258     if ((port = __INST(alPort)) != nil) {
  1125 	p = _ALportVal(__INST(filePointer));
  1259 	p = __ALportVal(port);
  1126 	while (ALgetfilled(p) > 0) {
  1260 	while (ALgetfilled(p) > 0) {
  1127 	    sginap(1);
  1261 	    sginap(1);
  1128 	}
  1262 	}
  1129     }
  1263     }
  1130     RETURN(self);
  1264     RETURN(self);
  1131 #endif
  1265 #endif
  1132 
  1266 
  1133 #if defined(DEV_AUDIO) && defined(LINUX)
  1267 #if defined(DEV_AUDIO)
  1134     if (__isSmallInteger(fd)) {
  1268     if (__isSmallInteger(fd)) {
  1135 	int f = __intVal(fd);
  1269 	int f = __intVal(fd);
  1136 	/* ... */
  1270 	/* ... */
  1137     }
  1271     }
  1138 #endif
  1272 #endif
  1139 %}.
  1273 %}.
  1140     "dont know how to wait on non-iris systems"
  1274     "dont know how to wait on non-iris systems"
  1141     ^ self
  1275     ^ self
       
  1276 !
       
  1277 
       
  1278 isOpen
       
  1279     alPort notNil ifTrue:[^ true].
       
  1280     pDirectSound notNil ifTrue:[^ true].
       
  1281     ^ filePointer notNil
  1142 !
  1282 !
  1143 
  1283 
  1144 nextBytes:count into:anObject startingAt:start
  1284 nextBytes:count into:anObject startingAt:start
  1145     "read the next count bytes into an object and return the number of
  1285     "read the next count bytes into an object and return the number of
  1146      bytes read or nil on error.
  1286      bytes read or nil on error.
  1147      Use with ByteArrays only."
  1287      Use with ByteArrays only."
  1148 
  1288 
  1149 %{
  1289 %{
  1150 #ifdef IRIS_AUDIO
  1290 #ifdef IRIS_AUDIO
  1151   {
  1291   {
       
  1292     OBJ port;
  1152     ALport p;
  1293     ALport p;
  1153     int cnt, offs;
  1294     int cnt, offs, nSamp;
  1154     int objSize;
  1295     int objSize;
  1155     char *cp;
  1296     char *cp;
  1156 
  1297 
  1157     if (__INST(filePointer) != nil) {
  1298     if ((port = __INST(alPort)) != nil) {
  1158 	if (__INST(mode) != _writeonly) {
  1299 	if (__INST(mode) != _writeonly) {
  1159 	    if (__bothSmallInteger(count, start)) {
  1300 	    if (__bothSmallInteger(count, start)) {
  1160 		cnt = _intVal(count);
  1301 		cnt = __intVal(count);
  1161 		offs = _intVal(start) - 1;
  1302 		offs = __intVal(start) - 1;
  1162 		p = _ALportVal(__INST(filePointer));
  1303 		p = __ALportVal(port);
  1163 		objSize = _Size(anObject) - OHDR_SIZE;
  1304 		objSize = _Size(anObject) - OHDR_SIZE;
  1164 		if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
  1305 		if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
  1165 		    cp = (char *)__InstPtr(anObject) + OHDR_SIZE + offs;
  1306 		    cp = (char *)__InstPtr(anObject) + OHDR_SIZE + offs;
  1166 		    if (__INST(bitsPerSample) == __MKSMALLINT(16))
  1307 		    if (__INST(bitsPerSample) == __MKSMALLINT(16))
  1167 			ALreadsamps(p, cp, cnt / 2);
  1308 			nSamp = cnt / 2;
  1168 		    else
  1309 		    else
  1169 			ALreadsamps(p, cp, cnt);
  1310 			nSamp = cnt;
       
  1311 		    ALreadsamps(p, cp, nSamp);
  1170 		    RETURN ( __MKSMALLINT(cnt) );
  1312 		    RETURN ( __MKSMALLINT(cnt) );
  1171 		}
  1313 		}
  1172 	    }
  1314 	    }
  1173 	}
  1315 	}
  1174     }
  1316     }
  1175   }
  1317   }
  1176 #endif
  1318 #endif
  1177 %}.
  1319 %}.
  1178     OperatingSystem getOSType = 'irix' ifFalse:[
  1320     OperatingSystem getOSType = 'irix' ifFalse:[
  1179 	^ super nextPutBytes:count from:anObject startingAt:start
  1321 	OperatingSystem getOSType = 'win32' ifFalse:[
       
  1322 	    ^ super nextPutBytes:count from:anObject startingAt:start
       
  1323 	].
  1180     ].
  1324     ].
  1181     filePointer isNil ifTrue:[^ self errorNotOpen].
  1325     filePointer isNil ifTrue:[^ self errorNotOpen].
  1182     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  1326     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  1183     self primitiveFailed
  1327     self primitiveFailed
  1184 !
  1328 !
  1190      (at least I dont know). Use with ByteArrays only."
  1334      (at least I dont know). Use with ByteArrays only."
  1191 
  1335 
  1192 %{
  1336 %{
  1193 #ifdef IRIS_AUDIO
  1337 #ifdef IRIS_AUDIO
  1194   {
  1338   {
       
  1339     OBJ port;
  1195     ALport p;
  1340     ALport p;
  1196     int cnt, offs;
  1341     int cnt, offs, nSamp;
  1197     int objSize;
  1342     int objSize;
  1198     char *cp;
  1343     char *cp;
  1199 
  1344 
  1200     if (__INST(filePointer) != nil) {
  1345     if ((port = __INST(alPort)) != nil) {
  1201 	if (__INST(mode) != @symbol(readonly)) {
  1346 	if (__INST(mode) != @symbol(readonly)) {
  1202 	    if (__bothSmallInteger(count, start)) {
  1347 	    if (__bothSmallInteger(count, start)) {
  1203 		cnt = _intVal(count);
  1348 		cnt = __intVal(count);
  1204 		offs = _intVal(start) - 1;
  1349 		offs = __intVal(start) - 1;
  1205 		p = _ALportVal(__INST(filePointer));
  1350 		p = __ALportVal(port);
  1206 
  1351 
  1207 		/*
  1352 		/*
  1208 		 * compute number of samples
  1353 		 * compute number of samples
  1209 		 */
  1354 		 */
  1210 		objSize = _Size(anObject) - OHDR_SIZE;
  1355 		objSize = _Size(anObject) - OHDR_SIZE;
  1211 		if ( (offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs)) ) {
  1356 		if ( (offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs)) ) {
  1212 		    cp = (char *)__InstPtr(anObject) + OHDR_SIZE + offs;
  1357 		    cp = (char *)__InstPtr(anObject) + OHDR_SIZE + offs;
  1213 		    if (__INST(bitsPerSample) == __MKSMALLINT(16))
  1358 		    if (__INST(bitsPerSample) == __MKSMALLINT(16))
  1214 			ALwritesamps(p, cp, cnt / 2);
  1359 			nSamp = cnt / 2;
  1215 		    else
  1360 		    else
  1216 			ALwritesamps(p, cp, cnt);
  1361 			nSamp = cnt;
       
  1362 		    ALwritesamps(p, cp, cnt);
  1217 		    RETURN ( count );
  1363 		    RETURN ( count );
  1218 		}
  1364 		}
  1219 	    }
  1365 	    }
  1220 	}
  1366 	}
  1221     }
  1367     }
  1222   }
  1368   }
  1223 #endif
  1369 #endif /* SGI_AUDIO */
       
  1370 
       
  1371 #ifdef WIN32
       
  1372   {
       
  1373       HRESULT hr;
       
  1374       DWORD status;
       
  1375       LPVOID lpbuf1 = NULL;
       
  1376       LPVOID lpbuf2 = NULL;
       
  1377       DWORD dwsize1 = 0;
       
  1378       DWORD dwsize2 = 0;
       
  1379       DWORD playPos, safePos, endWrite;
       
  1380       DWORD millis;
       
  1381       OBJ oDirectSound, oDSBuffer;
       
  1382       LPDIRECTSOUND       t_pDirectSound = (LPDIRECTSOUND)0;
       
  1383       LPDIRECTSOUNDBUFFER t_pDSBuffer = (LPDIRECTSOUNDBUFFER)0;
       
  1384       int t_cbBufOffset, t_cbBufSize;
       
  1385       short *buf;
       
  1386       int cnt, offs;
       
  1387 
       
  1388       if ((oDSBuffer = __INST(pDSBuffer)) != nil) {
       
  1389 	  t_pDSBuffer = __DSBufferVal(oDSBuffer);
       
  1390       }
       
  1391       if ((oDirectSound = __INST(pDirectSound)) != nil) {
       
  1392 	  t_pDirectSound = __DirectSoundVal(oDirectSound);
       
  1393       }
       
  1394 
       
  1395       if (!t_pDSBuffer || !t_pDirectSound) {
       
  1396 	  RETURN (0);
       
  1397       }
       
  1398       t_cbBufOffset = __intVal(__INST(cbBufOffset));
       
  1399       t_cbBufSize = __intVal(__INST(cbBufSize));
       
  1400 
       
  1401       cnt = __intVal(count);
       
  1402       offs = __intVal(start) - 1;
       
  1403       buf = (short *)__InstPtr(anObject) + OHDR_SIZE + offs;
       
  1404 
       
  1405       // Should be playing, right?
       
  1406       hr = IDirectSoundBuffer_GetStatus(t_pDSBuffer, &status );
       
  1407       if (!(status && DSBSTATUS_PLAYING)) {
       
  1408 	  printf("Buffer not playing!\n");
       
  1409       }
       
  1410 
       
  1411       // Sleep until we have enough room in buffer.
       
  1412       hr = IDirectSoundBuffer_GetCurrentPosition(t_pDSBuffer, &playPos, &safePos );
       
  1413       if( hr != DS_OK ) {
       
  1414 	  RETURN (0);
       
  1415       }
       
  1416       if( playPos < t_cbBufOffset ) playPos += t_cbBufSize; 
       
  1417 
       
  1418       endWrite = t_cbBufOffset + RT_BUFFER_SIZE * sizeof(short);
       
  1419       while ( playPos < endWrite ) {
       
  1420 	  // Calculate number of milliseconds until we will have room, as
       
  1421 	  // time = distance * (milliseconds/second) / ((bytes/sample) * (samples/second)),
       
  1422 	  // rounded up.
       
  1423 	  millis = (DWORD) (1.0 + ((endWrite - playPos) * 1000.0) / ( sizeof(short) * __intVal(__INST(sampleRate))));
       
  1424 
       
  1425 	  // Sleep for that long
       
  1426 	  Sleep( millis );
       
  1427 
       
  1428 	  // Wake up, find out where we are now
       
  1429 	  hr = IDirectSoundBuffer_GetCurrentPosition(t_pDSBuffer, &playPos, &safePos );
       
  1430 	  if( hr != DS_OK ) {
       
  1431 	      RETURN (0);
       
  1432 	  }
       
  1433 	  if( playPos < t_cbBufOffset ) playPos += t_cbBufSize; // unwrap offset
       
  1434       }
       
  1435 
       
  1436       // Lock free space in the DS
       
  1437       hr = IDirectSoundBuffer_Lock(t_pDSBuffer, t_cbBufOffset, RT_BUFFER_SIZE * sizeof(short), &lpbuf1, &dwsize1, &lpbuf2, &dwsize2, 0);
       
  1438       if (hr == DS_OK) {
       
  1439 	  // Copy the buffer into the DS
       
  1440 	  CopyMemory(lpbuf1, buf, dwsize1);
       
  1441 	  if(NULL != lpbuf2) CopyMemory(lpbuf2, buf+dwsize1, dwsize2);
       
  1442 
       
  1443 	  // Update our buffer offset and unlock sound buffer
       
  1444 	  t_cbBufOffset = (t_cbBufOffset + dwsize1 + dwsize2) % t_cbBufSize;
       
  1445 	  IDirectSoundBuffer_Unlock(t_pDSBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);
       
  1446       }
       
  1447       __INST(cbBufOffset) = __MKSMALLINT(t_cbBufOffset);
       
  1448 
       
  1449       RETURN (0);
       
  1450   }
       
  1451 #endif /* WIN32 */
  1224 
  1452 
  1225 #if defined(DEV_AUDIO)
  1453 #if defined(DEV_AUDIO)
  1226    /*
  1454    /*
  1227     * redefine to work around a bug in the linux sound driver;
  1455     * redefine to work around a bug in the linux sound driver;
  1228     * if a write is interrupted (EINTR), it is not defined, how many
  1456     * if a write is interrupted (EINTR), it is not defined, how many
  1241 
  1469 
  1242     if ((fp = __INST(filePointer)) != nil) {
  1470     if ((fp = __INST(filePointer)) != nil) {
  1243 	f = __FILEVal(fp);
  1471 	f = __FILEVal(fp);
  1244 	if (__INST(mode) != @symbol(readonly)) {
  1472 	if (__INST(mode) != @symbol(readonly)) {
  1245 	    if (__bothSmallInteger(count, start)) {
  1473 	    if (__bothSmallInteger(count, start)) {
  1246 		cnt = _intVal(count);
  1474 		cnt = __intVal(count);
  1247 		offs = _intVal(start) - 1;
  1475 		offs = __intVal(start) - 1;
  1248 
  1476 
  1249 		objSize = _Size(anObject) - OHDR_SIZE;
  1477 		objSize = _Size(anObject) - OHDR_SIZE;
  1250 		if ( (offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs)) ) {
  1478 		if ( (offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs)) ) {
  1251 		    do {
  1479 		    do {
  1252 		        cp = (char *)__InstPtr(anObject) + OHDR_SIZE + offs;
  1480 			cp = (char *)__InstPtr(anObject) + OHDR_SIZE + offs;
  1253 
  1481 
  1254 			n = cnt;
  1482 			n = cnt;
  1255 			if (n > 4096) n = 4096;
  1483 			if (n > 4096) n = 4096;
  1256 # ifdef LINUX
  1484 # ifdef LINUX
  1257 		        sigsetmask(~0);
  1485 			sigsetmask(~0);
  1258 # endif
  1486 # endif
  1259 			if (__INST(buffered) == true) {
  1487 			if (__INST(buffered) == true) {
  1260 			    n = fwrite(cp, 1, n, f);
  1488 			    n = fwrite(cp, 1, n, f);
  1261 			} else {
  1489 			} else {
  1262 			    fd = fileno(f);
  1490 			    fd = fileno(f);
  1263 			    n = write(fd, cp, n);
  1491 			    n = write(fd, cp, n);
  1264 			}
  1492 			}
  1265 # ifdef LINUX
  1493 # ifdef LINUX
  1266 		        sigsetmask(0);
  1494 			sigsetmask(0);
  1267 # endif
  1495 # endif
  1268 			__BEGIN_INTERRUPTABLE__
  1496 			__BEGIN_INTERRUPTABLE__
  1269 			__END_INTERRUPTABLE__
  1497 			__END_INTERRUPTABLE__
  1270 			if (n > 0) {
  1498 			if (n > 0) {
  1271 			    offs += n;
  1499 			    offs += n;
  1281 
  1509 
  1282 %}.
  1510 %}.
  1283     ^ super nextPutBytes:count from:anObject startingAt:start
  1511     ^ super nextPutBytes:count from:anObject startingAt:start
  1284 !
  1512 !
  1285 
  1513 
       
  1514 openForReading
       
  1515     |rslt|
       
  1516 
       
  1517     mode := #readonly.
       
  1518     didWrite := false.
       
  1519     (rslt :=  self openWithMode:ReadMode) notNil ifTrue:[
       
  1520 	Lobby register:self
       
  1521     ].
       
  1522     ^ rslt
       
  1523 !
       
  1524 
  1286 openForWriting
  1525 openForWriting
  1287     "open the file writeonly.
  1526     "open the file writeonly.
  1288      If the file does not exist its an error, return nil; 
  1527      If the file does not exist its an error, return nil; 
  1289      otherwise return the receiver."
  1528      otherwise return the receiver."
  1290 
  1529 
       
  1530     |rslt|
       
  1531 
  1291     mode := #writeonly.
  1532     mode := #writeonly.
  1292     didWrite := true.
  1533     didWrite := true.
  1293     ^ self openWithMode:WriteMode
  1534     (rslt := self openWithMode:WriteMode) notNil ifTrue:[
       
  1535 	Lobby register:self
       
  1536     ].
       
  1537     ^ rslt
  1294 
  1538 
  1295     "Created: / 15.12.1997 / 13:13:56 / cg"
  1539     "Created: / 15.12.1997 / 13:13:56 / cg"
  1296 !
  1540 !
  1297 
  1541 
  1298 openWithMode:aMode
  1542 openWithMode:aMode
  1299     ((aMode = 'r') or:[aMode = 'w']) ifFalse:[
       
  1300 	self error:'invalid mode'.
       
  1301 	^ nil
       
  1302     ].
       
  1303 %{
  1543 %{
  1304 #ifdef IRIS_AUDIO
  1544 #ifdef IRIS_AUDIO
  1305   {
  1545   {
  1306     ALconfig config;
  1546     ALconfig config;
  1307     ALport p;
  1547     ALport p;
  1320 	ALsetwidth(config, AL_SAMPLE_16);
  1560 	ALsetwidth(config, AL_SAMPLE_16);
  1321     else
  1561     else
  1322 	ALsetwidth(config, AL_SAMPLE_8);
  1562 	ALsetwidth(config, AL_SAMPLE_8);
  1323 
  1563 
  1324     if (__isSmallInteger(__INST(sampleRate)))
  1564     if (__isSmallInteger(__INST(sampleRate)))
  1325 	params[3] = params[5] = _intVal(__INST(sampleRate));
  1565 	params[3] = params[5] = __intVal(__INST(sampleRate));
  1326 
  1566 
  1327     ALsetparams(AL_DEFAULT_DEVICE, params, 6);
  1567     ALsetparams(AL_DEFAULT_DEVICE, params, 6);
  1328     p = ALopenport("smallchat", (char *)_stringVal(aMode), config);
  1568     p = ALopenport("smallchat", (char *)_stringVal(aMode), config);
  1329     if (p) {
  1569     if (p) {
  1330 	__INST(filePointer) = __MKEXTERNALADDRESS(p);
  1570 	OBJ t;
       
  1571 
       
  1572 	__INST(alPort) = t = __MKEXTERNALADDRESS(p); __STORE(self, t);
  1331     } else {
  1573     } else {
  1332 	__INST(filePointer) = nil;
  1574 	__INST(alPort) = nil;
  1333 	RETURN (nil);
  1575 	RETURN (nil);
  1334     }
  1576     }
  1335     __INST(binary) = true;
  1577     __INST(binary) = true;
  1336 
  1578 
  1337     ALfreeconfig(config);
  1579     ALfreeconfig(config);
  1366     __INST(sampleRate) = __MKSMALLINT(params[3]);
  1608     __INST(sampleRate) = __MKSMALLINT(params[3]);
  1367 
  1609 
  1368     ALfreeconfig(config);
  1610     ALfreeconfig(config);
  1369     RETURN (self);
  1611     RETURN (self);
  1370   }
  1612   }
  1371 #endif
  1613 #endif /* SGI_AUDIO */
       
  1614 
       
  1615 #ifdef WIN32
       
  1616   {
       
  1617     HRESULT result;
       
  1618     LPDIRECTSOUND       t_pDirectSound;
       
  1619     LPDIRECTSOUNDBUFFER t_pDSBuffer, t_pDSPrimeBuffer;
       
  1620     WAVEFORMATEX        wfFormat;
       
  1621     DSBUFFERDESC        dsbdDesc, primarydsbDesc;
       
  1622     BYTE                *pDSBuffData;
       
  1623     int                 t_cbBufSize;
       
  1624     int                 dwDataLen;
       
  1625 
       
  1626     /* Create the DS object */
       
  1627     if ((result = DirectSoundCreate(NULL, &t_pDirectSound, NULL)) != DS_OK) {
       
  1628 	fprintf(stderr,"SoundStream: Cannot open default sound device!!\n");
       
  1629 	RETURN (nil);
       
  1630     }
       
  1631 
       
  1632     /* Define the wave format structure */
       
  1633     wfFormat.wFormatTag = WAVE_FORMAT_PCM;
       
  1634     wfFormat.nChannels = __intVal(__INST(numberOfChannels));
       
  1635     wfFormat.nSamplesPerSec = __intVal(__INST(sampleRate));
       
  1636     wfFormat.wBitsPerSample = __intVal(__INST(bitsPerSample));
       
  1637     wfFormat.nBlockAlign = wfFormat.nChannels * wfFormat.wBitsPerSample / 8;
       
  1638     wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;
       
  1639     wfFormat.cbSize = 0;
       
  1640 #if 0
       
  1641     /* Setup the primary DS buffer description */
       
  1642     ZeroMemory(&primarydsbDesc, sizeof(DSBUFFERDESC));
       
  1643     primarydsbDesc.dwSize = sizeof(DSBUFFERDESC);
       
  1644     primarydsbDesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
       
  1645     primarydsbDesc.dwBufferBytes = 0;
       
  1646     primarydsbDesc.lpwfxFormat = NULL;
       
  1647 
       
  1648     /* Create the primary DS buffer */
       
  1649     if ((result = IDirectSound_CreateSoundBuffer(t_pDirectSound, &primarydsbDesc,
       
  1650 						 &t_pDSPrimeBuffer, NULL)) != DS_OK) {
       
  1651 	fprintf(stderr,"SoundStream: Cannot get the primary DS buffer address!\n");
       
  1652 	IDirectSound_Release(t_pDirectSound);
       
  1653 	RETURN (nil);
       
  1654     }
       
  1655 
       
  1656     /* Set the primary DS buffer sound format.  We have to do this because
       
  1657        the default primary buffer is 8-bit, 22kHz! */
       
  1658     if ((result = IDirectSoundBuffer_SetFormat(t_pDSPrimeBuffer, &wfFormat)) != DS_OK) {
       
  1659 	fprintf(stderr,"SoundStream: Cannot set the primary DS buffer to proper sound format (%x) (%d)!\n", result, result);
       
  1660 	IDirectSoundBuffer_Stop(t_pDSPrimeBuffer);
       
  1661 	IDirectSoundBuffer_Release(t_pDSPrimeBuffer);
       
  1662 	IDirectSound_Release(t_pDirectSound);
       
  1663 	RETURN (nil);
       
  1664     }
       
  1665 #endif
       
  1666 
       
  1667     /* Setup the secondary DS buffer description */
       
  1668     t_cbBufSize = RT_BUFFER_SIZE * sizeof(short) * NBUFS;
       
  1669     __INST(cbBufSize) = __MKSMALLINT(t_cbBufSize);
       
  1670 
       
  1671     ZeroMemory(&dsbdDesc, sizeof(DSBUFFERDESC));
       
  1672     dsbdDesc.dwSize = sizeof(DSBUFFERDESC);
       
  1673     dsbdDesc.dwFlags = DSBCAPS_GLOBALFOCUS;
       
  1674     dsbdDesc.dwBufferBytes = t_cbBufSize;
       
  1675     dsbdDesc.lpwfxFormat = &wfFormat;
       
  1676 
       
  1677     /* Create the secondary DS buffer */
       
  1678     if ((result = IDirectSound_CreateSoundBuffer(t_pDirectSound, &dsbdDesc, &t_pDSBuffer, NULL)) != DS_OK) {
       
  1679 	fprintf(stderr,"SoundStream: couldn't create sound buffer!\n");
       
  1680 	IDirectSoundBuffer_Stop(t_pDSPrimeBuffer);
       
  1681 	IDirectSoundBuffer_Release(t_pDSPrimeBuffer);
       
  1682 	IDirectSound_Release(t_pDirectSound);
       
  1683 	RETURN (nil);
       
  1684     }
       
  1685 
       
  1686     /* Lock the DS buffer */
       
  1687     if ((result = IDirectSoundBuffer_Lock(t_pDSBuffer, 0, t_cbBufSize, (LPLPVOID)&pDSBuffData,
       
  1688 					  &dwDataLen, NULL, NULL, 0)) != DS_OK) {
       
  1689 	fprintf(stderr,"SoundStream: couldn't lock sound buffer!\n");
       
  1690 	IDirectSoundBuffer_Stop(t_pDSBuffer);
       
  1691 	IDirectSoundBuffer_Stop(t_pDSPrimeBuffer);
       
  1692 	IDirectSoundBuffer_Release(t_pDSPrimeBuffer);
       
  1693 	IDirectSound_Release(t_pDirectSound);
       
  1694 	RETURN (nil);
       
  1695     }
       
  1696 
       
  1697     /* Zero the DS buffer */
       
  1698     ZeroMemory(pDSBuffData, dwDataLen);
       
  1699 
       
  1700     /* Unlock the DS buffer */
       
  1701     if ((result = IDirectSoundBuffer_Unlock(t_pDSBuffer, pDSBuffData, dwDataLen, NULL, 0)) != DS_OK) {
       
  1702 	fprintf(stderr,"SoundStream: couldn't unlock sound buffer!\n");
       
  1703 	IDirectSoundBuffer_Stop(t_pDSBuffer);
       
  1704 	IDirectSoundBuffer_Stop(t_pDSPrimeBuffer);
       
  1705 	IDirectSoundBuffer_Release(t_pDSPrimeBuffer);
       
  1706 	IDirectSound_Release(t_pDirectSound);
       
  1707 	RETURN (nil);
       
  1708     }
       
  1709 
       
  1710     __INST(cbBufOffset) = __MKSMALLINT(0);  // reset last write position to start of buffer
       
  1711 
       
  1712     /* Start the buffer playback */
       
  1713     if ((result = IDirectSoundBuffer_Play(t_pDSBuffer, 0, 0, DSBPLAY_LOOPING ) != DS_OK)) {
       
  1714 	fprintf(stderr,"SoundStream: couldn't play sound buffer!\n");
       
  1715 	IDirectSoundBuffer_Stop(t_pDSBuffer);
       
  1716 	IDirectSoundBuffer_Stop(t_pDSPrimeBuffer);
       
  1717 	IDirectSoundBuffer_Release(t_pDSPrimeBuffer);
       
  1718 	IDirectSound_Release(t_pDirectSound);
       
  1719 	RETURN (nil);
       
  1720     }
       
  1721 
       
  1722     {
       
  1723 	OBJ t;
       
  1724 
       
  1725 	__INST(pDSBuffer) = t = __MKEXTERNALADDRESS(t_pDSBuffer); __STORE(self, t);
       
  1726 	__INST(pDirectSound) = t = __MKEXTERNALADDRESS(t_pDirectSound); __STORE(self, t);
       
  1727     }
       
  1728     RETURN (self);
       
  1729   }
       
  1730 #endif /* WIN32 */
       
  1731 
  1372 %}.
  1732 %}.
  1373     "its a regular file open (i.e. /dev/audio) "
  1733     "its a regular file open (i.e. /dev/audio) "
  1374     ^ super openWithMode:aMode
  1734     ^ super openWithMode:aMode
  1375 ! !
  1735 ! !
  1376 
  1736 
  1403 
  1763 
  1404     "fill it with a sine wave"
  1764     "fill it with a sine wave"
  1405 
  1765 
  1406     scale := freq * 2 * (Float pi).
  1766     scale := freq * 2 * (Float pi).
  1407     1 to:numSamples do:[:i |
  1767     1 to:numSamples do:[:i |
  1408         val := (scale * i / numSamples) sin.
  1768 	val := (scale * i / numSamples) sin.
  1409         val := (val * 16r7FFF) rounded bitAnd:16rFFFF.
  1769 	val := (val * 16r7FFF) rounded bitAnd:16rFFFF.
  1410         buffer at:i put:val
  1770 	buffer at:i put:val
  1411     ].
  1771     ].
  1412 
  1772 
  1413     oldFormat := audioFormat.
  1773     oldFormat := audioFormat.
  1414     self setAudioFormat:#S16.
  1774     self setAudioFormat:#S16.
  1415     1 to:3 do:[:s |
  1775     1 to:3 do:[:s |
  1416         self nextPutBytes:(numSamples*2) from:buffer startingAt:1
  1776 	self nextPutBytes:(numSamples*2) from:buffer startingAt:1
  1417     ].
  1777     ].
  1418     self setAudioFormat:oldFormat.
  1778     self setAudioFormat:oldFormat.
  1419 
  1779 
  1420     "of course, the frequency should be below half the
  1780     "of course, the frequency should be below half the
  1421      sampleRate - hear below ...
  1781      sampleRate - hear below ...
  1441 
  1801 
  1442     "fill it with a sine wave"
  1802     "fill it with a sine wave"
  1443 
  1803 
  1444     scale := freq * 2 * (Float pi).
  1804     scale := freq * 2 * (Float pi).
  1445     1 to:numSamples do:[:i |
  1805     1 to:numSamples do:[:i |
  1446         val := (scale * i / numSamples) sin.
  1806 	val := (scale * i / numSamples) sin.
  1447         val := (val * 127 + 128) rounded.
  1807 	val := (val * 127 + 128) rounded.
  1448         buffer at:i put:val
  1808 	buffer at:i put:val
  1449     ].
  1809     ].
  1450 
  1810 
  1451     oldFormat := audioFormat.
  1811     oldFormat := audioFormat.
  1452     self setAudioFormat:#U8.
  1812     self setAudioFormat:#U8.
  1453     1 to:3 do:[:s |
  1813     1 to:3 do:[:s |
  1454         self nextPutBytes:numSamples from:buffer startingAt:1
  1814 	self nextPutBytes:numSamples from:buffer startingAt:1
  1455     ].
  1815     ].
  1456     self setAudioFormat:oldFormat.
  1816     self setAudioFormat:oldFormat.
  1457 
  1817 
  1458     "of course, the frequency should be below half the
  1818     "of course, the frequency should be below half the
  1459      sampleRate - hear below ...
  1819      sampleRate - hear below ...
  1492 
  1852 
  1493     "fill it with a sine wave"
  1853     "fill it with a sine wave"
  1494 
  1854 
  1495     scale := freq * 2 * (Float pi).
  1855     scale := freq * 2 * (Float pi).
  1496     1 to:numSamples do:[:i |
  1856     1 to:numSamples do:[:i |
  1497         val := (scale * i / numSamples) sin.
  1857 	val := (scale * i / numSamples) sin.
  1498         val := (val * 16r7FFF) rounded.
  1858 	val := (val * 16r7FFF) rounded.
  1499         buffer at:i put:(self class linear16ToUlaw:val)
  1859 	buffer at:i put:(self class linear16ToUlaw:val)
  1500     ].
  1860     ].
  1501 
  1861 
  1502     oldFormat := audioFormat.
  1862     oldFormat := audioFormat.
  1503     self setAudioFormat:#MU_LAW.
  1863     self setAudioFormat:#MU_LAW.
  1504     1 to:3 do:[:s |
  1864     1 to:3 do:[:s |
  1505         self nextPutBytes:numSamples from:buffer startingAt:1
  1865 	self nextPutBytes:numSamples from:buffer startingAt:1
  1506     ].
  1866     ].
  1507     self setAudioFormat:oldFormat.
  1867     self setAudioFormat:oldFormat.
  1508 
  1868 
  1509     "of course, the frequency should be below half the
  1869     "of course, the frequency should be below half the
  1510      sampleRate - hear below ...
  1870      sampleRate - hear below ...
  1519 ! !
  1879 ! !
  1520 
  1880 
  1521 !SoundStream class methodsFor:'documentation'!
  1881 !SoundStream class methodsFor:'documentation'!
  1522 
  1882 
  1523 version
  1883 version
  1524 ^ '$Header: /cvs/stx/stx/libbasic2/Attic/SoundStr.st,v 1.33 1998-02-08 00:45:12 cg Exp $'! !
  1884 ^ '$Header: /cvs/stx/stx/libbasic2/Attic/SoundStr.st,v 1.34 1998-12-21 11:43:58 cg Exp $'! !
  1525 SoundStream initialize!
  1885 SoundStream initialize!