代码之家  ›  专栏  ›  技术社区  ›  Bob Cross n8wrl

我怎么用八度音阶演奏声音?

  •  10
  • Bob Cross n8wrl  · 技术社区  · 16 年前

    Octave似乎假定特定的声音播放工具在系统上可用,但似乎不提供指定备用的功能。在下面的错误中,八度音正在寻找 ofsndplay 不是所有系统上都可用的实用程序。

    八度:38>声音(波束形成_20)

    sh:ofsndplay:未找到命令

    是否有一个八度配置设置或代码片段,我可以用来指定一个适合系统的实用程序?

    7 回复  |  直到 8 年前
        1
  •  8
  •   Matyas    15 年前

    我用以下函数从八度音阶重写了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
    
        2
  •  3
  •   rcs    16 年前

    安装 阿尔萨乌蒂斯 Pulseaudio实用程序 在你的~/.octaverc里写下:

    global sound_play_utility = 'aplay';
    

    global sound_play_utility = 'paplay';
    
        3
  •  3
  •   Bob Cross n8wrl    16 年前

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

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

    这个特定的脚本使用SOX play 实用工具。

    诚然,评论对于功能来说是不必要的,但它确实让我感觉好多了……

        4
  •  3
  •   Timmmm    13 年前

    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. 在最新的Linux发行版中,直接写入/dev/dsp总是失败,因此每次 如果运行该命令,将得到一个错误(在 cat > /dev/dsp 线)。
    2. 它很难编码使用 paplay 一个命令行的Pulseaudio播放器。
    3. 这个 帕普莱 打电话永远不会起作用,因为 帕普莱 默认为 s16ne (可能是打字错误,我想他们的意思是 s16be -有符号的16位big endian),以及 播放音频 写入无符号8位!
    4. 它使用 system() .总是个坏主意。
    5. 它将音频输出到文件,而不是流式传输。可能会导致大文件出现问题。
    6. 与matlab不同,它不处理浮点音频。它实际上只支持8位音频!有点傻,因为这是wavread返回的结果!
    7. 与matlab不同,它只支持一个采样率(44100Hz)。

    这个功能非常黑客,不安全和不可靠。如果它以任何方式表示八度音阶中其他地方的代码质量…好吧,这是令人担忧的。在八度音阶中,它真的应该用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
    

    这仍然是一个非常黑客的功能。但它至少应该比 播放音频 !我会留下一个 soundsc 作为读者的练习。

        5
  •  2
  •   tgig    11 年前

    我在一个Mac(约塞米蒂)上,发现了一个比其他人所建议的更简单的解决方案。以防万一这仍然与任何人有关:

    首次安装SOX: http://sox.sourceforge.net/

    (通过自制)

    brew install sox
    

    现在,在终端命令行上,可以使用:

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

    …你会听到美妙的音乐。

    但这个命令在八度以内是行不通的。这确实有效:

    system(‘play “/path/to/sound file.wav”’);
    
        6
  •  1
  •   terrace    16 年前

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

    哇!

        7
  •  1
  •   user13107 Android Killer    8 年前

    在八度音阶4.2.1上。您可以按如下方式播放wav文件

    在playwav.m文件中保存以下代码

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

    然后您可以调用函数 playWav('/path/to/wavfile'); 来自八度命令行。

    在Windows 7上测试。