kern.audio.record
sysctl may be used to enable it.
# sysctl kern.audio.record=1 # echo kern.audio.record=1 >> /etc/sysctl.conf
Not every option of every audio chip necessarily reaches the outside world. There may be, for example, more outputs listed than are physically connected. The controls of an audio device may be labeled differently. Usually the controls have a meaningful label, but sometimes one must simply try different settings to see what effect each control has.
Here's a list of controls to consider:
Mute and Level controls - Even if the main controls seem to be properly set, there might be multiple mute or level controls in the signal path. In the example below, the device has a master recording level and a microphone gain control:
record.adc-0:1=248,248 record.adc-0:1_source=mic inputs.mic=85,85External Amplifier Power-Down (EAPD) - This switch is typically used for power saving in laptops and may need to be set to get an output signal:
outputs.spkr_eapd=onRecording Source - Some devices have multiple microphone inputs. Examples of such controls:
record.source=mic record.adc-0:1_source=micTo make the changes take effect on each reboot, edit the
/etc/mixerctl.conf
file.
For example:
record.adc-0:1_source=mic inputs.mic=85,85
The output.level
control is always present.
It either corresponds to a hardware control or is emulated in software.
uaudio0 at uhub2 port 1 configuration 1 interface 1 "ABC C-Media USB Audio Device" rev 1.10/1.00 addr 2 uaudio0: class v1, full-speed, sync, channels: 2 play, 1 rec, 8 ctls audio1 at uaudio0On most systems, the first audio device is the internal sound card. A USB audio device then becomes the second one when connected. In the default sndiod(8) configuration, both devices are known to programs as
snd/0
(the default) and snd/1
respectively and may be used independently.
Programs set up to use snd/1
will use the USB device.
sndiod(8) may be configured
to make snd/0
correspond to the USB device if it's connected
or to the internal one when it's not:
# rcctl set sndiod flags -f rsnd/0 -F rsnd/1 # rcctl restart sndiodWhen the server opens the device, it will first try the USB one. If it's not present, the internal one is used instead. If the USB device is disconnected, sndiod attempts to continue operation using the internal sound card. If the USB device is connected again, sndiod will see it the next time it attempts to open the device. To force sndiod to switch between devices, reload the server:
# rcctl reload sndiod
OpenBSD comes with aucat(1), a program able to play uncompressed WAV, AIFF and AU files. It can be used in very simple cases or to test playback:
$ aucat -i filename.wavThere are many other players available as packages that support other audio formats.
kern.audio.record
sysctl,
aucat(1)
can be used for recording uncompressed WAV, AIFF and AU files.
$ aucat -o file.wavThe above command will start the recording of a file in WAV format. Press CTRL+C to finish the recording.
To play the file back, run:
$ aucat -i file.wavIf recording seemed to work, but playback of the recording was silent or not what was expected, the mixer probably needs some configuration. Make sure that you select the right source to record from and that it is unmuted.
If needed, the resulting WAV file could be compressed with the appropriate program from the ports tree. Alternatively, ports like sox, ffmpeg, or audacity can be used to record, process and compress audio files.
Create the monitor sub-device mon
for
sndiod(8) by using:
# rcctl set sndiod flags -s default -m play,mon -s mon # rcctl restart sndiodConfigure your program to record audio from the
snd/0.mon
device,
for instance:
$ aucat -f snd/0.mon -o file.wavAt this point, whatever your system plays is recorded in
file.wav
.
sndiod(8) imposes a minimum latency on all audio applications,
and the default latency is 160ms.
If you plan to use applications that require a lower latency, use the
-b
option to select the desired latency (expressed in number of
frames).
For instance, at 48000 samples/second, 50ms latency corresponds to:
48000 samples/second × 0.050 seconds = 2400 samplesThen do:
# rcctl set sndiod flags -b2400
# rcctl set sndiod flags -L-On the local system, configure your program to use
snd@hostname/0
,
where "hostname" is the address of the remote system.
The AUDIODEVICE
environment variable could be set to the above
value to make the remote sound card the default audio device.
Any system able to connect to TCP port 11025 of the remote host will be able
to use the audio device.
For privacy reasons, only one user from one system may have connections
to it at a given time.
If multiple systems have to use the audio device simultaneously, the
sndio(7) authorization cookie must be the same.
For instance, copy your ~/.sndio/cookie
to all accounts
that may use the audio device.
To avoid glitches, TCP traffic on port 11025 could be prioritized with the packet filter. With the default configuration, sndiod will consume around 200kB/s of network bandwidth.
AUDIODEVICE
environment variable.
If it's not set, snd/0
is used, which is the first audio device
managed by sndiod(8).
The most flexible way of choosing the default device is to export
AUDIODEVICE
, possibly in the user's login profile.
Another way to change the default audio output device is to make the desired device the first device managed by sndiod(8). For example, to use an external DAC rather than your motherboard's onboard audio, just change sndiod(8)'s startup flags to use that device:
# rcctl set sndiod flags -f rsnd/1 # rcctl restart sndiodThis would make the second audio device (
rsnd/1
) the default.
If you believe your device should be working, but for whatever reason isn't, then it's time for a little debugging. The following steps can determine if data is being processed by the DAC.
# cat > /dev/audio0 < /dev/zero & [1] 9926 # audioctl play.{bytes,errors} play.bytes=3312000 play.errors=0 # audioctl play.{bytes,errors} play.bytes=7065600 play.errors=0 # audioctl play.{bytes,errors} play.bytes=9379200 play.errors=0 # kill %1 # fg %1 cat > /dev/audio0 < /dev/zero TerminatedHere we see that the processed data count
play.bytes
increases
each time we check, so data is flowing.
We also see that the device has not underrun any samples
(play.errors
).
That's good too.
Note that even if you had speakers plugged in when running the above test, you should not have heard anything. The test sends zeros to the device, which is silence for all currently supported default encodings.
Since we know the device can process data, it's a good idea to check the mixer settings again. Make sure all outputs and all inputs are unmuted and are at a reasonable level.
If you are still having problems at this point, it's probably time to
file a bug report.
Besides the normal bug report information such as a full dmesg and description
of the problem, please also include the default output of
mixerctl -v
and the output of the above test for DAC processing.
To play MIDI data, a synthesizer connected to a MIDI port of the machine is required. Similarly, to record a MIDI data a MIDI instrument is required (such as a MIDI keyboard). Advanced MIDI instruments may contain multiple subparts (synthesizers, keyboards, control surfaces, etc...). They appear as multiple MIDI ports on OpenBSD.
When you already have OpenBSD running, look for MIDI ports in the output of the dmesg(8) command. An example of MIDI ports in a dmesg output is:
umidi0 at uhub2 port 2 configuration 1 interface 0 "Roland Roland XV-2020" rev 1.10/1.00 addr 2 midi0 at umidi0: <USB MIDI I/F> umidi1 at uhub1 port 2 configuration 1 interface 1 "Evolution Electronics Ltd. USB Keystation 61es" rev 1.00/1.25 addr 3 midi1 at umidi1: <USB MIDI I/F>It shows two midi(4) drivers attached, known by programs as:
midi/0
- synthesizer connected via USB
midi/1
- a MIDI master keyboard
$ midicat -q midi/0 -q midi/1Now you can hear what you're playing on the MIDI keyboard on the synthesizer.
The sndiod(8) server exposes MIDI thru ports, allowing programs to send each other MIDI data. For instance, if you have no hardware synthesizer connected, you could start a software one (like the audio/fluidsynth port) and then use it as MIDI output:
$ midicat -q midi/0 -q midithru/0
Most webcams today work according to the USB Video Class (UVC) specification, which is supported by the uvideo(4) device driver and attaches to the video(4) device. The manpage lists some supported devices, but there is a good chance that other devices work as well. For example, webcams in Lenovo Thinkpad laptops do usually work.
A supported webcam (or other video device) shows up in dmesg
like this:
uvideo0 at uhub0 port 8 configuration 1 interface 0 "Azurewave Integrated Camera" rev 2.01/69.05 addr 10 video0 at uvideo0 uvideo1 at uhub0 port 8 configuration 1 interface 2 "Azurewave Integrated Camera" rev 2.01/69.05 addr 10 video1 at uvideo1
You see that an uvideo
device was detected and has
been attached to video0
. This device will be accessible
through /dev/video0
.
Modern laptops sometimes attach a second video device, which is the infrared camera for face recognition. The second camera does not produce a usable video stream.
You can find the usable camera with the video(1) command:
$ video -q -f /dev/video0 video device /dev/video0: encodings: yuy2 frame sizes (width x height, in pixels) and rates (in frames per second): 320x180: 30 320x240: 30 352x288: 30 424x240: 30 640x360: 30 640x480: 30 848x480: 20 960x540: 15 1280x720: 10 controls: brightness, contrast, saturation, hue, gamma, sharpness, white_balance_temperature $ video -q -f /dev/video1 video: /dev/video1 has no usable YUV encodings
The usable camera device shows supported resolutions and framerates. Note that the framerates only apply to the uncompressed YUY2 stream. More on that in Recording a webcam stream.
To use the webcam as regular user, you need to change the device permissions. Only root is allowed to access video devices by default.
# chown $USER /dev/video0
This section uses ffplay
and ffmpeg
from
graphics/ffmpeg
. To find out what your camera is capable of,
run the following command:
$ ffplay -f v4l2 -list_formats all -i /dev/video0 [...] [video4linux2,v4l2 @ 0x921f8420800] Raw : yuyv422 : YUYV : 640x480 320x180 320x240 352x288 424x240 640x360 848x480 960x540 1280x720 [video4linux2,v4l2 @ 0x921f8420800] Compressed: mjpeg : MJPEG : 1280x720 320x180 320x240 352x288 424x240 640x360 640x480 848x480 960x540
At the end of the output, you'll find two lines similiar to the two above.
The first line shows resolutions supported in the uncompressed YUYV format. The frame rates in this format can be very low.
The second line shows the supported MJPEG compressed video resolutions, which deliver much higher framerates (usually 30fps or 60fps).
Now try to play the webcam stream. Choose one of the MJPEG resolutions and run:
$ ffplay -f v4l2 -input_format mjpeg -video_size 1280x720 -i /dev/video0 [...] Input #0, video4linux2,v4l2, from '/dev/video0':B sq= 0B f=0/0 Duration: N/A, start: 1599377893.546533, bitrate: N/A Stream #0:0: Video: mjpeg (Baseline), yuvj422p(pc, bt470bg/unknown/unknown), 1280x720, 30 fps, 30 tbr, 1000k tbn, 1000k tbcThe webcam stream should be displayed. Ffplay also shows the used resolution and the framerate (fps) used.
If this works, you can go ahead and record the video with ffmpeg:
$ ffmpeg -f v4l2 -input_format mjpeg -video_size 1280x720 -i /dev/video0 ~/video.mkvEnd the recording with "q". You have now recorded your stream to file
~/video.mkv
.
Webcams usually have brightness, contrast and other controls. video(1) allows you to alter these settings.
First find out which supported controls your camera has:
$ video -c brightness=128 contrast=32 saturation=64 hue=0 gamma=120 sharpness=3 white_balance_temperature=auto
You can change for example the brightness setting to 200:
$ video brightness=200 brightness: 128 -> 200
If you would like to reset all settings to their defaults, you can do so with:
$ video -d $ video -c brightness=128 contrast=32 saturation=64 hue=0 gamma=120 sharpness=3 white_balance_temperature=auto
Some settings, like the white_balance_temperature
support
automatic adjustments. You can set them to a fixed value or set them to
"auto", which lets the camera decide and use whatever value it thinks is
best.
Chromium has access to /dev/video
by default. To
allow Chromium to access other video devices, you need to add
the device paths to /etc/chromium/unveil.main
and
/etc/chromium/unveil.utility_video
Firefox has access to /dev/video
and /dev/video0
by default. To allow Firefox to access other video devices, you need to
add the device paths to /etc/firefox/unveil.main
.