Как воспроизвести звук в Октаве?
Октава, по-видимому, предполагает, что определенная утилита воспроизведения звука будет доступна в системе, но, похоже, не предоставляет возможности указать альтернативу. В приведенной ниже ошибке Octave ищет ofsndplay
, который не является утилитой, доступной во всех системах.
Октава:38> звук(beamformed_20)
sh: ofsndplay: команда не найдена
есть ли параметр конфигурации октавы или фрагмент кода, который я могу использовать для указания подходящая для системы утилита?
7 ответов
Я переопределил функцию playaudio из октавы со следующей функцией. Это будет работать только после установки Сокс.
sudo apt-get install sox
(в ubuntu)
function [ ] = playaudio (x, sampling_rate)
if nargin == 1
sampling_rate = 8000
end
file = tmpnam ();
file= [file, '.wav'];
wavwrite(x, sampling_rate, file);
['play ' file ]
system(['play ' file ]);
system(['rm ' file]);
end
подобный подход позволит вам записать тоже:
% Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2003, 2004, 2005,
% 2006, 2007 John W. Eaton
%
% This file is part of Octave.
%
% Octave 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 3 of the License, or (at
% your option) any later version.
%
% Octave 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 Octave; see the file COPYING. If not, see
% <http://www.gnu.org/licenses/>.
% -*- texinfo -*-
% @deftypefn {Function File} {} record (@var{sec}, @var{sampling_rate})
% Records @var{sec} seconds of audio input into the vector @var{x}. The
% default value for @var{sampling_rate} is 8000 samples per second, or
% 8kHz. The program waits until the user types @key{RET} and then
% immediately starts to record.
% @seealso{lin2mu, mu2lin, loadaudio, saveaudio, playaudio, setaudio}
% @end deftypefn
% Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
% Created: 19 September 1994
% Adapted-By: jwe
% And adapted again 11/25/2010 by Rob Frohne
function X = record (sec, sampling_rate)
if (nargin == 1)
sampling_rate = 8000;
elseif (nargin != 2)
print_usage ();
endif
file = tmpnam ();
file= [file,".wav"];
input ("Please hit ENTER and speak afterwards!\n", 1);
cmd = sprintf ("rec -c1 -r%d %s trim 0 %d",
sampling_rate, file, sec)
system (cmd);
X = wavread(file);
end
установить alsa-utils или pulseaudio-utils и поместите следующее в свой~/.octaverc:
global sound_play_utility = 'aplay';
или
global sound_play_utility = 'paplay';
на одной из моих машин Linux я создал следующий сценарий ofsndplay для работы с жесткой зависимостью:
$ cat /usr/bin/ofsndplay
#!/bin/sh
## Coping with stupid dependency on ofsndplay in octave
play -t au -
этот конкретный скрипт использует SoX play
утилиты.
по общему признанию, комментарий не нужен для функциональности, но это, безусловно, заставило меня чувствовать себя лучше....
playaudio
сломан!
стоит значение по умолчанию playsound
(версия 3.6.2):
function playaudio (name, ext)
if (nargin < 1 || nargin > 2)
print_usage ();
endif
if (nargin == 1 && isnumeric (name))
## play a vector
if (! isvector (name))
error ("playaudio: X must be a vector");
endif
X = name(:) + 127;
unwind_protect
file = tmpnam ();
fid = fopen (file, "wb");
fwrite (fid, X, "uchar");
fclose (fid);
[status, out] = system (sprintf ('cat "%s" > /dev/dsp', file));
if (status != 0)
system (sprintf ("paplay --raw \"%s\"", file))
endif
unwind_protect_cleanup
unlink (file);
end_unwind_protect
elseif (nargin >= 1 && ischar (name))
## play a file
if (nargin == 1)
name = [name ".lin"];
elseif (nargin == 2)
name = [name "." ext];
endif
if (any (strcmp (ext, {"lin", "raw"})))
[status, out] = system (sprintf ('cat "%s" > /dev/dsp', name));
if (status != 0)
system (sprintf ('paplay --raw "%s"', name))
endif
elseif (any (strcmp (ext, {"mu", "au" "snd", "ul"})))
[status, out] = system (sprintf ('cat "%s" > /dev/audio', name));
if (status != 0)
system (sprintf ('paplay "%s"', name))
endif
else
error ("playaudio: unsupported extension '%s'", ext);
endif
else
print_usage ();
endif
endfunction
есть некоторые вещи, чтобы отметить:
- запись непосредственно в /dev / dsp всегда терпит неудачу в последних дистрибутивах linux, поэтому каждый раз
выполнения команды вы получите сообщение об ошибке (о
cat > /dev/dsp
line). - это жестко использовать
paplay
, проигрыватель pulseaudio командной строки. - в
paplay
звонок не будет работать, потому чтоpaplay
по умолчаниюs16ne
(вероятно, опечатка; я думаю, они имели в видуs16be
- подписан 16-битный большой endian), иplayaudio
пишет без знака 8-бит! - он называет это с помощью
system()
. Всегда плохая идея. - он записывает аудио в файл, а не транслирует его. Может вызвать проблемы с большими файлами.
- в отличие от matlab, он не обрабатывает аудио с плавающей запятой. На самом деле он поддерживает только 8-битный звук! Вроде глупо, так как это результат, возвращаемый wavread!
- в отличие от MATLAB, он поддерживает только одну частоту дискретизации (44100 Гц).
эта функция является чрезвычайно хакерской, небезопасной и ненадежной. Если он каким-либо образом представляет качество кода в другом месте Октавы... что ж, это тревожно. Он действительно должен быть reimplemented как правильная функция в Октаве с использованием portaudio.
немного лучше версии
у меня нет времени или мотивации чтобы сделать много взлома на Октаве, поэтому в то же время я предлагаю вам вместо этого использовать эту немного лучшую функцию:
function playsound(wav, samplerate)
# Play a single-channel wave at a certain sample rate (defaults to 44100 Hz).
# Input can be integer, in which case it is assumed to be signed 16-bit, or
# float, in which case it is in the range -1:1.
if (nargin < 1 || nargin > 2)
print_usage();
endif
if (nargin < 2)
samplerate = 44100;
end
if (!isvector(wav))
error("playsound: X must be a vector");
endif
# Write it as a 16-bit signed, little endian (though the amaaazing docs don't say the endianness)
# If it is integers we assume it is 16 bit signed. Otherwise we assume in the range -1:1
if (isfloat(wav))
X = min(max(wav(:), -1), 1) * 32767; # Why matlab & octave do not have a clip() function... I do not know.
else
X = min(max(wav(:), -32767), 32767) + 32767;
endif
unwind_protect
file = tmpnam ();
fid = fopen (file, "wb");
fwrite (fid, X, "int16");
fclose (fid);
# Making aplay (alsa) the default, because let's be honest: it is still way more reliable than
# the mess that is pulseaudio.
if (exist("/usr/bin/aplay") == 2)
system(sprintf("/usr/bin/aplay --format=S16_LE --channels=1 --rate=%d \"%s\"", samplerate, file))
elseif (exist("/usr/bin/paplay") == 2)
system(sprintf("/usr/bin/paplay --format=s16le --channels=1 --rate=%d --raw \"%s\"", samplerate, file))
endif
unwind_protect_cleanup
unlink (file);
end_unwind_protect
endfunction
это все еще очень хакерская функция. Но он должен быть, по крайней мере, немного более надежным, чем playaudio
! Я оставлю реализацию soundsc
как упражнение для читателя.
Я на Mac (Yosemite) и обнаружил более простое решение, чем то, что предложили другие. На всякий случай это все еще актуально для кого-либо:
Сначала установите SoX:http://sox.sourceforge.net/
(через Homebrew)
brew install sox
Теперь в командной строке терминала вы можете использовать:
play “/path/to/sound file.wav"
...и вы услышите прекрасную музыку.
но эта команда не работает изнутри Октавы. Это работа:
system(‘play “/path/to/sound file.wav”’);
на OSX, это то, что я сделал, чтобы заставить звук работать:
С sound
команда:
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";
Я назвал следующий скрипт "octaveplay" и поместил его в ~/bin:
cat > ~/.octave_play.aif
afplay ~/.octave_play.aif
rm -f ~/.octave_play.aif
затем я создал .octaverc и добавлено:
global sound_play_utility="~/bin/octaveplay";
вуаля!
На Октаву 4.2.1. Вы можете воспроизвести wav-файл следующим образом
сохраните следующий код в файле playWav.м
function playWav(inputFilePath)
[y, fs] = audioread(inputFilePath);
player = audioplayer(y, fs);
playblocking(player)
end
тогда вы можете вызвать функцию как playWav('/path/to/wavfile');
из командной строки Октавы.
проверен на Windows 7.