[0] | 1 | /* |
---|
| 2 | * |
---|
| 3 | * ao_roar.c |
---|
| 4 | * |
---|
[3232] | 5 | * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2010 |
---|
[0] | 6 | * based on ao_esd.c of libao by Stan Seibert - July 2000, July 2001 |
---|
| 7 | * |
---|
| 8 | * This file is part of RoarAudio, a cross-platform sound server. See |
---|
| 9 | * README for a history of this source code. |
---|
| 10 | * |
---|
| 11 | * This file is free software; you can redistribute it and/or modify |
---|
| 12 | * it under the terms of the GNU General Public License as published by |
---|
[3516] | 13 | * the Free Software Foundation; either version 2, or (at your opinion) |
---|
[0] | 14 | * any later version. |
---|
| 15 | * |
---|
| 16 | * RoarAudio is distributed in the hope that it will be useful, |
---|
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 19 | * GNU General Public License for more details. |
---|
| 20 | * |
---|
| 21 | * You should have received a copy of the GNU General Public License |
---|
| 22 | * along with GNU Make; see the file COPYING. If not, write to |
---|
[3517] | 23 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, |
---|
| 24 | * Boston, MA 02110-1301, USA. |
---|
[0] | 25 | * |
---|
| 26 | */ |
---|
| 27 | |
---|
| 28 | #include <stdio.h> |
---|
| 29 | #include <unistd.h> |
---|
| 30 | #include <stdlib.h> |
---|
| 31 | #include <string.h> |
---|
| 32 | |
---|
| 33 | #include <roaraudio.h> |
---|
| 34 | #include <ao/ao.h> |
---|
| 35 | #include <ao/plugin.h> |
---|
| 36 | |
---|
| 37 | static char * ao_roar_options[] = {"host"}; |
---|
| 38 | |
---|
| 39 | /* |
---|
| 40 | typedef struct ao_info { |
---|
| 41 | int type; // live output or file output? |
---|
| 42 | char *name; // full name of driver |
---|
| 43 | char *short_name; // short name of driver |
---|
| 44 | char *author; // driver author |
---|
| 45 | char *comment; // driver comment |
---|
| 46 | int preferred_byte_format; |
---|
| 47 | int priority; |
---|
| 48 | char **options; |
---|
| 49 | int option_count; |
---|
| 50 | } ao_info; |
---|
| 51 | */ |
---|
| 52 | |
---|
| 53 | static ao_info ao_roar_info = |
---|
| 54 | { |
---|
| 55 | AO_TYPE_LIVE, |
---|
| 56 | "RoarAudio output", |
---|
| 57 | "roar", |
---|
| 58 | "Philipp 'ph3-der-loewe' Schafft, Based on code by: Stan Seibert <volsung@asu.edu>", |
---|
| 59 | "Outputs to the RoarAudio Sound Daemon.", |
---|
| 60 | AO_FMT_NATIVE, |
---|
[3230] | 61 | 50, |
---|
[0] | 62 | ao_roar_options, |
---|
| 63 | 1 |
---|
| 64 | }; |
---|
| 65 | |
---|
| 66 | |
---|
| 67 | typedef struct ao_roar_internal { |
---|
[3231] | 68 | struct roar_vio_calls svio; |
---|
[0] | 69 | char * host; |
---|
| 70 | } ao_roar_internal; |
---|
| 71 | |
---|
| 72 | |
---|
| 73 | int ao_plugin_test(void) { |
---|
| 74 | struct roar_connection con; |
---|
| 75 | |
---|
| 76 | if ( roar_simple_connect(&con, NULL, "libao client") == -1 ) |
---|
| 77 | return 0; |
---|
| 78 | |
---|
| 79 | if (roar_get_standby(&con)) { |
---|
| 80 | roar_disconnect(&con); |
---|
| 81 | return 0; |
---|
| 82 | } |
---|
| 83 | |
---|
| 84 | roar_disconnect(&con); |
---|
| 85 | return 1; |
---|
| 86 | } |
---|
| 87 | |
---|
| 88 | |
---|
| 89 | ao_info * ao_plugin_driver_info(void) { |
---|
| 90 | return &ao_roar_info; |
---|
| 91 | } |
---|
| 92 | |
---|
| 93 | |
---|
| 94 | int ao_plugin_device_init(ao_device * device) { |
---|
| 95 | ao_roar_internal * internal; |
---|
| 96 | |
---|
| 97 | internal = (ao_roar_internal *) malloc(sizeof(ao_roar_internal)); |
---|
| 98 | |
---|
| 99 | if (internal == NULL) |
---|
| 100 | return 0; |
---|
| 101 | |
---|
| 102 | internal->host = NULL; |
---|
| 103 | |
---|
| 104 | device->internal = internal; |
---|
| 105 | |
---|
| 106 | return 1; |
---|
| 107 | } |
---|
| 108 | |
---|
| 109 | int ao_plugin_set_option(ao_device * device, const char * key, const char * value) { |
---|
| 110 | ao_roar_internal * internal = (ao_roar_internal *) device->internal; |
---|
| 111 | |
---|
| 112 | if ( strcmp(key, "host") == 0 ) { |
---|
| 113 | if(internal->host) free(internal->host); |
---|
| 114 | internal->host = strdup(value); |
---|
| 115 | } |
---|
| 116 | |
---|
| 117 | return 1; |
---|
| 118 | } |
---|
| 119 | |
---|
| 120 | int ao_plugin_open(ao_device * device, ao_sample_format * format) { |
---|
| 121 | ao_roar_internal * internal = (ao_roar_internal *) device->internal; |
---|
[3235] | 122 | #ifdef HAVE_MATRIX |
---|
| 123 | char * map = NULL; |
---|
| 124 | #endif |
---|
[0] | 125 | |
---|
[3231] | 126 | if ( roar_vio_simple_stream(&(internal->svio), format->rate, format->channels, format->bits, |
---|
| 127 | ROAR_CODEC_DEFAULT, internal->host, ROAR_DIR_PLAY, "libao client") == -1 ) |
---|
[0] | 128 | return 0; |
---|
| 129 | |
---|
| 130 | device->driver_byte_format = AO_FMT_NATIVE; |
---|
| 131 | |
---|
[3235] | 132 | #ifdef HAVE_MATRIX |
---|
| 133 | if( device->output_matrix != NULL ) |
---|
| 134 | free(device->output_matrix); |
---|
| 135 | |
---|
| 136 | device->output_matrix = NULL; |
---|
| 137 | |
---|
| 138 | switch (format->channels) { |
---|
| 139 | case 1: map = "M"; break; |
---|
| 140 | case 2: map = "L,R"; break; |
---|
| 141 | case 3: map = "L,R,C"; break; |
---|
| 142 | case 4: map = "L,R,BL,BR"; break; |
---|
| 143 | case 5: map = "L,R,C,BL,BR"; break; |
---|
| 144 | case 6: map = "L,R,C,LFE,BL,BR"; break; |
---|
| 145 | } |
---|
| 146 | |
---|
| 147 | if ( map != NULL ) |
---|
| 148 | device->output_matrix = strdup(map); |
---|
| 149 | #endif |
---|
| 150 | |
---|
[0] | 151 | return 1; |
---|
| 152 | } |
---|
| 153 | |
---|
| 154 | int ao_plugin_play(ao_device * device, const char * output_samples, uint_32 num_bytes) { |
---|
| 155 | ao_roar_internal * internal = (ao_roar_internal *) device->internal; |
---|
| 156 | |
---|
[3231] | 157 | if (roar_vio_write(&(internal->svio), (char*)output_samples, num_bytes) == -1) { |
---|
[0] | 158 | return 0; |
---|
| 159 | } else { |
---|
| 160 | return 1; |
---|
| 161 | } |
---|
| 162 | } |
---|
| 163 | |
---|
| 164 | |
---|
| 165 | int ao_plugin_close(ao_device * device) { |
---|
| 166 | ao_roar_internal * internal = (ao_roar_internal *) device->internal; |
---|
| 167 | |
---|
[3231] | 168 | roar_vio_close(&(internal->svio)); |
---|
[0] | 169 | |
---|
| 170 | return 1; |
---|
| 171 | } |
---|
| 172 | |
---|
| 173 | |
---|
| 174 | void ao_plugin_device_clear(ao_device * device) { |
---|
| 175 | ao_roar_internal * internal = (ao_roar_internal *) device->internal; |
---|
| 176 | |
---|
| 177 | if( internal->host != NULL ) |
---|
| 178 | free(internal->host); |
---|
| 179 | |
---|
| 180 | free(internal); |
---|
| 181 | } |
---|