SoundStream.st
changeset 594 0d62900b49c8
parent 593 719f9d1c7bbb
child 595 fcff6c911d4a
equal deleted inserted replaced
593:719f9d1c7bbb 594:0d62900b49c8
    29 # include <audio.h>
    29 # include <audio.h>
    30 # define _ALportVal(o)  (ALport)(__externalAddressVal(o))
    30 # define _ALportVal(o)  (ALport)(__externalAddressVal(o))
    31 #endif
    31 #endif
    32 
    32 
    33 #ifdef LINUX
    33 #ifdef LINUX
       
    34 # define DEV_AUDIO
       
    35 # include <sys/soundcard.h>
       
    36 #endif
       
    37 
       
    38 #if defined(sunos) || defined(solaris)
       
    39 # define DEV_AUDIO
       
    40 #endif
       
    41 
       
    42 #ifdef DEV_AUDIO
    34 # include <stdio.h>
    43 # include <stdio.h>
    35 # include <sys/soundcard.h>
       
    36 #endif
    44 #endif
    37 %}
    45 %}
    38 ! !
    46 ! !
    39 
    47 
    40 !SoundStream class methodsFor:'documentation'!
    48 !SoundStream class methodsFor:'documentation'!
   574     int __blockSize = -1;
   582     int __blockSize = -1;
   575     int __speed = 0;
   583     int __speed = 0;
   576     int __stereo = 0;
   584     int __stereo = 0;
   577     int __channels = 0;
   585     int __channels = 0;
   578 
   586 
   579 #ifdef LINUX
   587 #if defined(DEV_AUDIO) 
       
   588 # if defined(LINUX)
   580     if (ioctl(f, SNDCTL_DSP_GETBLKSIZE, &__blockSize) >= 0) {
   589     if (ioctl(f, SNDCTL_DSP_GETBLKSIZE, &__blockSize) >= 0) {
   581 	blockSize = __MKSMALLINT(__blockSize);
   590 	blockSize = __MKSMALLINT(__blockSize);
   582     }
   591     }
   583     if (ioctl(f, SNDCTL_DSP_CHANNELS, &__channels) >= 0) {
   592     if (ioctl(f, SNDCTL_DSP_CHANNELS, &__channels) >= 0) {
   584 	channels = __MKSMALLINT(__channels);
   593 	channels = __MKSMALLINT(__channels);
   590 	speed = __MKSMALLINT(__speed);
   599 	speed = __MKSMALLINT(__speed);
   591     }
   600     }
   592     if (ioctl(f, SNDCTL_DSP_GETFMTS, &__audioFormatMask) >= 0) {
   601     if (ioctl(f, SNDCTL_DSP_GETFMTS, &__audioFormatMask) >= 0) {
   593 	audioFormatMask = __MKSMALLINT(__audioFormatMask);
   602 	audioFormatMask = __MKSMALLINT(__audioFormatMask);
   594     }
   603     }
   595 
   604 # endif /* LINUX */
   596 #endif
   605 #endif /* DEV_AUDIO */
   597 %}.
   606 %}.
   598     blockSize notNil ifTrue:[
   607     blockSize notNil ifTrue:[
   599 	Transcript show:'blockSize: '; showCR:blockSize
   608 	Transcript show:'blockSize: '; showCR:blockSize
   600     ].
   609     ].
   601     speed notNil ifTrue:[
   610     speed notNil ifTrue:[
   651     ].
   660     ].
   652 %{
   661 %{
   653     int f = __intVal(fd);
   662     int f = __intVal(fd);
   654     int __audioFormatMask = 0;
   663     int __audioFormatMask = 0;
   655 
   664 
   656 #ifdef LINUX
   665 #if defined(DEV_AUDIO)
       
   666 # if defined(LINUX)
   657     if (ioctl(f, SNDCTL_DSP_GETFMTS, &__audioFormatMask) >= 0) {
   667     if (ioctl(f, SNDCTL_DSP_GETFMTS, &__audioFormatMask) >= 0) {
   658 	audioFormatMask = __MKSMALLINT(__audioFormatMask);
   668 	audioFormatMask = __MKSMALLINT(__audioFormatMask);
   659 
   669 
   660 	supports_MU_LAW = (__audioFormatMask & AFMT_MU_LAW) ? true : false;
   670 	supports_MU_LAW = (__audioFormatMask & AFMT_MU_LAW) ? true : false;
   661 	supports_A_LAW = (__audioFormatMask & AFMT_A_LAW) ? true : false;
   671 	supports_A_LAW = (__audioFormatMask & AFMT_A_LAW) ? true : false;
   666 	supports_S8 = (__audioFormatMask & AFMT_S8) ? true : false;
   676 	supports_S8 = (__audioFormatMask & AFMT_S8) ? true : false;
   667 	supports_U16_LE = (__audioFormatMask & AFMT_U16_LE) ? true : false;
   677 	supports_U16_LE = (__audioFormatMask & AFMT_U16_LE) ? true : false;
   668 	supports_U16_BE = (__audioFormatMask & AFMT_U16_BE) ? true : false;
   678 	supports_U16_BE = (__audioFormatMask & AFMT_U16_BE) ? true : false;
   669 	supports_MPEG = (__audioFormatMask & AFMT_MPEG) ? true : false;
   679 	supports_MPEG = (__audioFormatMask & AFMT_MPEG) ? true : false;
   670     }
   680     }
   671 #endif
   681 # endif
       
   682 #endif /* DEV_AUDIO */
       
   683 
   672 #ifdef IRIS_AUDIO
   684 #ifdef IRIS_AUDIO
   673 	supports_U8 = true;
   685 	supports_U8 = true;
   674 	supports_U16_BE = true;
   686 	supports_U16_BE = true;
   675 #endif
   687 #endif
   676 
   688 
   736     ].
   748     ].
   737 %{
   749 %{
   738     int f = __intVal(fd);
   750     int f = __intVal(fd);
   739     int __dummy;
   751     int __dummy;
   740 
   752 
   741 #ifdef LINUX
   753 #if defined(DEV_AUDIO) && defined(LINUX)
   742     if (ioctl(f, SNDCTL_DSP_RESET, &__dummy) >= 0) {
   754     if (ioctl(f, SNDCTL_DSP_RESET, &__dummy) >= 0) {
   743 	RETURN (true);
   755 	RETURN (true);
   744     }
   756     }
   745 #endif
   757 #endif
   746 %}.
   758 %}.
   768     union {
   780     union {
   769 	unsigned short us;
   781 	unsigned short us;
   770 	unsigned char ub[2];
   782 	unsigned char ub[2];
   771     } u;
   783     } u;
   772 
   784 
   773 #ifdef LINUX
   785 #if defined(DEV_AUDIO) && defined(LINUX)
   774     if (__isSymbol(aSymbol)) {
   786     if (__isSymbol(aSymbol)) {
   775 
   787 
   776 	if (aSymbol == @symbol(U16)) {
   788 	if (aSymbol == @symbol(U16)) {
   777 	    u.us = 0x1234;
   789 	    u.us = 0x1234;
   778 	    if (u.ub[0] == 0x12) {
   790 	    if (u.ub[0] == 0x12) {
   841     ].
   853     ].
   842 %{
   854 %{
   843     int f = __intVal(fd);
   855     int f = __intVal(fd);
   844     int __nCh = 0;
   856     int __nCh = 0;
   845 
   857 
   846 #ifdef LINUX
   858 #if defined(DEV_AUDIO) && defined(LINUX)
   847     if (__isSmallInteger(nChannels)) {
   859     if (__isSmallInteger(nChannels)) {
   848 	__nCh = __intVal(nChannels);
   860 	__nCh = __intVal(nChannels);
   849 	if (ioctl(f, SOUND_PCM_WRITE_CHANNELS, &__nCh) >= 0) {
   861 	if (ioctl(f, SOUND_PCM_WRITE_CHANNELS, &__nCh) >= 0) {
   850 	    __INST(numberOfChannels) = nChannels;
   862 	    __INST(numberOfChannels) = nChannels;
   851 	    RETURN (true);
   863 	    RETURN (true);
   876     ].
   888     ].
   877 %{
   889 %{
   878     int f = __intVal(fd);
   890     int f = __intVal(fd);
   879     int __blockSize = 0;
   891     int __blockSize = 0;
   880 
   892 
   881 #ifdef LINUX
   893 #if defined(DEV_AUDIO) && defined(LINUX)
   882     if (__isSmallInteger(blockSize)) {
   894     if (__isSmallInteger(blockSize)) {
   883 	__blockSize = __intVal(blockSize);
   895 	__blockSize = __intVal(blockSize);
   884 	if (ioctl(f, SNDCTL_DSP_SETFRAGMENT, &__blockSize) >= 0) {
   896 	if (ioctl(f, SNDCTL_DSP_SETFRAGMENT, &__blockSize) >= 0) {
   885 	    /* __INST(blockSize) = blockSize; */
   897 	    /* __INST(blockSize) = blockSize; */
   886 	    RETURN (true);
   898 	    RETURN (true);
   906 %{
   918 %{
   907     int f = __intVal(fd);
   919     int f = __intVal(fd);
   908     int __rate = 0;
   920     int __rate = 0;
   909     int __rateWant;
   921     int __rateWant;
   910 
   922 
   911 #ifdef LINUX
   923 #if defined(DEV_AUDIO) && defined(LINUX)
   912     if (__isSmallInteger(hz)) {
   924     if (__isSmallInteger(hz)) {
   913 	__rate = __rateWant = __intVal(hz);
   925 	__rate = __rateWant = __intVal(hz);
   914 	if (ioctl(f, SOUND_PCM_WRITE_RATE, &__rate) >= 0) {
   926 	if (ioctl(f, SOUND_PCM_WRITE_RATE, &__rate) >= 0) {
   915 	    if (__rate != __rateWant) {
   927 	    if (__rate != __rateWant) {
   916 		fprintf(stderr, "SoundStream [warning]: actual rate is %d\n", __rate);
   928 		fprintf(stderr, "SoundStream [warning]: actual rate is %d\n", __rate);
  1024 !
  1036 !
  1025 
  1037 
  1026 closeFile
  1038 closeFile
  1027     "a stream has been collected - close the file"
  1039     "a stream has been collected - close the file"
  1028 
  1040 
  1029     OperatingSystem getOSType = 'irix' ifTrue:[
  1041 %{
  1030 %{ 
       
  1031 #ifdef IRIS_AUDIO
  1042 #ifdef IRIS_AUDIO
  1032 	ALcloseport(_ALportVal(__INST(filePointer)));
  1043     ALcloseport(_ALportVal(__INST(filePointer)));
  1033 #endif
  1044 #endif
       
  1045 #if defined(DEV_AUDIO)
       
  1046     OBJ fp;
       
  1047     int fd;
       
  1048     FILE *f;
       
  1049 
       
  1050     if ((fp = __INST(filePointer)) != nil) {
       
  1051 	f = __FILEVal(fp);
       
  1052 	__INST(filePointer) = nil;
       
  1053 # ifdef LINUX
       
  1054 	sigsetmask(~0);
       
  1055 # endif
       
  1056 	if (__INST(buffered) == true) {
       
  1057 	    fflush(f);
       
  1058 	    fclose(f);
       
  1059 	} else {
       
  1060 	    fd = fileno(f);
       
  1061 	    close(fd);
       
  1062 	    fclose(f);
       
  1063 	}
       
  1064 # ifdef LINUX
       
  1065 	sigsetmask(0);
       
  1066 # endif
       
  1067     }
       
  1068 #endif /* DEV_AUDIO */
  1034 %}
  1069 %}
  1035     ] ifFalse:[
       
  1036 %{
       
  1037 	OBJ fp;
       
  1038 	int fd;
       
  1039 	FILE *f;
       
  1040 
       
  1041 	if ((fp = __INST(filePointer)) != nil) {
       
  1042 	    f = __FILEVal(fp);
       
  1043 	    __INST(filePointer) = nil;
       
  1044 #ifdef LINUX
       
  1045 	    sigsetmask(~0);
       
  1046 #endif
       
  1047 	    if (__INST(buffered) == true) {
       
  1048 		fflush(f);
       
  1049 		fclose(f);
       
  1050 	    } else {
       
  1051 		fd = fileno(f);
       
  1052 		close(fd);
       
  1053 		fclose(f);
       
  1054 	    }
       
  1055 #ifdef LINUX
       
  1056 	    sigsetmask(0);
       
  1057 #endif
       
  1058 	}
       
  1059 %}
       
  1060     ]
       
  1061 !
  1070 !
  1062 
  1071 
  1063 flush
  1072 flush
  1064     "wait until all sound has been played"
  1073     "wait until all sound has been played"
  1065 
  1074 
  1077 	}
  1086 	}
  1078     }
  1087     }
  1079     RETURN(self);
  1088     RETURN(self);
  1080 #endif
  1089 #endif
  1081 
  1090 
  1082 #ifdef LINUX
  1091 #if defined(DEV_AUDIO) && defined(LINUX)
  1083     if (__isSmallInteger(fd)) {
  1092     if (__isSmallInteger(fd)) {
  1084 	int f = __intVal(fd);
  1093 	int f = __intVal(fd);
  1085 	/* ... */
  1094 	/* ... */
  1086     }
  1095     }
  1087 #endif
  1096 #endif
  1169 	}
  1178 	}
  1170     }
  1179     }
  1171   }
  1180   }
  1172 #endif
  1181 #endif
  1173 
  1182 
  1174 #ifdef LINUX
  1183 #if defined(DEV_AUDIO)
  1175    /*
  1184    /*
  1176     * redefine to work around a bug in the linux sound driver;
  1185     * redefine to work around a bug in the linux sound driver;
  1177     * if a write is interrupted (EINTR), it is not defined, how many
  1186     * if a write is interrupted (EINTR), it is not defined, how many
  1178     * bytes have been written to the device.
  1187     * bytes have been written to the device.
  1179     * I.e. a retry of the write may lead to ever-playing without ever
  1188     * I.e. a retry of the write may lead to ever-playing without ever
  1197 
  1206 
  1198 		objSize = _Size(anObject) - OHDR_SIZE;
  1207 		objSize = _Size(anObject) - OHDR_SIZE;
  1199 		if ( (offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs)) ) {
  1208 		if ( (offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs)) ) {
  1200 		    cp = (char *)__InstPtr(anObject) + OHDR_SIZE + offs;
  1209 		    cp = (char *)__InstPtr(anObject) + OHDR_SIZE + offs;
  1201 
  1210 
       
  1211 # ifdef LINUX
  1202 		    sigsetmask(~0);
  1212 		    sigsetmask(~0);
       
  1213 # endif
  1203 		    do {
  1214 		    do {
  1204 			n = cnt;
  1215 			n = cnt;
  1205 			if (n > 4096) n = 4096;
  1216 			if (n > 4096) n = 4096;
  1206 			if (__INST(buffered) == true) {
  1217 			if (__INST(buffered) == true) {
  1207 			    n = fwrite(cp, 1, n, f);
  1218 			    n = fwrite(cp, 1, n, f);
  1212 			if (n > 0) {
  1223 			if (n > 0) {
  1213 			    cp += n;
  1224 			    cp += n;
  1214 			    cnt -= n;
  1225 			    cnt -= n;
  1215 			}
  1226 			}
  1216 		    } while (cnt);
  1227 		    } while (cnt);
       
  1228 # ifdef LINUX
  1217 		    sigsetmask(0);
  1229 		    sigsetmask(0);
       
  1230 # endif
  1218 		}
  1231 		}
  1219 		RETURN (count);
  1232 		RETURN (count);
  1220 	    }
  1233 	    }
  1221 	}
  1234 	}
  1222     }
  1235     }
  1225 %}.
  1238 %}.
  1226     ^ super nextPutBytes:count from:anObject startingAt:start
  1239     ^ super nextPutBytes:count from:anObject startingAt:start
  1227 !
  1240 !
  1228 
  1241 
  1229 openWithMode:aMode
  1242 openWithMode:aMode
  1230     OperatingSystem getOSType = 'irix' ifFalse:[
       
  1231 	"its a regular file open"
       
  1232 	^ super openWithMode:aMode
       
  1233     ].
       
  1234 
       
  1235     ((aMode = 'r') or:[aMode = 'w']) ifFalse:[
  1243     ((aMode = 'r') or:[aMode = 'w']) ifFalse:[
  1236 	self error:'invalid mode'.
  1244 	self error:'invalid mode'.
  1237 	^ nil
  1245 	^ nil
  1238     ].
  1246     ].
  1239 %{
  1247 %{
  1300     }
  1308     }
  1301     ALgetparams(AL_DEFAULT_DEVICE, params, 6);
  1309     ALgetparams(AL_DEFAULT_DEVICE, params, 6);
  1302     __INST(sampleRate) = __MKSMALLINT(params[3]);
  1310     __INST(sampleRate) = __MKSMALLINT(params[3]);
  1303 
  1311 
  1304     ALfreeconfig(config);
  1312     ALfreeconfig(config);
       
  1313     RETURN (self);
  1305   }
  1314   }
  1306 #endif
  1315 #endif
  1307 %}.
  1316 %}.
  1308     ^ self
  1317     "its a regular file open (i.e. /dev/audio) "
       
  1318     ^ super openWithMode:aMode
  1309 ! !
  1319 ! !
  1310 
  1320 
  1311 !SoundStream methodsFor:'sine wave generation'!
  1321 !SoundStream methodsFor:'sine wave generation'!
  1312 
  1322 
  1313 tuneTone:freq
  1323 tuneTone:freq
  1376 ! !
  1386 ! !
  1377 
  1387 
  1378 !SoundStream class methodsFor:'documentation'!
  1388 !SoundStream class methodsFor:'documentation'!
  1379 
  1389 
  1380 version
  1390 version
  1381 ^ '$Header: /cvs/stx/stx/libbasic2/SoundStream.st,v 1.27 1997-12-15 10:35:37 cg Exp $'! !
  1391 ^ '$Header: /cvs/stx/stx/libbasic2/SoundStream.st,v 1.28 1997-12-15 10:54:20 cg Exp $'! !