Changeset 4852:166a9cc557c9 in roaraudio for roard/roard.c
- Timestamp:
- 04/10/11 02:12:57 (13 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
roard/roard.c
r4851 r4852 56 56 char * x11display = NULL; 57 57 #endif 58 59 int add_output (char * drv, char * dev, char * opts, int prim, int count);60 58 61 59 void dbg_notify_cb(struct roar_notify_core * core, struct roar_event * event, void * userdata) { … … 965 963 } 966 964 967 #ifdef ROAR_DRIVER_DEFAULT968 #define add_default_output add_output969 #else970 int add_default_output (char * drv, char * dev, char * opts, int prim, int count) {971 char * drvs[] = {972 // operating system depended things:973 #ifdef __OpenBSD__974 /* OpenBSD use sndio natively, this check is discusses with upstream (See ML archive August 2010) */975 "sndio",976 #endif977 // native and pseudo-native interfaces:978 "oss", "alsa", "sndio", "wmm",979 // sound libs:980 "ao", "portaudio",981 // other sound systems:982 "esd", "rsound", "pulsesimple", "roar",983 // specal buildins:984 "sysclock", "null",985 // terminator:986 NULL987 };988 int i;989 int ret;990 int _alive;991 char * _opts;992 993 if ( drv != NULL )994 return add_output(drv, dev, opts, prim, count);995 996 if ( dev != NULL ) {997 ROAR_WARN("add_default_output(drv=(none), dev='%s', opts='%s', prim=%i, count=%i): It's not recommended to use device name without driver name.", dev, opts, prim, count);998 }999 1000 for (i = 0; drvs[i] != NULL; i++) {1001 ROAR_INFO("add_default_output(*): trying driver %s", ROAR_DBG_INFO_INFO, drvs[i]);1002 _alive = alive; // save global alive setting1003 1004 if ( opts == NULL ) {1005 _opts = NULL;1006 } else {1007 _opts = roar_mm_strdup(opts);1008 }1009 1010 ret = add_output(drvs[i], dev, _opts, prim, count);1011 1012 if ( _opts != NULL )1013 roar_mm_free(_opts);1014 1015 if ( ret != -1 )1016 return ret;1017 1018 alive = _alive; // restore global alive setting1019 ROAR_INFO("add_default_output(*): Driver %s faild to load", ROAR_DBG_INFO_VERBOSE, drvs[i]);1020 }1021 1022 return -1;1023 }1024 #endif1025 1026 #define _CKPARAM(n) if ( n (v == NULL) ) { \1027 ROAR_WARN("add_output(drv='%s', dev='%s', opts=..., prim=%i, count=%i): " \1028 "Parameter '%s' expects %s parameter.", \1029 drv, dev, prim, count, k, (n 1) ? "a" : "no"); \1030 error++; \1031 } else1032 1033 int add_output (char * drv, char * dev, char * opts, int prim, int count) {1034 int stream;1035 int default_flags;1036 struct roar_stream * s;1037 struct roar_stream_server * ss;1038 char * k, * v;1039 #ifdef ROAR_DRIVER_CODEC1040 char * to_free = NULL;1041 #endif1042 int sync = 0, f_mmap = 0;1043 int32_t blocks = -1, blocksize = -1;1044 int dir = ROAR_DIR_OUTPUT;1045 int error = 0;1046 // DMX:1047 int32_t channel = -1;1048 int32_t universe = -1;1049 uint16_t tu16;1050 float q = -32e6;1051 1052 ROAR_INFO("add_output(drv='%s', dev='%s', opts='%s', prim=%i, count=%i): trying to add output driver", ROAR_DBG_INFO_INFO, drv, dev, opts, prim, count);1053 1054 if ( drv == NULL && count == 0 ) {1055 #ifdef ROAR_DRIVER_DEFAULT1056 drv = ROAR_DRIVER_DEFAULT;1057 prim = 1;1058 sync = 1;1059 1060 #ifdef ROAR_DRIVER_CODEC1061 if ( opts == NULL ) {1062 opts = to_free = strdup("codec=" ROAR_DRIVER_CODEC);1063 }1064 #endif1065 #else1066 ROAR_ERR("add_output(*): Can not find default driver");1067 return -1;1068 #endif1069 }1070 1071 if ( opts == NULL && count == 0 ) {1072 default_flags = ROAR_FLAG_AUTOCONF|ROAR_FLAG_RECSOURCE;1073 sync = 1;1074 prim = 1; // if ( prim == 0 ) prim = 1; -> prim allways = 11075 }1076 1077 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);1078 1079 if ( (stream = streams_new()) == -1 ) {1080 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts);1081 if ( prim ) alive = 0;1082 return -1;1083 }1084 1085 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);1086 1087 streams_get(stream, &ss);1088 s = ROAR_STREAM(ss);1089 1090 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);1091 1092 memset(&(s->info), 0xFF, sizeof(struct roar_audio_info)); // set everything to -11093 1094 s->pos_rel_id = -1;1095 // s->info.codec = codec;1096 1097 // seting default flags:1098 streams_set_flag(stream, default_flags);1099 1100 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);1101 1102 if ( opts == NULL ) {1103 k = NULL;1104 } else {1105 k = strtok(opts, ",");1106 }1107 1108 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s'): initial k='%s'(%p)", drv, dev, opts, k, k);1109 1110 while (k != NULL) {1111 // ROAR_WARN("add_output(*): opts: %s", k);1112 1113 if ( (v = strstr(k, "=")) != NULL ) {1114 *v++ = 0;1115 }1116 1117 ROAR_DBG("add_output(*): opts: k='%s', v='%s'", k, v);1118 if ( strcmp(k, "rate") == 0 ) {1119 _CKPARAM()1120 s->info.rate = atoi(v);1121 } else if ( strcmp(k, "channels") == 0 ) {1122 _CKPARAM()1123 s->info.channels = atoi(v);1124 } else if ( strcmp(k, "bits") == 0 ) {1125 _CKPARAM()1126 s->info.bits = atoi(v);1127 } else if ( strcmp(k, "codec") == 0 ) {1128 _CKPARAM()1129 if ( (s->info.codec = roar_str2codec(v)) == -1 ) {1130 ROAR_ERR("add_output(*): unknown codec '%s'", v);1131 error++;1132 }1133 } else if ( strcmp(k, "q") == 0 ) {1134 _CKPARAM()1135 q = atof(v);1136 } else if ( strcmp(k, "blocks") == 0 ) {1137 _CKPARAM()1138 blocks = atoi(v);1139 } else if ( strcmp(k, "blocksize") == 0 ) {1140 _CKPARAM()1141 blocksize = atoi(v);1142 } else if ( strcmp(k, "mmap") == 0 ) {1143 _CKPARAM(!)1144 f_mmap = 1;1145 } else if ( strcmp(k, "subsystem") == 0 ) {1146 _CKPARAM() {1147 if ( !strcasecmp(v, "wave") || !strcasecmp(v, "waveform") ) {1148 dir = ROAR_DIR_OUTPUT;1149 #ifndef ROAR_WITHOUT_DCOMP_MIDI1150 } else if ( !strcasecmp(v, "midi") ) {1151 dir = ROAR_DIR_MIDI_OUT;1152 #endif1153 #ifndef ROAR_WITHOUT_DCOMP_LIGHT1154 } else if ( !strcasecmp(v, "light") ) {1155 dir = ROAR_DIR_LIGHT_OUT;1156 #endif1157 #ifndef ROAR_WITHOUT_DCOMP_RAW1158 } else if ( !strcasecmp(v, "raw") ) {1159 dir = ROAR_DIR_RAW_OUT;1160 #endif1161 } else if ( !strcasecmp(v, "complex") ) {1162 dir = ROAR_DIR_COMPLEX_OUT;1163 } else {1164 ROAR_ERR("add_output(*): unknown/unsupported subsystem '%s'", k);1165 error++;1166 }1167 }1168 // DMX:1169 } else if ( strcmp(k, "channel") == 0 ) {1170 _CKPARAM() {1171 channel = atoi(v);1172 if ( channel < 0 || channel > 65535 ) {1173 ROAR_ERR("add_output(*): Invalide channel (not within 0..65535): %i", channel);1174 channel = -1;1175 error++;1176 }1177 }1178 } else if ( strcmp(k, "universe") == 0 ) {1179 _CKPARAM() {1180 universe = atoi(v);1181 if ( universe < 0 || universe > 255 ) {1182 ROAR_ERR("add_output(*): Invalide universe (not within 0..255): %i", universe);1183 universe = -1;1184 error++;1185 }1186 }1187 1188 } else if ( strcmp(k, "name") == 0 ) {1189 _CKPARAM() {1190 if ( streams_set_name(stream, v) == -1 ) {1191 ROAR_ERR("add_output(*): Can not set Stream name");1192 error++;1193 }1194 }1195 1196 } else if ( strcmp(k, "meta") == 0 ) {1197 _CKPARAM(!)1198 streams_set_flag(stream, ROAR_FLAG_META);1199 } else if ( strcmp(k, "sync") == 0 ) {1200 _CKPARAM(!)1201 sync = 1;1202 } else if ( strcmp(k, "primary") == 0 ) {1203 _CKPARAM(!)1204 prim = 1;1205 1206 } else if ( strcmp(k, "cleanmeta") == 0 ) {1207 _CKPARAM(!)1208 streams_set_flag(stream, ROAR_FLAG_CLEANMETA);1209 } else if ( strcmp(k, "autoconf") == 0 ) {1210 _CKPARAM(!)1211 streams_set_flag(stream, ROAR_FLAG_AUTOCONF);1212 } else if ( strcmp(k, "recsource") == 0 ) {1213 _CKPARAM(!)1214 streams_set_flag(stream, ROAR_FLAG_RECSOURCE);1215 } else if ( strcmp(k, "passmixer") == 0 ) {1216 _CKPARAM(!)1217 streams_set_flag(stream, ROAR_FLAG_PASSMIXER);1218 } else if ( strcmp(k, "recsource") == 0 ) {1219 _CKPARAM(!)1220 streams_set_flag(stream, ROAR_FLAG_RECSOURCE);1221 } else {1222 ROAR_ERR("add_output(*): unknown option '%s'", k);1223 error++;1224 }1225 1226 if ( error ) {1227 streams_delete(stream);1228 if ( prim ) alive = 0;1229 #ifdef ROAR_DRIVER_CODEC1230 if ( to_free != NULL )1231 free(to_free);1232 #endif1233 return -1;1234 }1235 1236 k = strtok(NULL, ",");1237 }1238 1239 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);1240 1241 // set audio info...1242 switch (dir) {1243 case ROAR_DIR_LIGHT_OUT:1244 switch (s->info.codec) {1245 case ROAR_CODEC_DMX512:1246 case -1:1247 if ( s->info.rate == -1 )1248 s->info.rate = ROAR_OUTPUT_CFREQ;1249 1250 s->info.channels = 0;1251 s->info.bits = 8;1252 s->info.codec = ROAR_CODEC_DMX512; // in case codec == -11253 break;1254 }1255 break;1256 case ROAR_DIR_MIDI_OUT:1257 switch (s->info.codec) {1258 case ROAR_CODEC_MIDI:1259 case -1:1260 if ( s->info.rate == -1 )1261 s->info.rate = ROAR_MIDI_TICKS_PER_BEAT;1262 1263 s->info.channels = ROAR_MIDI_CHANNELS_DEFAULT;1264 s->info.bits = ROAR_MIDI_BITS;1265 s->info.codec = ROAR_CODEC_MIDI; // in case codec == -11266 break;1267 }1268 break;1269 case ROAR_DIR_RAW_OUT:1270 if ( s->info.rate == -1 )1271 s->info.rate = 0;1272 if ( s->info.bits == -1 )1273 s->info.bits = 0;1274 if ( s->info.channels == -1 )1275 s->info.channels = 0;1276 if ( s->info.codec == -1 )1277 s->info.codec = 0;1278 break;1279 }1280 1281 if ( s->info.rate == -1 )1282 s->info.rate = g_sa->rate;1283 if ( s->info.bits == -1 )1284 s->info.bits = g_sa->bits;1285 if ( s->info.channels == -1 )1286 s->info.channels = g_sa->channels;1287 if ( s->info.codec == -1 )1288 s->info.codec = g_sa->codec;1289 1290 ROAR_DBG("add_output(*): s->info = {.rate=%i, .bits=%i, .channels=%i, .codec=%i}", s->info.rate, s->info.bits, s->info.channels, s->info.codec);1291 1292 if ( streams_set_dir(stream, dir, 1) == -1 ) {1293 streams_delete(stream);1294 return -1;1295 }1296 1297 #ifdef ROAR_DRIVER_CODEC1298 if ( to_free != NULL )1299 free(to_free);1300 #endif1301 1302 if ( s->info.codec == ROAR_CODEC_ALAW || s->info.codec == ROAR_CODEC_MULAW )1303 s->info.bits = 8; // needed to open OSS driver, will be overriden by codecfilter1304 1305 ROAR_STREAM_SERVER(s)->codec_orgi = s->info.codec;1306 1307 if ( driver_openvio(&(ss->vio), &(ss->driver_id), drv, dev, &(s->info), -1, ss) == -1 ) {1308 ss->driver_id = -1; // don't close a driver not opened...1309 memset(&(ss->vio), 0, sizeof(struct roar_vio_calls));1310 streams_delete(stream);1311 if ( prim ) alive = 0;1312 ROAR_ERR("add_output(drv='%s', dev='%s', opts='%s'): can not open output driver.", drv, dev, opts);1313 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts);1314 return -1;1315 }1316 1317 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAMID, &stream); // ignore errors here1318 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAM, s); // ignore errors here1319 1320 if ( blocks != -1 )1321 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DBLOCKS, &blocks);1322 1323 if ( blocksize != -1 )1324 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DBLKSIZE, &blocksize);1325 1326 // TODO: we shoudld *really* check for errors here...1327 if ( channel != -1 ) {1328 tu16 = channel;1329 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DMXSCHAN, &tu16);1330 }1331 if ( universe != -1 ) {1332 tu16 = universe;1333 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DMXUNIV, &tu16);1334 }1335 1336 ROAR_DBG("add_output(*): ss->driver_id=%i", ss->driver_id);1337 1338 streams_set_fh(stream, -1); // update some internal structures1339 1340 if ( q > -1e6 ) {1341 ROAR_DBG("add_output(*): setting q=%f", q);1342 streams_ctl(stream, ROAR_CODECFILTER_CTL_SET_Q|ROAR_STREAM_CTL_TYPE_FLOAT, &q);1343 }1344 1345 client_stream_add(g_self_client, stream);1346 1347 if ( prim ) {1348 streams_mark_primary(stream);1349 s->pos_rel_id = stream;1350 }1351 1352 if ( sync ) {1353 streams_set_flag(stream, ROAR_FLAG_SYNC);1354 } else {1355 streams_reset_flag(stream, ROAR_FLAG_SYNC);1356 }1357 1358 if ( f_mmap )1359 streams_set_flag(stream, ROAR_FLAG_MMAP);1360 1361 ROAR_DBG("add_output(*): s->info = {.rate=%i, .bits=%i, .channels=%i, .codec=%i}", s->info.rate, s->info.bits, s->info.channels, s->info.codec);1362 return 0;1363 }1364 1365 #ifndef ROAR_WITHOUT_DCOMP_MIXER1366 int add_hwmixer (char * drv, char * dev, char * opts, int prim, int count) {1367 char * basename = NULL;1368 char * subnames = NULL;1369 char * k, * v;1370 int basestream = streams_new();1371 int ret;1372 int error = 0;1373 //int hwmixer_open(int basestream, char * drv, char * dev, int fh, char * basename, char * subnames) {1374 1375 if ( basestream == -1 )1376 return -1;1377 1378 client_stream_add(g_self_client, basestream);1379 1380 if ( opts == NULL ) {1381 k = NULL;1382 } else {1383 k = strtok(opts, ",");1384 }1385 1386 while (k != NULL) {1387 // ROAR_WARN("add_output(*): opts: %s", k);1388 1389 if ( (v = strstr(k, "=")) != NULL ) {1390 *v++ = 0;1391 }1392 1393 if ( strcmp(k, "primary") == 0 ) {1394 prim = 1;1395 1396 } else if ( strcmp(k, "name") == 0 ) {1397 basename = v;1398 } else if ( strcmp(k, "subs") == 0 ) {1399 subnames = v;1400 1401 } else if ( strcmp(k, "autoconf") == 0 ) {1402 streams_set_flag(basestream, ROAR_FLAG_AUTOCONF);1403 } else if ( strcmp(k, "passmixer") == 0 ) {1404 streams_set_flag(basestream, ROAR_FLAG_PASSMIXER);1405 } else {1406 ROAR_ERR("add_hwmixer(*): unknown option '%s'", k);1407 error++;1408 }1409 1410 if ( error ) {1411 streams_delete(basestream);1412 if ( prim ) alive = 0;1413 return -1;1414 }1415 1416 k = strtok(NULL, ",");1417 }1418 1419 if ( prim ) {1420 streams_mark_primary(basestream);1421 }1422 1423 ret = hwmixer_open(basestream, drv, dev, -1, basename, subnames);1424 1425 if ( ret == -1 ) {1426 streams_delete(basestream);1427 }1428 1429 return ret == -1 ? -1 : 0;1430 }1431 #endif1432 1433 965 int add_authfile (const char * file, const char * type, enum af_mode mode, enum roard_client_acclev acclev) { 1434 966 struct roar_authfile * authfile = NULL; … … 2147 1679 } else if ( strcmp(k, "-oN") == 0 ) { 2148 1680 if ( action == START || action == RESTART ) { 2149 if ( add_output(o_drv, o_dev, o_opts, o_prim, o_count) != -1 )1681 if ( output_add(o_drv, o_dev, o_opts, o_prim, o_count) != -1 ) 2150 1682 o_count++; 2151 1683 … … 2245 1777 } else if ( strcmp(k, "-mN") == 0 ) { 2246 1778 #ifndef ROAR_WITHOUT_DCOMP_MIXER 2247 if ( add_hwmixer(m_drv, m_dev, m_opts, m_prim, m_count) != -1 )1779 if ( hwmixer_add(m_drv, m_dev, m_opts, m_prim, m_count) != -1 ) 2248 1780 m_count++; 2249 1781 … … 2652 2184 #ifndef ROAR_WITHOUT_DCOMP_MIXER 2653 2185 if ( m_drv != NULL ) { 2654 if ( add_hwmixer(m_drv, m_dev, m_opts, m_prim, m_count) == -1 ) {2186 if ( hwmixer_add(m_drv, m_dev, m_opts, m_prim, m_count) == -1 ) { 2655 2187 ROAR_ERR("main(*): adding mixer '%s' via '%s' failed!", m_dev, m_drv); 2656 2188 } … … 2666 2198 #endif 2667 2199 2668 if ( add_default_output(o_drv, o_dev, o_opts, o_prim, o_count) == -1 ) {2200 if ( output_add_default(o_drv, o_dev, o_opts, o_prim, o_count) == -1 ) { 2669 2201 ROAR_ERR("Can not initialize default driver"); 2670 2202 return 1;
Note: See TracChangeset
for help on using the changeset viewer.