Как воспроизвести звук в Octave?

Октава, по-видимому, предполагает, что специальная утилита для воспроизведения звука будет доступна в системе, но, похоже, не дает возможности указать альтернативу. В приведенной ниже ошибке Octave ищет ofsndplay, которая не является доступной для всех систем.

октава: 38 > звук (beamformed_20)

sh: ofsndplay: команда не найдена

Есть ли параметр конфигурации Octave или фрагмент кода, который я могу использовать для указания утилиты, подходящей для системы?

Ответ 1

На одной из моих Linux-машин я создал следующий из ssndplay script, чтобы обойти жесткую зависимость:

$ cat /usr/bin/ofsndplay

#!/bin/sh
## Coping with stupid dependency on ofsndplay in octave
play -t au -

В этом конкретном script используется утилита SoX play.

По общему признанию, комментарий не нужен для функциональности, но это, безусловно, заставило меня чувствовать себя лучше.

Ответ 2

Я переопределил функцию playaudio из октавы со следующей функцией. Это будет работать только после установки sox.

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 <[email protected]>
% 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

Ответ 3

Установите alsa-utils или pulseaudio-utils и поместите следующее в свой ~/.octaverc:

global sound_play_utility = 'aplay';

или

global sound_play_utility = 'paplay';

Ответ 4

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).
  • Он жестко закодирован для использования paplay, проигрывателя пульсации командной строки.
  • Вызов paplay никогда не будет работать, потому что paplay по умолчанию имеет значение s16ne (вероятно, опечатка, я думаю, что они означали s16be - подписанный 16-разрядный большой конец), а playaudio записывает без знака 8-разрядный!
  • Он вызывает это, используя system(). Всегда плохая идея.
  • Он записывает аудиофайл в файл, а не передает его. Может возникнуть проблема с большими файлами.
  • В отличие от matlab, он не обрабатывает звук с плавающей запятой. Он фактически поддерживает только 8-битный звук! Вид глупого, так как это результат, возвращаемый wavread!
  • В отличие от Matlab, он поддерживает только одну частоту дискретизации (44100 Гц).

Эта функция чрезвычайно халатная, небезопасная и ненадежная. Если это каким-либо образом представляет качество кода в другом месте в Octave... ну, это беспокоит. Это действительно должно быть переопределено как надлежащая функция в Octave с помощью 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 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 как упражнение для читателя.

Ответ 5

Я нахожусь на Mac (Yosemite) и обнаружил более простое решение, чем предлагали другие. На всякий случай это все еще актуально для любого:

Сначала установите SoX: http://sox.sourceforge.net/

(через Homebrew)

brew install sox

Теперь в командной строке терминала вы можете использовать:

play "/path/to/sound file.wav"

... и вы услышите прекрасную музыку.

Но эта команда не работает из Octave. Это работает:

system(‘play "/path/to/sound file.wav"’);

Ответ 6

В 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";

Я назвал следующий script "октавеплей" и поместил его в ~/bin:

cat > ~/.octave_play.aif
afplay ~/.octave_play.aif
rm -f ~/.octave_play.aif

Затем я создал .octaverc и добавил: global sound_play_utility="~/bin/octaveplay";

Voila!

Ответ 7

В Октаве 4.2.1. Вы можете воспроизвести wav файл следующим образом

Сохраните следующий код в файле playWav.m

function playWav(inputFilePath)
  [y, fs] = audioread(inputFilePath);
  player  = audioplayer(y, fs);
  playblocking(player)
end

Затем вы можете вызвать функцию как playWav('/path/to/wavfile'); из командной строки Octave.

Протестировано в Windows 7.