X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?p=CreaPhase.git;a=blobdiff_plain;f=octave_packages%2Faudio-1.1.4%2Fsound.m;fp=octave_packages%2Faudio-1.1.4%2Fsound.m;h=760689c1d324fbfbef1b1f174293eba6c2256389;hp=0000000000000000000000000000000000000000;hb=f5f7a74bd8a4900f0b797da6783be80e11a68d86;hpb=1705066eceaaea976f010f669ce8e972f3734b05 diff --git a/octave_packages/audio-1.1.4/sound.m b/octave_packages/audio-1.1.4/sound.m new file mode 100644 index 0000000..760689c --- /dev/null +++ b/octave_packages/audio-1.1.4/sound.m @@ -0,0 +1,159 @@ +## Copyright (C) 1999-2000 Paul Kienzle +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; If not, see . + +## usage: sound(x [, fs, bs]) +## +## Play the signal through the speakers. Data is a matrix with +## one column per channel. Rate fs defaults to 8000 Hz. The signal +## is clipped to [-1, 1]. Buffer size bs controls how many audio samples +## are clipped and buffered before sending them to the audio player. bs +## defaults to fs, which is equivalent to 1 second of audio. +## +## Note that if $DISPLAY != $HOSTNAME:n then a remote shell is opened +## to the host specified in $HOSTNAME to play the audio. See manual +## pages for ssh, ssh-keygen, ssh-agent and ssh-add to learn how to +## set it up. +## +## This function writes the audio data through a pipe to the program +## "play" from the sox distribution. sox runs pretty much anywhere, +## but it only has audio drivers for OSS (primarily linux and freebsd) +## and SunOS. In case your local machine is not one of these, write +## a shell script such as ~/bin/octaveplay, substituting AUDIO_UTILITY +## with whatever audio utility you happen to have on your system: +## #!/bin/sh +## cat > ~/.octave_play.au +## SYSTEM_AUDIO_UTILITY ~/.octave_play.au +## rm -f ~/.octave_play.au +## and set the global variable (e.g., in .octaverc) +## global sound_play_utility="~/bin/octaveplay"; +## +## If your audio utility can accept an AU file via a pipe, then you +## can use it directly: +## global sound_play_utility="SYSTEM_AUDIO_UTILITY flags" +## where flags are whatever you need to tell it that it is receiving +## an AU file. +## +## With clever use of the command dd, you can chop out the header and +## dump the data directly to the audio device in big-endian format: +## global sound_play_utility="dd of=/dev/audio ibs=2 skip=12" +## or little-endian format: +## global sound_play_utility="dd of=/dev/dsp ibs=2 skip=12 conv=swab" +## but you lose the sampling rate in the process. +## +## Finally, you could modify sound.m to produce data in a format that +## you can dump directly to your audio device and use "cat >/dev/audio" +## as your sound_play_utility. Things you may want to do are resample +## so that the rate is appropriate for your machine and convert the data +## to mulaw and output as bytes. +## +## If you experience buffer underruns while playing audio data, the bs +## buffer size parameter can be increased to tradeoff interactivity +## for smoother playback. If bs=Inf, then all the data is clipped and +## buffered before sending it to the audio player pipe. By default, 1 +## sec of audio is buffered. + +function sound(data, rate, buffer_size) + + if nargin<1 || nargin>3 + usage("sound(x [, fs, bs])"); + endif + if nargin<2 || isempty(rate), rate = 8000; endif + if nargin<3 || isempty(buffer_size), buffer_size = rate; endif + if rows(data) != length(data), data=data'; endif + [samples, channels] = size(data); + + ## Check if the octave engine is running locally by seeing if the + ## DISPLAY environment variable is empty or if it is the same as the + ## host name of the machine running octave. The host name is + ## taken from the HOSTNAME environment variable if it is available, + ## otherwise it is taken from the "uname -n" command. + display=getenv("DISPLAY"); + colon = rindex(display,":"); + if isempty(display) || colon==1 + islocal = 1; + else + if colon, display = display(1:colon-1); endif + host=getenv("HOSTNAME"); + if isempty(host), + [status, host] = system("uname -n"); + ## trim newline from end of hostname + if !isempty(host), host = host(1:length(host)-1); endif + endif + islocal = strcmp(tolower(host),tolower(display)); + endif + + ## What do we use for playing? + global sound_play_utility; + if ~isempty(sound_play_utility), + ## User specified command + elseif (file_in_path(EXEC_PATH, "ofsndplay")) + ## Mac + sound_play_utility = "ofsndplay -" + elseif (file_in_path(EXEC_PATH, "play")) + ## Linux (sox) + sound_play_utility = "play -t AU -"; + else + error("sound.m: No command line utility found for sound playing"); + endif + + ## If not running locally, then must use ssh to execute play command + if islocal + fid=popen(sound_play_utility, "w"); + else + fid=popen(["ssh ", host, " ", sound_play_utility], "w"); + end + if fid < 0, + warning("sound could not open play process"); + else + ## write sun .au format header to the pipe + fwrite(fid, toascii(".snd"), 'char'); + fwrite(fid, 24, 'int32', 0, 'ieee-be'); + fwrite(fid, -1, 'int32', 0, 'ieee-be'); + fwrite(fid, 3, 'int32', 0, 'ieee-be'); + fwrite(fid, rate, 'int32', 0, 'ieee-be'); + fwrite(fid, channels, 'int32', 0, 'ieee-be'); + + if isinf(buffer_size), + fwrite(fid, 32767*clip(data,[-1, 1])', 'int16', 0, 'ieee-be'); + else + ## write data in blocks rather than all at once + nblocks = ceil(samples/buffer_size); + block_start = 1; + for i=1:nblocks, + block_end = min(size(data,1), block_start+buffer_size-1); + fwrite(fid, 32767*clip(data(block_start:block_end,:),[-1, 1])', 'int16', 0, 'ieee-be'); + block_start = block_end + 1; + end + endif + pclose(fid); + endif +end + +###### auplay based version: not needed if using sox +## ## If not running locally, then must use ssh to execute play command +## global sound_play_utility="~/bin/auplay" +## if islocal +## fid=popen(sound_play_utility, "w"); +## else +## fid=popen(["ssh ", host, " ", sound_play_utility], "w"); +## end +## fwrite(fid, rate, 'int32'); +## fwrite(fid, channels, 'int32'); +## fwrite(fid, 32767*clip(data,[-1, 1])', 'int16'); +## pclose(fid); + +%!demo +%! [x, fs] = auload(file_in_loadpath("sample.wav")); +%! sound(x,fs);