Gerando ruído aleatório para se divertir em / dev / snd /

41

Recentemente, estive explorando a pasta / dev encantada. Quero gravar alguns dados aleatórios em um dispositivo de áudio para gerar algum ruído.

Estou usando o ALSA.

Então, eu instruo o gato a canalizar alguns dados aleatórios para o arquivo de reprodução na pasta / dev ...

 cat file-of-random-data > /dev/snd/pcmC0D0p

então eu recebo o que parece ser um erro do gato

 cat: write error: File descriptor in bad state

Como posso corrigir isso para poder ouvir uma reprodução estática deliciosa da minha placa de som?

jones
fonte
1
Eu acho que você precisa enviar dados aleatórios de PCM , ou talvez você precise configurar o dispositivo com alguns ioctls primeiro - você não pode simplesmente despejar bytes aleatórios.
Gilles 'SO- stop be evil'
@ Gilles De acordo com a Wikipedia, .wav é PCM e recebo exatamente o mesmo resultado quando substituo o arquivo aleatório por um arquivo .wav. Vou investigar a configuração de alguns controles de entrada / saída.
jones
Alguém tem um ponteiro para um tutorial sobre como configurar alguns ioctls? Para algo chamado ioctls, pensei que o ALSA como uma API deveria fornecer a interface para entrada e saída?
jones
Aqui está um exemplo prático de
Igor Liferenko

Respostas:

46

Acho que o motivo de isso não funcionar para você é porque essa interface foi preterida. Você normalmente não pode gravar áudio usando /dev/dspmais, pelo menos sem ser complicado.

Não é um programa que vai conseguir isso para você em seu sistema: padsp. Isso mapeará o arquivo /dev/audioou /dev/dsppara o novo sistema do Audio Server.

Ligue o terminal e entre no modo raiz com sudo su.

Então, vou cat /dev/urandomdirecionar a saída padspe usar o teecomando para enviar os dados /dev/audio. Você receberá uma tonelada de lixo no seu terminal e poderá redirecionar para /dev/null.

Quando você estiver no superusuário, tente este comando:

cat /dev/urandom | padsp tee /dev/audio > /dev/null

Você pode tentar outros dispositivos, como o mouse: Use /dev/psaux:, por exemplo, ou o driver USB. Você pode até executar sua memória através dele: /dev/mem

Espero que isso esclareça por que não estava funcionando antes.

Pessoalmente, achei o mouse e a memória muito mais interessantes do que jogar estática aleatória!

Chris Thomas
fonte
1
Muito obrigado! Era isso que eu estava procurando. Respondeu um total de 7 meses após postar a pergunta! :-)
jones
3
Parece que sudoprivilégios não são necessários para isso.
Iyrin
2
muito obrigado. Eu achei os binários estranhamente interessantes. coisas como / usr / bin / ls / usr / bin / gnome-terminal / usr / bin / mysql
don brilhante
hmm, estranho, 'tee' pode fazer isso, mas 'dd of = / dev / audio' não pode.
Jasen
@ Jason dd pode estar escrevendo muito de cada vez. O padsp simula / dev / audio para redirecioná-lo através do alsa. O dd sem padsp nem verá / dev / audio, a menos que a emulação OSS no kernel esteja ativada (e por padrão não). E acho que escrever um bloco grande, muito maior que os buffers do driver, pode até falhar.
Paul Stelian
8

cat /dev/urandom | aplay é o comando que precisa ser digitado. Se você não está no grupo "áudio", você pode prefixar aplay com sudo. Isso também não interfere em nenhum daemons (eu estava executando pulseaudioenquanto este comando estava ativo e ouvi corretamente o "ruído".

EDIT (6 de agosto de 2019): Em uma versão mais antiga do comando, eu também tinha uma padsp teecoisa entre o cate aplay. Agora que estou trabalhando no campo, percebo que não fazia absolutamente nenhum sentido. Além disso, eu sei que o comando atualizado (o que está visível agora no início desta resposta) funciona porque eu o uso várias vezes ao dia no trabalho.

Paul Stelian
fonte
6
Eu uso o ALSA e "padsp tee" não é necessário.
Geremia
1
Nas minhas experiências com o pulseaudio (e o que quer que o Ubuntu esteja usando quando o PA está desativado), isso padsp teeera necessário (eu tinha o 12.04.2 preciso naquele momento). O problema é que você não deve tentar despejar dados diretamente nos dispositivos, mesmo que você seja root ( até onde eu sei, poucos arquivos são legíveis e nenhum gravável na pasta / dev), porque você pode receber um erro (na melhor das hipóteses, o que é mais comum a cada atualização), travar o kernel ou até quebrar o dispositivo, em casos raros. Deve-se usar elementos não privilegiados, como aplay, para fazer isso (grupo ou raiz de áudio necessário, infelizmente). @geremia
Paul Stelian
Engraçado como agora vejo que a padsp teecoisa realmente não faz nenhum sentido. No trabalho, uso algo semelhante sem essa linha para testar se estou fazendo progresso ao escrever o driver de áudio. Agora atualizará minha resposta.
Paul Stelian
3

Tente / dev / audio ou um dos outros dispositivos em / dev / snd. Nem todos são coletores de dados de áudio, você pode ter pego um mixer, microfone ou algo assim

Stefan Noack
fonte
1
Obrigado pela resposta. De acordo com / proc / asound / devices / dev / snd / pcmC0D0p é o dispositivo certo para reprodução de áudio (daí o 'p')
jones
1
Além disso, não tenho certeza, mas pode haver vários "arquivos" de desenvolvimento para reprodução? Eu não tenho um '/ dev / audio' Eu acho que '/ dev / audio' tem algo a ver com o OSS que é usado em kernels mais antigos (antes da versão 2.5)
jones
2

Um daemon de som (por exemplo pulseaudio) mantém uma trava no dispositivo? Eu acho que você pode descobrir se alguma outra coisa tem um controle sobre isso via lsof.

jmtd
fonte
1
Obrigado pela sugestão útil. Eu tinha um cheque, usando grepe lsof. pulseaudioestá usando, /dev/snd/controlC0mas não está ativado /dev/snd/pcmC0D0p. Eu verifiquei duas vezes /var/lockpara descobrir se havia um arquivo para uma trava no dispositivo. ls -alinforma que a pasta está vazia. Então eu acho que não há bloqueio na pcmC0D0p
jones
@jones Manter uma trava no controle pode ser suficiente para bloquear o cartão inteiro, dependendo do driver. (desculpe por responder depois de 8 anos, agora eu aprendi isso sozinho)
Paul Stelian
0

TL; DR: Os parâmetros do dispositivo devem ser definidos antes de ler ou gravar dados nele.

Passo a passo:

  1. Abra o dispositivo PCM. Por exemplo: fd = open("/dev/snd/pcmC0D0p", O_RDWR). Depois de aberto, o PCM está no OPENestado.

  2. Defina os parâmetros com ioctl(fd, SNDRV_PCM_IOCTL_HW_PARAMS, (struct snd_pcm_hw_params*) p). A estrutura de parâmetros do hardware possui máscaras (cada bit é um valor) e intervalos ( intervalo [mínimo, máximo]). Os parâmetros que não estão sendo definidos devem ser passados ​​preenchidos (todos os bits / valores definidos para máscaras; intervalo completo para intervalos). Após definir os parâmetros de hardware, o PCM está no SETUPestado. Veja pcm_set_config () do TinyALSA para código.

    Definindo ACCESS, FORMAT, RATE, CHANNELS, PERIOD_SIZEe PERIODSé suficiente. Os outros parâmetros são variantes destes, exceto BUFFER_SIZEque em alguns dispositivos pode ser definido como um não múltiplo de PERIOD_SIZE.

  3. Chame ioctl(fd, SNDRV_PCM_IOCTL_PREPARE)para preparar variáveis ​​de tempo de execução do dispositivo e do ALSA. Depois disso, o PCM está no PREPAREDestado.

  4. Comece a ler (capturar) ou escrever (reproduzir).

Um aplicativo mínimo para leitura ou gravação em um dispositivo PCM terá a maior parte do código relacionado à manipulação de parâmetros de hardware.

Ricardo Biehl Pasquali
fonte
Não tenho certeza se o trabalho de leitura / gravação real, pois o aplay usa (pelo menos no sistema em que estou desenvolvendo) ioctl (fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, ...) e não uma chamada de gravação () real na reprodução. O próprio ALSA possui um invólucro que pega os pontos de entrada de leitura / gravação e os converte nos do ioctl?
Paul Stelian
@PaulStelian Sim. Veja a definição de operações de arquivo para pcm . Em snd_pcm_read()e snd_pcm_write(), os bytes são convertidos em quadros .
Ricardo Biehl Pasquali