xmos / xplay

Simple command line based audio file player/recorder
2 stars 5 forks source link

Functionality is a subset of ffmpeg #21

Closed oscarbailey-xmos closed 3 years ago

oscarbailey-xmos commented 3 years ago

ffmpeg can play/record across Mac/Windows/Linux and has more options

https://ffmpeg.org/ffmpeg-devices.html

oscarbailey-xmos commented 3 years ago

My build of ffmpeg (both the homebrew-core version, and the 3rd party version recommended in the ffmpeg docs) only supports SDL as an output device:

(.venv) oscarbailey:~/s/u/s/tests> ffplay -devices
ffplay version 4.3.1 Copyright (c) 2003-2020 the FFmpeg developers
  built with Apple clang version 12.0.0 (clang-1200.0.32.27)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3.1-with-options_6 --enable-shared --cc=clang --host-cflags= --host-ldflags= --enable-gpl --enable-libaom --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-libsnappy --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-demuxer=dash --disable-libjack --disable-indev=jack --enable-opencl --enable-videotoolbox --disable-htmlpages
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
Devices:
 D. = Demuxing supported
 .E = Muxing supported
 --
 D  avfoundation    AVFoundation input device
 D  lavfi           Libavfilter virtual input device
  E sdl,sdl2        SDL2 output device

SDL cannot list or specify devices, so will only output to the default device. The docs for devices shows that AudioToolbox can be used for this, but I've been unable to get any of the examples working: https://ffmpeg.org/ffmpeg-devices.html#AudioToolbox

oscarbailey-xmos commented 3 years ago

EDIT: This is because the audiotoolbox output device is not currently in an FFMPEG release: https://github.com/FFmpeg/FFmpeg/blob/ef59a40c2a0df694cf6f23870f94b6e32deabfe1/Changelog#L5

An example from the docs page: ./ffmpeg -f lavfi -i sine=r=44100 -f audiotoolbox -list_devices true -

The latest binary from this page works, but the 4.3.1 release does not: https://evermeet.cx/ffmpeg/

oscarbailey-xmos commented 3 years ago

ffmpeg also has the ability to generate audio:

(.venv) oscar:~/s/u/s/tests> ffmpeg -filters 2> /dev/null | grep '|->A'
 ... aevalsrc          |->A       Generate an audio signal generated by an expression.
 ... afirsrc           |->A       Generate a FIR coefficients audio stream.
 ... anoisesrc         |->A       Generate a noise audio signal.
 ... anullsrc          |->A       Null audio source, return empty audio frames.
 ... hilbert           |->A       Generate a Hilbert transform FIR coefficients.
 ... sinc              |->A       Generate a sinc kaiser-windowed low-pass, high-pass, band-pass, or band-reject FIR coefficients.
 ... sine              |->A       Generate sine wave audio signal.
 ... abuffer           |->A       Buffer audio frames, and make them accessible to the filterchain.

Particularly useful is the "sine" filter (for generating sine tones), the "anoisesrc" filter, and the "aevalsrc" filter for generating arbitrary audio from an expression. Examples are here: https://www.ffmpeg.org/ffmpeg-all.html#Examples-73

You can use the filters as inputs using:

ffmpeg -f lavfi -i <filter string>

Specify more inputs for mulit-channel, then merge them afterwards:

ffmpeg -f lavfi -i "sine=frequency=100:duration=10" -f lavfi -i "anoisesrc=duration=10" -filter_complex "amerge=inputs=2" test.wav
oscarbailey-xmos commented 3 years ago

I've found that high channel counts are not well supported, and the lack of device selection support makes this an imperfect tool to replace xplay.

I suggest making a pyaudio-powered alternative to xplay, since a lot of our tests use Python so an API would be good, and the code would be cross-platform