如何在Octave中播放声音?

时间:2009-09-25 15:40:58

标签: linux audio signal-processing octave

Octave似乎假设系统上可以使用特定的声音播放实用程序,但似乎无法指定备用音频。在下面的错误中,Octave正在寻找ofsndplay,这不是所有系统上都可用的实用程序。

  

八度:38基声音(beamformed_20)

     

sh:ofsndplay:找不到命令

是否有可用于指定系统适用实用程序的Octave配置设置或代码片段?

7 个答案:

答案 0 :(得分:8)

我使用以下功能从八度音阶重写了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 <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

答案 1 :(得分:3)

安装 alsa-utils pulseaudio-utils 并将以下内容放在〜/ .octaverc中:

global sound_play_utility = 'aplay';

global sound_play_utility = 'paplay';

答案 2 :(得分:3)

在我的一台Linux机器上,我创建了以下ofsndplay脚本来解决硬连线依赖:

$ cat /usr/bin/ofsndplay

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

此特定脚本使用SoX play实用程序。

不可否认,评论对于功能来说是不必要的,但它确实让我感觉更好....

答案 3 :(得分:3)

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

有些事情需要注意:

  1. 直接写入/ dev / dsp总是在最新的Linux发行版中失败,所以每次都这样 运行命令时会出现错误(在cat > /dev/dsp行上)。
  2. 使用命令行pulseaudio播放器paplay进行硬编码。
  3. paplay来电永远不会有效,因为paplay默认为s16ne(可能是错字;我认为他们的意思是s16be - 签名为16- bit big endian),playaudio写无符号8位!
  4. 使用system()调用它。总是一个坏主意。
  5. 它将音频写入文件而不是流式传输。可能会导致大文件出现问题。
  6. 与matlab不同,它不处理浮点音频。它实际上只支持8位音频!有点愚蠢,因为那是wavread返回的结果!
  7. 与matlab不同,它只支持一个采样率(44100 Hz)。
  8. 这个功能非常黑客,不安全且不可靠。如果它以任何方式代表Octave其他地方的代码质量......那么,这是令人担忧的。它真的应该在使用portaudio的Octave中重新实现为正确的功能。

    稍微好一点的版本

    我没有时间或动力在八度音程上做很多黑客攻击,所以在同一时间我建议你改用这个稍微好一点的功能:

    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
    

    这仍然是一个非常hacky功能。但它应该至少比playaudio更可靠!我会留下soundsc的实现作为读者的练习。

答案 4 :(得分:2)

我在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”’);

答案 5 :(得分:1)

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

瞧!

答案 6 :(得分:1)

在Octave 4.2.1上。您可以按如下方式播放wav文件

将以下代码保存在文件playWav.m

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

然后你可以从Octave命令行调用函数playWav('/path/to/wavfile');

在Windows 7上测试。