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) |
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 } |
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:[ |
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; |
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 ... |