Mercurial > forge
comparison main/audio/sound.m @ 0:6b33357c7561 octave-forge
Initial revision
author | pkienzle |
---|---|
date | Wed, 10 Oct 2001 19:54:49 +0000 |
parents | |
children | f442d0aca116 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:6b33357c7561 |
---|---|
1 ## Copyright (C) 1999-2000 Paul Kienzle | |
2 ## | |
3 ## This program is free software; you can redistribute it and/or modify | |
4 ## it under the terms of the GNU General Public License as published by | |
5 ## the Free Software Foundation; either version 2 of the License, or | |
6 ## (at your option) any later version. | |
7 ## | |
8 ## This program is distributed in the hope that it will be useful, | |
9 ## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 ## GNU General Public License for more details. | |
12 ## | |
13 ## You should have received a copy of the GNU General Public License | |
14 ## along with this program; if not, write to the Free Software | |
15 ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
16 | |
17 ## usage: sound(x [, fs]) | |
18 ## | |
19 ## Play the signal through the speakers. Data is a matrix with | |
20 ## one column per channel. Rate fs defaults to 8000 Hz. The signal | |
21 ## is clipped to [-1, 1]. | |
22 ## | |
23 ## Note that if $DISPLAY != $HOSTNAME:n then a remote shell is opened | |
24 ## to the host specified in $HOSTNAME to play the audio. See manual | |
25 ## pages for rsh and .rhosts for your system to learn how to set it up. | |
26 ## | |
27 ## This function writes the audio data through a pipe to the program | |
28 ## "play" from the sox distribution. sox runs pretty much anywhere, | |
29 ## but it only has audio drivers for OSS (primarily linux and freebsd) | |
30 ## and SunOS. In case your local machine is not one of these, write | |
31 ## a shell script such as ~/bin/octaveplay, substituting AUDIO_UTILITY | |
32 ## with whatever audio utility you happen to have on your system: | |
33 ## #!/bin/sh | |
34 ## cat > ~/.octave_play.au | |
35 ## SYSTEM_AUDIO_UTILITY ~/.octave_play.au | |
36 ## rm -f ~/.octave_play.au | |
37 ## and set the global variable (e.g., in .octaverc) | |
38 ## global sound_play_utility="~/bin/octaveplay"; | |
39 ## | |
40 ## If your audio utility can accept an AU file via a pipe, then you | |
41 ## can use it directly: | |
42 ## global sound_play_utility="SYSTEM_AUDIO_UTILITY flags" | |
43 ## where flags are whatever you need to tell it that it is receiving | |
44 ## an AU file. | |
45 ## | |
46 ## With clever use of the command dd, you can chop out the header and | |
47 ## dump the data directly to the audio device in big-endian format: | |
48 ## global sound_play_utility="dd of=/dev/audio ibs=2 skip=12" | |
49 ## or little-endian format: | |
50 ## global sound_play_utility="dd of=/dev/dsp ibs=2 skip=12 conv=swab" | |
51 ## but you lose the sampling rate in the process. | |
52 ## | |
53 ## Finally, you could modify sound.m to produce data in a format that | |
54 ## you can dump directly to your audio device and use "cat >/dev/audio" | |
55 ## as your sound_play_utility. Things you may want to do are resample | |
56 ## so that the rate is appropriate for your machine and convert the data | |
57 ## to mulaw and output as bytes. | |
58 function sound(data, rate) | |
59 | |
60 if nargin<1 || nargin>2 | |
61 usage("sound(x [, fs])"); | |
62 endif | |
63 if nargin<2 || isempty(rate), rate = 8000; endif | |
64 if rows(data) != length(data), data=data'; endif | |
65 [samples, channels] = size(data); | |
66 | |
67 ## Check if the octave engine is running locally by seeing if the | |
68 ## DISPLAY environment variable is empty or if it is the same as the | |
69 ## host name of the machine running octave. The host name is | |
70 ## taken from the HOSTNAME environment variable if it is available, | |
71 ## otherwise it is taken from the "uname -n" command. | |
72 display=getenv("DISPLAY"); | |
73 colon = rindex(display,":"); | |
74 if isempty(display) || colon==1 | |
75 islocal = 1; | |
76 else | |
77 if colon, display = display(1:colon-1); endif | |
78 host=getenv("HOSTNAME"); | |
79 if isempty(host), | |
80 host = system("uname -n"); | |
81 # trim newline from end of hostname | |
82 if !isempty(host), host = host(1:length(host)-1); endif | |
83 endif | |
84 islocal = strcmp(tolower(host),tolower(display)); | |
85 endif | |
86 | |
87 ## If not running locally, then must use rsh to execute play command | |
88 global sound_play_utility="play -t AU -"; | |
89 if islocal | |
90 fid=popen(sound_play_utility, "w"); | |
91 else | |
92 fid=popen(["rsh ", host, " ", sound_play_utility], "w"); | |
93 end | |
94 if fid < 0, | |
95 warning("sound could not open play process"); | |
96 else | |
97 ## write sun .au format header to the pipe | |
98 fwrite(fid, toascii(".snd"), 'char'); | |
99 fwrite(fid, 24, 'long', 0, 'ieee-be'); | |
100 fwrite(fid, -1, 'long', 0, 'ieee-be'); | |
101 fwrite(fid, 3, 'long', 0, 'ieee-be'); | |
102 fwrite(fid, rate, 'long', 0, 'ieee-be'); | |
103 fwrite(fid, channels, 'long', 0, 'ieee-be'); | |
104 fwrite(fid, 32767*clip(data,[-1, 1])', 'short', 0, 'ieee-be'); | |
105 pclose(fid); | |
106 endif | |
107 end | |
108 | |
109 ###### auplay based version: not needed if using sox | |
110 ## ## If not running locally, then must use rsh to execute play command | |
111 ## global sound_play_utility="~/bin/auplay" | |
112 ## if islocal | |
113 ## fid=popen(sound_play_utility, "w"); | |
114 ## else | |
115 ## fid=popen(["rsh ", host, " ", sound_play_utility], "w"); | |
116 ## end | |
117 ## fwrite(fid, rate, 'long'); | |
118 ## fwrite(fid, channels, 'long'); | |
119 ## fwrite(fid, 32767*clip(data,[-1, 1])', 'short'); | |
120 ## pclose(fid); | |
121 | |
122 %!demo | |
123 %! [x, fs] = auload(file_in_loadpath("sample.wav")); | |
124 %! sound(x,fs); |