Pergunta

Octave parece pressupor que um serviço de som de jogo específico estará disponível em um sistema, mas não parecem fornecer a capacidade de especificar um suplente. No erro abaixo, Octave está procurando ofsndplay, que não é um utilitário disponível em todos os sistemas.

oitava: 38> Som (beamformed_20)

sh: ofsndplay: comando não encontrado

Existe uma Octave configuração ou fragmento de código que eu posso usar para especificar um utilitário apropriado do sistema?

Foi útil?

Solução 3

Em uma de minhas máquinas Linux, eu criei o seguinte script ofsndplay Para contornar a dependência hard-wired:

$ cat /usr/bin/ofsndplay

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

Este script em particular usa o utilitário play SoX.

É certo que o comentário é desnecessário para a funcionalidade, mas certamente me fez sentir melhor ....

Outras dicas

Eu tenho substituído a função playaudio de oitava com a seguinte função. Isto irá funcionar apenas depois de instalar sox .

sudo apt-get install sox

(no 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

Uma abordagem semelhante lhe permitirá gravar demasiado:

% 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

Instalar alsa-utils ou PulseAudio-utils e colocar o seguinte em seu ~ / .octaverc:

global sound_play_utility = 'aplay';

ou

global sound_play_utility = 'paplay';

playaudio é quebrado!

Vale a pena ler a implementação padrão de playsound (versão 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

Há algumas coisas a nota:

  1. Escrevendo diretamente para / dev / dsp sempre falha nas últimas distribuições Linux, por isso cada vez você executar o comando que você obterá um erro (na linha cat > /dev/dsp).
  2. É codificado para uso paplay, um jogador de linha de comando pulseaudio.
  3. A chamada paplay nunca vai funcionar porque defaults paplay para s16ne (provavelmente um erro de digitação, eu acho que eles queriam dizer s16be - assinado de 16 bits big endian), e playaudio escreve não assinado de 8 bits
  4. Ele chama-lo usando system(). Sempre uma má idéia.
  5. Ele escreve a saída de áudio para um arquivo em vez de transmiti-lo. Pode causar problemas para arquivos grandes.
  6. Ao contrário de Matlab, ele não manipula áudio de ponto flutuante. Ele realmente só suporta áudio de 8 bits! Uma espécie de idiota uma vez que é o resultado retornado por wavread!
  7. Matlab Ao contrário, ele suporta apenas uma taxa de amostragem (44100 Hz).

Esta função é extremamente hacky, inseguro e não confiável. Se de alguma forma representa a qualidade do código em outras partes Octave ... bem, isso é preocupante. Deve realmente ser reimplantado como função adequada em Octave usando PortAudio.

versão ligeiramente melhor

Eu realmente não tem tempo ou motivação para fazer um monte de hackers na oitava, assim, no tempo médio, sugiro que em vez usar esta um pouco melhor função:

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

Esta é ainda uma função muito hacky. Mas deve ser pelo menos um pouco mais confiável do que playaudio! Vou deixar uma implementação de soundsc como um exercício para o leitor.

Eu estou em um Mac (Yosemite), e descobriu uma solução mais simples do que o que os outros têm sugerido. Apenas no caso de esta ainda é relevante para qualquer um:

Primeiro instale SoX: http://sox.sourceforge.net/

(via Homebrew)

brew install sox

Agora, na linha de comando terminal que você pode usar:

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

... e você vai ouvir uma bela música.

Mas esse comando não funciona de dentro Octave. Isto funciona:

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

No OSX, é isso que eu fiz para obter som de trabalho:

a partir da ajuda do comando 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";

I chamado o seguinte script "octaveplay" e colocá-lo em ~ / bin:

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

Então eu criei .octaverc e acrescentou: global sound_play_utility="~/bin/octaveplay";

Voila!

Em Octave 4.2.1. Você pode jogar um arquivo WAV como segue

Salvar o seguinte código em um arquivo playWav.m

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

Em seguida, você pode chamar a função como playWav('/path/to/wavfile'); de Octave de comando.

Testado no Windows 7.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top