libao icon indicating copy to clipboard operation
libao copied to clipboard

Plugin with static linking

Open alvarolb opened this issue 6 years ago • 1 comments

Hi! Is it possible to include a plugin like Alsa, as a built-in driver? Thanks!

alvarolb avatar Feb 16 '19 01:02 alvarolb

Yeah you can manipulate the static_drivers mechanism. Here is how to do:

  1. First remove the static from following line so you can manipulate this array within your code afterwards: https://github.com/xiph/libao/blob/20dc8ed9fa4605f5c25e7496ede42e8ba6468225/src/audio_out.c#L87

  2. Build libao with --enable-alsa and --enable-static (this will also build you a static libalsa.a plugin)

  3. In your main code do the following

#include <ao/ao.h>
#include <ao/plugin.h>

// declaration from include/ao/ao_private.h
struct ao_functions {
	int (*test)(void);
	ao_info* (*driver_info)(void);
	int (*device_init)(ao_device *device);
	int (*set_option)(ao_device *device, const char *key,
			  const char *value);
	int (*open)(ao_device *device, ao_sample_format *format);
	int (*play)(ao_device *device, const char *output_samples,
			   uint_32 num_bytes);
	int (*close)(ao_device *device);
	void (*device_clear)(ao_device *device);
	const char* (*file_extension)(void);
};

// declare the plugin symbols. We will get them later when 
// linking against the static plugin lib (i.e. libalsa.a)
ao_functions ao_generic_plugin = {
	ao_plugin_test,
	ao_plugin_driver_info,
	ao_plugin_device_init,
	ao_plugin_set_option,
	ao_plugin_open,
	ao_plugin_play,
	ao_plugin_close,
	ao_plugin_device_clear
       //ao_plugin_file_extension
};

// gain access to the static_drivers array from libao.a, 
// this is now possible because we removed the static in audio_out.c
extern ao_functions* static_drivers[];

int main(int argc, char** argv)
{
    // override the null driver with the plugin (i.e. alsa) driver
    static_drivers[0] = &ao_generic_plugin;
    ao_initialize();
   // .... 
   // do awesome stuff here
   // ....
   return 0;
}
  1. link your executable with -lao -lalsa -lasound
  2. profit

Depending on your alsa setup this might or might not work.

Here a fully working example (completely statically linked, including source code). You may need to tweak the alsa config files within the alsa_config directory to make it work on your device. Execute wavplay.linux_x86_64_musl --file test.wav to hear the WAV file.

wavplay_example.tar.gz

(I use https://github.com/nwrkbiz/static-build to build my dependencies (->3rdParty folder missing in the *.tar.gz archive), this already applies the 'remove static hack' on libao.)

nwrkbiz avatar Oct 22 '20 23:10 nwrkbiz