Zufälliges Rauschen zum Spaß in / dev / snd / erzeugen

41

Kürzlich habe ich den verzauberten / dev-Ordner erkundet. Ich möchte zufällige Daten auf ein Audiogerät schreiben, um Rauschen zu erzeugen.

Ich benutze ALSA.

Also weise ich cat an, einige zufällige Daten in die Wiedergabedatei im Ordner / dev zu leiten ...

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

dann erhalte ich von cat einen scheinbaren fehler

 cat: write error: File descriptor in bad state

Wie kann ich das beheben, damit ich ein köstliches statisches Spiel von meiner Soundkarte hören kann?

Jones
quelle
1
Ich denke, Sie müssen zufällige PCM-Daten senden , oder Sie müssen das Gerät zuerst mit ein paar Ioctls einrichten - Sie können nicht einfach zufällige Bytes ausgeben.
Gilles 'SO- hör auf böse zu sein'
@Gilles Laut Wikipedia ist .wav PCM und ich erhalte genau das gleiche Ergebnis, wenn ich die zufällige Datei durch eine .wav-Datei ersetze. Ich werde die Einrichtung einiger Ein- / Aus-Steuerelemente untersuchen.
Jones
Hat jemand einen Zeiger für ein Tutorial, wie man einige ioctls einrichtet? Für etwas namens ioctls dachte ich, ALSA als API sollte die Schnittstelle für Ein- und Ausgabe bereitstellen?
Jones
Hier ist ein funktionierendes Beispiel, wie PCM-Daten direkt in die Gerätedatei geschrieben werden: github.com/igor-liferenko/pcm
Igor Liferenko

Antworten:

46

Ich denke, der Grund, warum dies bei Ihnen nicht funktioniert, ist, dass diese Schnittstelle veraltet ist. Normalerweise kann man mit Audio nicht mehr schreiben /dev/dsp, zumindest ohne dass es schwierig ist.

Es ist ein Programm, das für Sie auf Ihrem System erreichen wird: padsp. Dadurch wird die Datei /dev/audiooder /dev/dspdem neuen Audioserver-System zugeordnet.

Starten Sie das Terminal und wechseln Sie mit in den Root-Modus sudo su.

Dann gehe ich zu cat /dev/urandomund leite die Ausgabe in padspund benutze den teeBefehl, um die Daten an zu senden /dev/audio. Sie werden eine Menge Müll in Ihrem Terminal finden, zu dem Sie möglicherweise umleiten möchten /dev/null.

Versuchen Sie im Superuser den folgenden Befehl:

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

Vielleicht möchten Sie es sogar mit anderen Geräten wie Ihrer Maus versuchen: Verwenden Sie /dev/psauxzum Beispiel: oder den USB-Treiber. Sie können sogar Ihr Gedächtnis durchgehen lassen: /dev/mem

Hoffe, das erklärt, warum es vorher nicht funktioniert hat.

Ich persönlich fand die Maus und das Gedächtnis viel interessanter als das Spielen von statischem Zufall!

Chris Thomas
quelle
1
Danke vielmals! Das ist, wonach ich gesucht habe. Beantwortet volle 7 Monate nach dem Posten der Frage! :-)
jones
3
Es scheint, dass hierfür sudokeine Berechtigungen erforderlich sind.
iyrin
2
vielen Dank. Ich fand Binaries komisch interessant. Dinge wie / usr / bin / ls / usr / bin / gnome-terminal / usr / bin / mysql
don bright
hmm, seltsam, 'tee' kann das, aber 'dd of = / dev / audio' nicht.
Jasen
@Jasen dd schreibt möglicherweise zu viel auf einmal. padsp simuliert / dev / audio, um es durch alsa umzuleiten. dd ohne padsp sieht / dev / audio erst, wenn die kerninterne OSS-Emulation aktiviert ist (und standardmäßig nicht). Und ich denke, das Schreiben eines großen Blocks, der viel größer als die Puffer im Treiber ist, könnte sogar scheitern.
Paul Stelian
8

cat /dev/urandom | aplay ist der Befehl, der eingegeben werden muss. Wenn Sie nicht in der Gruppe "Audio" sind, können Sie sudo das Präfix aplay voranstellen. Dies stört auch keine Daemons (ich lief, pulseaudiowährend dieser Befehl aktiv war und das "Rauschen" richtig hörte).

BEARBEITEN (6. August 2019): In einer älteren Version des Befehls hatte ich auch eine padsp teeSache zwischen dem catund aplay. Jetzt, da ich tatsächlich auf dem Gebiet arbeite, merke ich, dass es absolut keinen Sinn ergab. Außerdem weiß ich, dass der aktualisierte Befehl (der jetzt am Anfang dieser Antwort angezeigte) funktioniert, da ich ihn mehrmals am Tag bei der Arbeit verwende.

Paul Stelian
quelle
6
Ich benutze ALSA und "padsp tee" ist nicht notwendig.
Geremia
1
In meinen Erfahrungen mit pulseaudio (und was auch immer Ubuntu verwendet, wenn PA padsp teeausfällt ) war dies erforderlich (ich hatte zu diesem Zeitpunkt genau den 12.04.2). Das Problem ist, dass Sie nicht versuchen sollten, Daten direkt auf Geräte zu übertragen, selbst wenn Sie root waren ( Soweit ich weiß, sind nur wenige Dateien im Ordner / dev lesbar und keine beschreibbar. Sie könnten entweder einen Fehler bekommen (im besten Fall, der bei jedem Update häufiger auftritt), den Kernel zum Absturz bringen oder sogar das Gerät beschädigen. in seltenen Fällen. Man sollte dazu unprivilegierte Elemente wie aplay verwenden (Audio-Gruppe oder Root sind leider erforderlich). @ Geremia
Paul Stelian
Komisch, wie ich jetzt sehe, dass das padsp teeDing überhaupt keinen Sinn ergibt. Bei der Arbeit benutze ich etwas Ähnliches ohne diese Zeile, um zu testen, ob ich beim Schreiben des Audiotreibers Fortschritte mache. Werde jetzt meine Antwort aktualisieren.
Paul Stelian
3

Probieren Sie / dev / audio oder eines der anderen Geräte unter / dev / snd aus. Nicht alle von ihnen sind Audio-Datenquellen. Möglicherweise haben Sie einen Mixer, ein Mikrofon oder etwas anderes gefunden

Stefan Noack
quelle
1
danke für die Antwort. Laut / proc / asound / devices / dev / snd / pcmC0D0p ist das richtige Gerät für die Audiowiedergabe (daher das 'p')
Jones
1
Ich bin mir auch nicht sicher, aber kann es mehrere Entwicklerdateien für die Wiedergabe geben? Ich habe kein '/ dev / audio' Ich denke, '/ dev / audio' hat etwas mit OSS zu tun, das auf älteren Kerneln (vor 2.5) verwendet wird
jones
2

Hält ein Sound-Daemon (z. B. pulseaudio) eine Sperre für das Gerät? Ich denke, Sie können herausfinden, ob irgendetwas anderes einen Griff darüber hat lsof.

jmtd
quelle
1
Danke für den hilfreichen Vorschlag. Ich hatte einen Scheck mit grepund lsof. pulseaudiowird verwendet /dev/snd/controlC0, ist aber nicht aktiviert /dev/snd/pcmC0D0p. Ich überprüfte noch einmal, /var/lockob eine Datei für eine Sperre auf dem Gerät vorhanden war. ls -alsagt, dass der Ordner leer ist. Ich denke, es gibt keine Sperre für pcmC0D0p
jones
@jones Je nach Treiber kann es ausreichen, die Steuerung zu sperren, um die gesamte Karte zu sperren. (Entschuldigung für die Antwort nach 8 Jahren, jetzt habe ich das selbst gelernt)
Paul Stelian
0

TL; DR: Die Geräteparameter müssen vor dem Lesen oder Schreiben von Daten eingestellt werden.

Schritt für Schritt:

  1. Öffnen Sie das PCM-Gerät. Zum Beispiel: fd = open("/dev/snd/pcmC0D0p", O_RDWR). Nach dem Öffnen befindet sich PCM im OPENStatus.

  2. Parameter einstellen mit ioctl(fd, SNDRV_PCM_IOCTL_HW_PARAMS, (struct snd_pcm_hw_params*) p). Die Hardware-Parameterstruktur enthält Masken (jedes Bit ist ein Wert) und Intervalle ([Minimum, Maximum] -Bereich). Die nicht gesetzten Parameter müssen gefüllt übergeben werden (alle gesetzten Bits / Werte für Masken; voller Bereich für Intervalle). Nach dem Einstellen der Hardware-Parameter befindet sich PCM im SETUPStatus. Code finden Sie in pcm_set_config () von TinyALSA.

    Einstellung ACCESS, FORMAT, RATE, CHANNELS, PERIOD_SIZEund PERIODSist ausreichend. Die anderen Parameter sind Varianten davon, mit der Ausnahme, BUFFER_SIZEdass bei einigen Geräten ein Nicht-Vielfaches von eingestellt werden kann PERIOD_SIZE.

  3. Aufruf ioctl(fd, SNDRV_PCM_IOCTL_PREPARE)zur Vorbereitung von Geräte- und ALSA-Laufzeitvariablen. Danach befindet sich das PCM im PREPAREDStatus.

  4. Beginnen Sie mit dem Lesen (Aufnahme) oder Schreiben (Wiedergabe).

Bei einer Minimalanwendung zum Lesen oder Schreiben auf ein PCM-Gerät dreht sich der größte Teil des Codes um die Manipulation von Hardwareparametern.

Ricardo Biehl Pasquali
quelle
Ich bin nicht sicher, ob das eigentliche Lesen / Schreiben funktioniert, da aplay (zumindest auf dem System, auf dem ich arbeite) ioctl (fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, ...) und keinen tatsächlichen Write () - Aufruf für die Wiedergabe verwendet. Verfügt ALSA selbst über einen Wrapper, der die Lese- / Schreibzugriffspunkte auf die ioctls überträgt?
Paul Stelian
@PaulStelian Ja. Siehe die Definition der Dateioperationen für pcm . In snd_pcm_read()und snd_pcm_write()werden Bytes in Frames konvertiert .
Ricardo Biehl Pasquali