static ao_option * dict_to_options(PyObject *dict) { Py_ssize_t pos = 0; PyObject *key, *val; ao_option *head = NULL; int ret; if (!PyDict_Check(dict)) { PyErr_SetString(PyExc_TypeError, "Must be a dictionary"); return NULL; } while (PyDict_Next(dict, &pos, &key, &val) > 0) { if (!PyString_Check(key) || !PyString_Check(val)) { PyErr_SetString(PyExc_TypeError, "Option keys may only be strings"); goto error; } ret = ao_append_option(&head, PyString_AsString(key), PyString_AsString(val)); if (ret == 0) { PyErr_SetString(Py_aoError, "Error appending options"); goto error; } } return head; error: ao_free_options(head); return NULL; }
static ao_device * audio_open_device(shairplay_options_t *opt, int bits, int channels, int samplerate) { ao_device *device = NULL; ao_option *ao_options = NULL; ao_sample_format format; int driver_id; /* Get the libao driver ID */ if (strlen(opt->ao_driver)) { driver_id = ao_driver_id(opt->ao_driver); } else { driver_id = ao_default_driver_id(); } /* Add all available libao options */ if (strlen(opt->ao_devicename)) { ao_append_option(&ao_options, "dev", opt->ao_devicename); } if (strlen(opt->ao_deviceid)) { ao_append_option(&ao_options, "id", opt->ao_deviceid); } /* Set audio format */ memset(&format, 0, sizeof(format)); format.bits = bits; format.channels = channels; format.rate = samplerate; format.byte_format = AO_FMT_NATIVE; /* Try opening the actual device */ device = ao_open_live(driver_id, &format, ao_options); ao_free_options(ao_options); return device; }
int fm_player_open(fm_player_t *pl, fm_player_config_t *config) { pl->config = *config; if (strcmp(config->driver, "pifm") == 0) { float f = atof(config->dev); if (f < 1) f = 102.4; printf("Player audio driver: pifm\n"); printf("Player sample rate: %d Hz\n", config->rate); printf("Player FM fequency: %f Hz\n", f); config->channels = 1; fm_setup_fm(); fm_setup_dma(f); } else { ao_sample_format ao_fmt; ao_fmt.rate = config->rate; ao_fmt.channels = config->channels; ao_fmt.bits = mpg123_encsize(config->encoding) * 8; ao_fmt.byte_format = AO_FMT_NATIVE; ao_fmt.matrix = 0; int driver = ao_driver_id(config->driver); if (driver == -1) { return -1; } ao_info *driver_info = ao_driver_info(driver); printf("Player audio driver: %s\n", driver_info->name); printf("Player sample rate: %d Hz\n", pl->config.rate); ao_option *options = NULL; if (config->dev[0] != '\0') { ao_append_option(&options, "dev", config->dev); } pl->dev = ao_open_live(driver, &ao_fmt, options); ao_free_options(options); if (pl->dev == NULL) return -1; } pl->mh = mpg123_new(NULL, NULL); mpg123_format_none(pl->mh); mpg123_format(pl->mh, config->rate, config->channels, config->encoding); pl->curl = curl_easy_init(); curl_easy_setopt(pl->curl, CURLOPT_WRITEFUNCTION, download_callback); curl_easy_setopt(pl->curl, CURLOPT_WRITEDATA, pl); pl->tid_ack = 0; pthread_mutex_init(&pl->mutex_status, NULL); pthread_cond_init(&pl->cond_play, NULL); pl->status = FM_PLAYER_STOP; return 0; }
/* Clear out all of the library configuration options and set them to defaults. The defaults should match the initializer above. */ static void _clear_config() { memset(ao_global_dummy,0,sizeof(*ao_global_dummy)); ao_global_dummy = NULL; ao_free_options(ao_global_options); ao_global_options = NULL; free(config.default_driver); config.default_driver = NULL; }
static void ao_output_finish(void *data) { struct ao_data *ad = (struct ao_data *)data; ao_free_options(ad->options); g_free(ad); ao_output_ref--; if (ao_output_ref == 0) ao_shutdown(); }
static void ao_output_finish(struct audio_output *ao) { struct ao_data *ad = (struct ao_data *)ao; ao_free_options(ad->options); ao_base_finish(&ad->base); g_free(ad); ao_output_ref--; if (ao_output_ref == 0) ao_shutdown(); }
/* Actually create a new AudioDevice object */ static PyObject* py_ao_new(PyObject *self, PyObject *args, PyObject *kwargs) { uint_32 overwrite, driver_id; const char *filename = NULL; PyObject *py_options = NULL; ao_option *c_options = NULL; ao_device *dev; ao_sample_format sample_format; ao_Object *retobj; if (!parse_args(args, kwargs, &sample_format, &py_options, &filename, &driver_id, &overwrite)) return NULL; if (py_options && PyDict_Size(py_options) > 0) { /* dict_to_options returns NULL on error, so you can't pass an empty dictionary. We can skip this then anyway. */ c_options = dict_to_options(py_options); if (!c_options) { return NULL; } } if (filename == NULL) { dev = ao_open_live(driver_id, &sample_format, c_options); } else { dev = ao_open_file(driver_id, filename, overwrite, &sample_format, c_options); } ao_free_options(c_options); if (dev == NULL) { PyErr_SetString(Py_aoError, "Error opening device."); return NULL; } retobj = (ao_Object *) PyObject_NEW(ao_Object, &ao_Type); retobj->dev = dev; retobj->driver_id = driver_id; return (PyObject *) retobj; }
int main(int argc, char **argv) { int status = 0; struct params par; int opt; signal(SIGHUP, interrupt_handler); signal(SIGINT, interrupt_handler); signal(SIGQUIT, interrupt_handler); ao_initialize(); driver_id = ao_default_driver_id(); memset(¤t_sample_format, 0, sizeof(current_sample_format)); if (argc == 1) { /* We were invoked with no arguments */ usage(argv[0]); goto done; } again: { struct params default_par = DEFAULT_PARAMS; memcpy(&par, &default_par, sizeof(par)); } while ((opt = getopt(argc, argv, "-D:F:L:M:S:b:d:f:o:@:hrv")) != -1) { switch (opt) { case '@': if (play_playlist(optarg, &par)) { status = 1; goto done; } break; case 'D': par.fade_delay = atof(optarg); break; case 'F': par.fade_time = atof(optarg); break; case 'L': par.loop_count = atoi(optarg); break; case 'M': par.min_time = atof(optarg); par.loop_count = -1; break; case 'S': par.stream_index = atoi(optarg); break; case 'b': if (!buffer) buffer_size_kb = atoi(optarg); break; case 'd': driver_id = ao_driver_id(optarg); if (driver_id < 0) { fprintf(stderr, "Invalid output driver \"%s\"\n", optarg); status = 1; goto done; } break; case 'f': out_filename = optarg; break; case 'h': usage(argv[0]); goto done; case 'o': add_driver_option(optarg); break; case 'r': repeat = 1; break; case 'v': verbose = 1; break; default: goto done; } } argc -= optind; argv += optind; for (opt = 0; opt < argc; ++opt) { if (play_file(argv[opt], &par)) { status = 1; goto done; } } if (repeat) { optind = 0; goto again; } done: if (device) ao_close(device); if (buffer) free(buffer); ao_free_options(device_options); ao_shutdown(); return status; }
int sound_lowlevel_init( const char *device, int *freqptr, int *stereoptr ) { ao_option *options = NULL; ao_info *driver_info = NULL; int driver_id = -1; static ao_sample_format format = { .bits = 0 }; /* To prevent recursive errors */ static int sound_lowlevel_init_in_progress = 0; int error; if( sound_lowlevel_init_in_progress ) return 0; sound_lowlevel_init_in_progress = 1; ao_initialize(); error = parse_driver_options( device, &driver_id, &options ); if( error ) { settings_current.sound = 0; sound_lowlevel_init_in_progress = 0; return error; } if( driver_id == -1 ) driver_id = ao_default_driver_id(); if( driver_id == -1 ) { ui_error( UI_ERROR_ERROR, "ao: driver '%s' unknown", device ); settings_current.sound = 0; sound_lowlevel_init_in_progress = 0; return 1; } driver_info = ao_driver_info( driver_id ); if( driver_info->type == AO_TYPE_FILE && format.bits != 0 ) { /* OK. We not want to trunc the file :-) */ ui_error( UI_ERROR_WARNING, "ao: must truncate audio file '%s'", filename ); } format.channels = *stereoptr ? 2 : 1; format.rate = *freqptr; format.bits = settings_current.sound_force_8bit ? 8 : 16; format.byte_format = AO_FMT_LITTLE; sixteenbit = settings_current.sound_force_8bit ? 0 : 1; if( driver_info->type == AO_TYPE_LIVE ) { dev_for_ao = ao_open_live( driver_id, &format, options); } else { if( !filename ) filename = (char *)default_filename; dev_for_ao = ao_open_file( driver_id, filename, 1, &format, options); } if( !dev_for_ao ) { driver_error(); settings_current.sound = 0; sound_lowlevel_init_in_progress = 0; return 1; } ao_free_options( options ); sound_lowlevel_init_in_progress = 0; first_init = 0; return 0; } void sound_lowlevel_end( void ) { if( filename != default_filename ) free( filename ); ao_close(dev_for_ao); ao_shutdown(); } void sound_lowlevel_frame( libspectrum_signed_word *data, int len ) { static signed char buf8[4096]; void *data8 = data; len <<= 1; /* now in bytes */ if( !sixteenbit ) { libspectrum_signed_word *src; signed char *dst; int f; src = data; dst = buf8; len >>= 1; for( f = 0; f < len; f++) *dst++ = ( int )( ( *src++ ) / 256 ); data8 = buf8; } ao_play( dev_for_ao, data8, len ); }