summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/src/s_audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/s_audio.c')
-rw-r--r--apps/plugins/pdbox/PDa/src/s_audio.c872
1 files changed, 0 insertions, 872 deletions
diff --git a/apps/plugins/pdbox/PDa/src/s_audio.c b/apps/plugins/pdbox/PDa/src/s_audio.c
index 4cb93307b0..5f27d98671 100644
--- a/apps/plugins/pdbox/PDa/src/s_audio.c
+++ b/apps/plugins/pdbox/PDa/src/s_audio.c
@@ -871,876 +871,4 @@ void glob_foo(void *dummy, t_symbol *s, int argc, t_atom *argv)
871 } 871 }
872#endif 872#endif
873} 873}
874/* Copyright (c) 2003, Miller Puckette and others.
875* For information on usage and redistribution, and for a DISCLAIMER OF ALL
876* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
877
878/* machine-independent (well, mostly!) audio layer. Stores and recalls
879 audio settings from argparse routine and from dialog window.
880*/
881
882#include "m_pd.h"
883#include "s_stuff.h"
884#include <stdio.h>
885#ifdef UNIX
886#include <unistd.h>
887#include <sys/time.h>
888#include <sys/resource.h>
889#endif
890#include <stdlib.h>
891#include <string.h>
892#include <errno.h>
893
894#define SYS_DEFAULTCH 2
895#define SYS_MAXCH 100
896#define SYS_DEFAULTSRATE 44100
897typedef long t_pa_sample;
898#define SYS_SAMPLEWIDTH sizeof(t_pa_sample)
899#define SYS_BYTESPERCHAN (DEFDACBLKSIZE * SYS_SAMPLEWIDTH)
900#define SYS_XFERSAMPS (SYS_DEFAULTCH*DEFDACBLKSIZE)
901#define SYS_XFERSIZE (SYS_SAMPLEWIDTH * SYS_XFERSAMPS)
902
903 /* these are set in this file when opening audio, but then may be reduced,
904 even to zero, in the system dependent open_audio routines. */
905int sys_inchannels;
906int sys_outchannels;
907int sys_advance_samples; /* scheduler advance in samples */
908int sys_blocksize = 0; /* audio I/O block size in sample frames */
909int sys_audioapi = API_DEFAULT;
910
911static int sys_meters; /* true if we're metering */
912static float sys_inmax; /* max input amplitude */
913static float sys_outmax; /* max output amplitude */
914
915 /* exported variables */
916int sys_schedadvance; /* scheduler advance in microseconds */
917float sys_dacsr;
918
919#ifdef MACOSX
920int sys_hipriority = 1;
921#else
922int sys_hipriority = 0;
923#endif
924
925t_sample *sys_soundout;
926t_sample *sys_soundin;
927
928 /* the "state" is normally one if we're open and zero otherwise;
929 but if the state is one, we still haven't necessarily opened the
930 audio hardware; see audio_isopen() below. */
931static int audio_state;
932
933 /* last requested parameters */
934static int audio_naudioindev;
935static int audio_audioindev[MAXAUDIOINDEV];
936static int audio_audiochindev[MAXAUDIOINDEV];
937static int audio_naudiooutdev;
938static int audio_audiooutdev[MAXAUDIOOUTDEV];
939static int audio_audiochoutdev[MAXAUDIOOUTDEV];
940static int audio_rate;
941static int audio_advance;
942
943static int audio_isopen(void)
944{
945 return (audio_state &&
946 ((audio_naudioindev > 0 && audio_audiochindev[0] > 0)
947 || (audio_naudiooutdev > 0 && audio_audiochoutdev[0] > 0)));
948}
949
950static void sys_get_audio_params(
951 int *pnaudioindev, int *paudioindev, int *chindev,
952 int *pnaudiooutdev, int *paudiooutdev, int *choutdev,
953 int *prate, int *padvance)
954{
955 int i;
956 *pnaudioindev = audio_naudioindev;
957 for (i = 0; i < MAXAUDIOINDEV; i++)
958 paudioindev[i] = audio_audioindev[i],
959 chindev[i] = audio_audiochindev[i];
960 *pnaudiooutdev = audio_naudiooutdev;
961 for (i = 0; i < MAXAUDIOOUTDEV; i++)
962 paudiooutdev[i] = audio_audiooutdev[i],
963 choutdev[i] = audio_audiochoutdev[i];
964 *prate = audio_rate;
965 *padvance = audio_advance;
966}
967
968static void sys_save_audio_params(
969 int naudioindev, int *audioindev, int *chindev,
970 int naudiooutdev, int *audiooutdev, int *choutdev,
971 int rate, int advance)
972{
973 int i;
974 audio_naudioindev = naudioindev;
975 for (i = 0; i < MAXAUDIOINDEV; i++)
976 audio_audioindev[i] = audioindev[i],
977 audio_audiochindev[i] = chindev[i];
978 audio_naudiooutdev = naudiooutdev;
979 for (i = 0; i < MAXAUDIOOUTDEV; i++)
980 audio_audiooutdev[i] = audiooutdev[i],
981 audio_audiochoutdev[i] = choutdev[i];
982 audio_rate = rate;
983 audio_advance = advance;
984}
985
986 /* init routines for any API which needs to set stuff up before
987 any other API gets used. This is only true of OSS so far. */
988#ifdef USEAPI_OSS
989void oss_init(void);
990#endif
991
992static void audio_init( void)
993{
994 static int initted = 0;
995 if (initted)
996 return;
997 initted = 1;
998#ifdef USEAPI_OSS
999 oss_init();
1000#endif
1001}
1002
1003 /* set channels and sample rate. */
1004
1005static void sys_setchsr(int chin, int chout, int sr)
1006{
1007 int nblk;
1008 int inbytes = (chin ? chin : 2) * (DEFDACBLKSIZE*sizeof(float));
1009 int outbytes = (chout ? chout : 2) * (DEFDACBLKSIZE*sizeof(float));
1010
1011 sys_inchannels = chin;
1012 sys_outchannels = chout;
1013 sys_dacsr = sr;
1014 sys_advance_samples = (sys_schedadvance * sys_dacsr) / (1000000.);
1015 if (sys_advance_samples < 3 * DEFDACBLKSIZE)
1016 sys_advance_samples = 3 * DEFDACBLKSIZE;
1017
1018 if (sys_soundin)
1019 free(sys_soundin);
1020 sys_soundin = (t_float *)malloc(inbytes);
1021 memset(sys_soundin, 0, inbytes);
1022
1023 if (sys_soundout)
1024 free(sys_soundout);
1025 sys_soundout = (t_float *)malloc(outbytes);
1026 memset(sys_soundout, 0, outbytes);
1027
1028 if (sys_verbose)
1029 post("input channels = %d, output channels = %d",
1030 sys_inchannels, sys_outchannels);
1031 canvas_resume_dsp(canvas_suspend_dsp());
1032}
1033
1034/* ----------------------- public routines ----------------------- */
1035
1036 /* open audio devices (after cleaning up the specified device and channel
1037 vectors). The audio devices are "zero based" (i.e. "0" means the first
1038 one.) We also save the cleaned-up device specification so that we
1039 can later re-open audio and/or show the settings on a dialog window. */
1040
1041void sys_open_audio(int naudioindev, int *audioindev, int nchindev,
1042 int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev,
1043 int *choutdev, int rate, int advance, int enable)
1044{
1045 int i, *ip;
1046 int defaultchannels = SYS_DEFAULTCH;
1047 int inchans, outchans;
1048 if (rate < 1)
1049 rate = SYS_DEFAULTSRATE;
1050 audio_init();
1051 /* Since the channel vector might be longer than the
1052 audio device vector, or vice versa, we fill the shorter one
1053 in to match the longer one. Also, if both are empty, we fill in
1054 one device (the default) and two channels. */
1055 if (naudioindev == -1)
1056 { /* no input audio devices specified */
1057 if (nchindev == -1)
1058 {
1059 nchindev=1;
1060 chindev[0] = defaultchannels;
1061 naudioindev = 1;
1062 audioindev[0] = DEFAULTAUDIODEV;
1063 }
1064 else
1065 {
1066 for (i = 0; i < MAXAUDIOINDEV; i++)
1067 audioindev[i] = i;
1068 naudioindev = nchindev;
1069 }
1070 }
1071 else
1072 {
1073 if (nchindev == -1)
1074 {
1075 nchindev = naudioindev;
1076 for (i = 0; i < naudioindev; i++)
1077 chindev[i] = defaultchannels;
1078 }
1079 else if (nchindev > naudioindev)
1080 {
1081 for (i = naudioindev; i < nchindev; i++)
1082 {
1083 if (i == 0)
1084 audioindev[0] = DEFAULTAUDIODEV;
1085 else audioindev[i] = audioindev[i-1] + 1;
1086 }
1087 naudioindev = nchindev;
1088 }
1089 else if (nchindev < naudioindev)
1090 {
1091 for (i = nchindev; i < naudioindev; i++)
1092 {
1093 if (i == 0)
1094 chindev[0] = defaultchannels;
1095 else chindev[i] = chindev[i-1];
1096 }
1097 naudioindev = nchindev;
1098 }
1099 }
1100
1101 if (naudiooutdev == -1)
1102 { /* not set */
1103 if (nchoutdev == -1)
1104 {
1105 nchoutdev=1;
1106 choutdev[0]=defaultchannels;
1107 naudiooutdev=1;
1108 audiooutdev[0] = DEFAULTAUDIODEV;
1109 }
1110 else
1111 {
1112 for (i = 0; i < MAXAUDIOOUTDEV; i++)
1113 audiooutdev[i] = i;
1114 naudiooutdev = nchoutdev;
1115 }
1116 }
1117 else
1118 {
1119 if (nchoutdev == -1)
1120 {
1121 nchoutdev = naudiooutdev;
1122 for (i = 0; i < naudiooutdev; i++)
1123 choutdev[i] = defaultchannels;
1124 }
1125 else if (nchoutdev > naudiooutdev)
1126 {
1127 for (i = naudiooutdev; i < nchoutdev; i++)
1128 {
1129 if (i == 0)
1130 audiooutdev[0] = DEFAULTAUDIODEV;
1131 else audiooutdev[i] = audiooutdev[i-1] + 1;
1132 }
1133 naudiooutdev = nchoutdev;
1134 }
1135 else if (nchoutdev < naudiooutdev)
1136 {
1137 for (i = nchoutdev; i < naudiooutdev; i++)
1138 {
1139 if (i == 0)
1140 choutdev[0] = defaultchannels;
1141 else choutdev[i] = choutdev[i-1];
1142 }
1143 naudiooutdev = nchoutdev;
1144 }
1145 }
1146
1147 /* count total number of input and output channels */
1148 for (i = inchans = 0; i < naudioindev; i++)
1149 inchans += chindev[i];
1150 for (i = outchans = 0; i < naudiooutdev; i++)
1151 outchans += choutdev[i];
1152 /* if no input or output devices seem to have been specified,
1153 this really means just disable audio, which we now do. Meanwhile,
1154 we can set audio input and output devices to their defaults. */
1155 if (!inchans && !outchans)
1156 {
1157 enable = 0;
1158 naudioindev = nchindev = naudiooutdev = nchoutdev = 1;
1159 audioindev[0] = audiooutdev[0] = DEFAULTAUDIODEV;
1160 chindev[0] = choutdev[0] = 0;
1161 }
1162 sys_schedadvance = advance * 1000;
1163 sys_setchsr(inchans, outchans, rate);
1164 sys_log_error(ERR_NOTHING);
1165
1166 if (enable && (inchans > 0 || outchans > 0))
1167 {
1168#ifdef USEAPI_PORTAUDIO
1169 if (sys_audioapi == API_PORTAUDIO)
1170 {
1171 int blksize = (sys_blocksize ? sys_blocksize : 64);
1172 pa_open_audio(inchans, outchans, rate, sys_soundin, sys_soundout,
1173 blksize, sys_advance_samples/blksize,
1174 (naudiooutdev > 0 ? audioindev[0] : 0),
1175 (naudiooutdev > 0 ? audiooutdev[0] : 0));
1176 }
1177else
1178#endif
1179#ifdef USEAPI_JACK
1180 if (sys_audioapi == API_JACK)
1181 jack_open_audio((naudioindev > 0 ? chindev[0] : 0),
1182 (naudiooutdev > 0 ? choutdev[0] : 0), rate);
1183
1184 else
1185#endif
1186#ifdef USEAPI_OSS
1187 if (sys_audioapi == API_OSS)
1188 oss_open_audio(naudioindev, audioindev, nchindev, chindev,
1189 naudiooutdev, audiooutdev, nchoutdev, choutdev, rate);
1190 else
1191#endif
1192#ifdef USEAPI_ALSA
1193 /* for alsa, only one device is supported; it may
1194 be open for both input and output. */
1195 if (sys_audioapi == API_ALSA)
1196 alsa_open_audio(naudioindev, audioindev, nchindev, chindev,
1197 naudiooutdev, audiooutdev, nchoutdev, choutdev, rate);
1198 else
1199#endif
1200#ifdef USEAPI_MMIO
1201 if (sys_audioapi == API_MMIO)
1202 mmio_open_audio(naudioindev, audioindev, nchindev, chindev,
1203 naudiooutdev, audiooutdev, nchoutdev, choutdev, rate);
1204 else
1205#endif
1206 post("unknown audio API specified");
1207 }
1208 sys_save_audio_params(naudioindev, audioindev, chindev,
1209 naudiooutdev, audiooutdev, choutdev, rate, advance);
1210 if (sys_inchannels == 0 && sys_outchannels == 0)
1211 enable = 0;
1212 audio_state = enable;
1213 sys_vgui("set pd_whichapi %d\n", (audio_isopen() ? sys_audioapi : 0));
1214 sched_set_using_dacs(enable);
1215}
1216
1217void sys_close_audio(void)
1218{
1219 if (!audio_isopen())
1220 return;
1221#ifdef USEAPI_PORTAUDIO
1222 if (sys_audioapi == API_PORTAUDIO)
1223 pa_close_audio();
1224 else
1225#endif
1226#ifdef USEAPI_JACK
1227 if (sys_audioapi == API_JACK)
1228 jack_close_audio();
1229 else
1230#endif
1231#ifdef USEAPI_OSS
1232 if (sys_audioapi == API_OSS)
1233 oss_close_audio();
1234 else
1235#endif
1236#ifdef USEAPI_ALSA
1237 if (sys_audioapi == API_ALSA)
1238 alsa_close_audio();
1239 else
1240#endif
1241#ifdef USEAPI_MMIO
1242 if (sys_audioapi == API_MMIO)
1243 mmio_close_audio();
1244 else
1245#endif
1246 post("sys_close_audio: unknown API %d", sys_audioapi);
1247 sys_inchannels = sys_outchannels = 0;
1248}
1249
1250 /* open audio using whatever parameters were last used */
1251void sys_reopen_audio( void)
1252{
1253 int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV];
1254 int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV];
1255 int rate, advance;
1256 sys_get_audio_params(&naudioindev, audioindev, chindev,
1257 &naudiooutdev, audiooutdev, choutdev, &rate, &advance);
1258 sys_open_audio(naudioindev, audioindev, naudioindev, chindev,
1259 naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate, advance, 1);
1260}
1261
1262int sys_send_dacs(void)
1263{
1264 if (sys_meters)
1265 {
1266 int i, n;
1267 float maxsamp;
1268 for (i = 0, n = sys_inchannels * DEFDACBLKSIZE, maxsamp = sys_inmax;
1269 i < n; i++)
1270 {
1271 float f = sys_soundin[i];
1272 if (f > maxsamp) maxsamp = f;
1273 else if (-f > maxsamp) maxsamp = -f;
1274 }
1275 sys_inmax = maxsamp;
1276 for (i = 0, n = sys_outchannels * DEFDACBLKSIZE, maxsamp = sys_outmax;
1277 i < n; i++)
1278 {
1279 float f = sys_soundout[i];
1280 if (f > maxsamp) maxsamp = f;
1281 else if (-f > maxsamp) maxsamp = -f;
1282 }
1283 sys_outmax = maxsamp;
1284 }
1285
1286#ifdef USEAPI_PORTAUDIO
1287 if (sys_audioapi == API_PORTAUDIO)
1288 return (pa_send_dacs());
1289 else
1290#endif
1291#ifdef USEAPI_JACK
1292 if (sys_audioapi == API_JACK)
1293 return (jack_send_dacs());
1294 else
1295#endif
1296#ifdef USEAPI_OSS
1297 if (sys_audioapi == API_OSS)
1298 return (oss_send_dacs());
1299 else
1300#endif
1301#ifdef USEAPI_ALSA
1302 if (sys_audioapi == API_ALSA)
1303 return (alsa_send_dacs());
1304 else
1305#endif
1306#ifdef USEAPI_MMIO
1307 if (sys_audioapi == API_MMIO)
1308 return (mmio_send_dacs());
1309 else
1310#endif
1311 post("unknown API");
1312 return (0);
1313}
1314
1315float sys_getsr(void)
1316{
1317 return (sys_dacsr);
1318}
1319
1320int sys_get_outchannels(void)
1321{
1322 return (sys_outchannels);
1323}
1324
1325int sys_get_inchannels(void)
1326{
1327 return (sys_inchannels);
1328}
1329
1330void sys_audiobuf(int n)
1331{
1332 /* set the size, in milliseconds, of the audio FIFO */
1333 if (n < 5) n = 5;
1334 else if (n > 5000) n = 5000;
1335 sys_schedadvance = n * 1000;
1336}
1337
1338void sys_getmeters(float *inmax, float *outmax)
1339{
1340 if (inmax)
1341 {
1342 sys_meters = 1;
1343 *inmax = sys_inmax;
1344 *outmax = sys_outmax;
1345 }
1346 else
1347 sys_meters = 0;
1348 sys_inmax = sys_outmax = 0;
1349}
1350
1351void sys_reportidle(void)
1352{
1353}
1354
1355#define MAXNDEV 20
1356#define DEVDESCSIZE 80
1357
1358static void audio_getdevs(char *indevlist, int *nindevs,
1359 char *outdevlist, int *noutdevs, int *canmulti,
1360 int maxndev, int devdescsize)
1361{
1362 audio_init();
1363#ifdef USEAPI_OSS
1364 if (sys_audioapi == API_OSS)
1365 {
1366 oss_getdevs(indevlist, nindevs, outdevlist, noutdevs, canmulti,
1367 maxndev, devdescsize);
1368 }
1369 else
1370#endif
1371#ifdef USEAPI_ALSA
1372 if (sys_audioapi == API_ALSA)
1373 {
1374 alsa_getdevs(indevlist, nindevs, outdevlist, noutdevs, canmulti,
1375 maxndev, devdescsize);
1376 }
1377 else
1378#endif
1379#ifdef USEAPI_PORTAUDIO
1380 if (sys_audioapi == API_PORTAUDIO)
1381 {
1382 pa_getdevs(indevlist, nindevs, outdevlist, noutdevs, canmulti,
1383 maxndev, devdescsize);
1384 }
1385 else
1386#endif
1387#ifdef USEAPI_MMIO
1388 if (sys_audioapi == API_MMIO)
1389 {
1390 mmio_getdevs(indevlist, nindevs, outdevlist, noutdevs, canmulti,
1391 maxndev, devdescsize);
1392 }
1393 else
1394#endif
1395 {
1396 /* this shouldn't happen once all the above get filled in. */
1397 int i;
1398 *nindevs = *noutdevs = 3;
1399 for (i = 0; i < 3; i++)
1400 {
1401 sprintf(indevlist + i * devdescsize, "input device #%d", i+1);
1402 sprintf(outdevlist + i * devdescsize, "output device #%d", i+1);
1403 }
1404 *canmulti = 0;
1405 }
1406}
1407
1408#ifdef MSW
1409#define DEVONSET 0 /* microsoft device list starts at 0 (the "mapper"). */
1410#else /* (see also MSW ifdef in sys_parsedevlist(), s_main.c) */
1411#define DEVONSET 1 /* To agree with command line flags, normally start at 1 */
1412#endif
1413
1414static void sys_listaudiodevs(void )
1415{
1416 char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE];
1417 int nindevs = 0, noutdevs = 0, i, canmulti = 0;
1418
1419 audio_getdevs(indevlist, &nindevs, outdevlist, &noutdevs, &canmulti,
1420 MAXNDEV, DEVDESCSIZE);
1421
1422 if (!nindevs)
1423 post("no audio input devices found");
1424 else
1425 {
1426 post("input devices:");
1427 for (i = 0; i < nindevs; i++)
1428 post("%d. %s", i+1, indevlist + i * DEVDESCSIZE);
1429 }
1430 if (!noutdevs)
1431 post("no audio output devices found");
1432 else
1433 {
1434 post("output devices:");
1435 for (i = 0; i < noutdevs; i++)
1436 post("%d. %s", i + DEVONSET, outdevlist + i * DEVDESCSIZE);
1437 }
1438 post("API number %d\n", sys_audioapi);
1439}
1440
1441 /* start an audio settings dialog window */
1442void glob_audio_properties(t_pd *dummy, t_floatarg flongform)
1443{
1444 char buf[1024 + 2 * MAXNDEV*(DEVDESCSIZE+4)];
1445 /* these are the devices you're using: */
1446 int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV];
1447 int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV];
1448 int audioindev1, audioindev2, audioindev3, audioindev4,
1449 audioinchan1, audioinchan2, audioinchan3, audioinchan4,
1450 audiooutdev1, audiooutdev2, audiooutdev3, audiooutdev4,
1451 audiooutchan1, audiooutchan2, audiooutchan3, audiooutchan4;
1452 int rate, advance;
1453 /* these are all the devices on your system: */
1454 char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE];
1455 int nindevs = 0, noutdevs = 0, canmulti = 0, i;
1456
1457 char indevliststring[MAXNDEV*(DEVDESCSIZE+4)+80],
1458 outdevliststring[MAXNDEV*(DEVDESCSIZE+4)+80];
1459
1460 audio_getdevs(indevlist, &nindevs, outdevlist, &noutdevs, &canmulti,
1461 MAXNDEV, DEVDESCSIZE);
1462
1463 strcpy(indevliststring, "{");
1464 for (i = 0; i < nindevs; i++)
1465 {
1466 strcat(indevliststring, "\"");
1467 strcat(indevliststring, indevlist + i * DEVDESCSIZE);
1468 strcat(indevliststring, "\" ");
1469 }
1470 strcat(indevliststring, "}");
1471
1472 strcpy(outdevliststring, "{");
1473 for (i = 0; i < noutdevs; i++)
1474 {
1475 strcat(outdevliststring, "\"");
1476 strcat(outdevliststring, outdevlist + i * DEVDESCSIZE);
1477 strcat(outdevliststring, "\" ");
1478 }
1479 strcat(outdevliststring, "}");
1480
1481 sys_get_audio_params(&naudioindev, audioindev, chindev,
1482 &naudiooutdev, audiooutdev, choutdev, &rate, &advance);
1483
1484 /* post("naudioindev %d naudiooutdev %d longform %f",
1485 naudioindev, naudiooutdev, flongform); */
1486 if (naudioindev > 1 || naudiooutdev > 1)
1487 flongform = 1;
1488
1489
1490 audioindev1 = (naudioindev > 0 && audioindev[0]>= 0 ? audioindev[0] : 0);
1491 audioindev2 = (naudioindev > 1 && audioindev[1]>= 0 ? audioindev[1] : 0);
1492 audioindev3 = (naudioindev > 2 && audioindev[2]>= 0 ? audioindev[2] : 0);
1493 audioindev4 = (naudioindev > 3 && audioindev[3]>= 0 ? audioindev[3] : 0);
1494 audioinchan1 = (naudioindev > 0 ? chindev[0] : 0);
1495 audioinchan2 = (naudioindev > 1 ? chindev[1] : 0);
1496 audioinchan3 = (naudioindev > 2 ? chindev[2] : 0);
1497 audioinchan4 = (naudioindev > 3 ? chindev[3] : 0);
1498 audiooutdev1 = (naudiooutdev > 0 && audiooutdev[0]>=0 ? audiooutdev[0] : 0);
1499 audiooutdev2 = (naudiooutdev > 1 && audiooutdev[1]>=0 ? audiooutdev[1] : 0);
1500 audiooutdev3 = (naudiooutdev > 2 && audiooutdev[2]>=0 ? audiooutdev[2] : 0);
1501 audiooutdev4 = (naudiooutdev > 3 && audiooutdev[3]>=0 ? audiooutdev[3] : 0);
1502 audiooutchan1 = (naudiooutdev > 0 ? choutdev[0] : 0);
1503 audiooutchan2 = (naudiooutdev > 1 ? choutdev[1] : 0);
1504 audiooutchan3 = (naudiooutdev > 2 ? choutdev[2] : 0);
1505 audiooutchan4 = (naudiooutdev > 3 ? choutdev[3] : 0);
1506 sprintf(buf,
1507"pdtk_audio_dialog %%s \
1508%s %d %d %d %d %d %d %d %d \
1509%s %d %d %d %d %d %d %d %d \
1510%d %d %d %d\n",
1511 indevliststring,
1512 audioindev1, audioindev2, audioindev3, audioindev4,
1513 audioinchan1, audioinchan2, audioinchan3, audioinchan4,
1514 outdevliststring,
1515 audiooutdev1, audiooutdev2, audiooutdev3, audiooutdev4,
1516 audiooutchan1, audiooutchan2, audiooutchan3, audiooutchan4,
1517 rate, advance, canmulti, (flongform != 0));
1518 gfxstub_deleteforkey(0);
1519 gfxstub_new(&glob_pdobject, glob_audio_properties, buf);
1520}
1521
1522 /* new values from dialog window */
1523void glob_audio_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv)
1524{
1525 int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV];
1526 int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV];
1527 int rate, advance, audioon, i, nindev, noutdev;
1528 int audioindev1, audioinchan1, audiooutdev1, audiooutchan1;
1529 int newaudioindev[4], newaudioinchan[4],
1530 newaudiooutdev[4], newaudiooutchan[4];
1531 /* the new values the dialog came back with: */
1532 int newrate = atom_getintarg(16, argc, argv);
1533 int newadvance = atom_getintarg(17, argc, argv);
1534 int statewas;
1535
1536 for (i = 0; i < 4; i++)
1537 {
1538 newaudioindev[i] = atom_getintarg(i, argc, argv);
1539 newaudioinchan[i] = atom_getintarg(i+4, argc, argv);
1540 newaudiooutdev[i] = atom_getintarg(i+8, argc, argv);
1541 newaudiooutchan[i] = atom_getintarg(i+12, argc, argv);
1542 }
1543
1544 for (i = 0, nindev = 0; i < 4; i++)
1545 {
1546 if (newaudioinchan[i] > 0)
1547 {
1548 newaudioindev[nindev] = newaudioindev[i];
1549 newaudioinchan[nindev] = newaudioinchan[i];
1550 /* post("in %d %d %d", nindev,
1551 newaudioindev[nindev] , newaudioinchan[nindev]); */
1552 nindev++;
1553 }
1554 }
1555 for (i = 0, noutdev = 0; i < 4; i++)
1556 {
1557 if (newaudiooutchan[i] > 0)
1558 {
1559 newaudiooutdev[noutdev] = newaudiooutdev[i];
1560 newaudiooutchan[noutdev] = newaudiooutchan[i];
1561 /* post("out %d %d %d", noutdev,
1562 newaudiooutdev[noutdev] , newaudioinchan[noutdev]); */
1563 noutdev++;
1564 }
1565 }
1566
1567 sys_close_audio();
1568 sys_open_audio(nindev, newaudioindev, nindev, newaudioinchan,
1569 noutdev, newaudiooutdev, noutdev, newaudiooutchan,
1570 newrate, newadvance, 1);
1571}
1572
1573void sys_listdevs(void )
1574{
1575#ifdef USEAPI_PORTAUDIO
1576 if (sys_audioapi == API_PORTAUDIO)
1577 sys_listaudiodevs();
1578 else
1579#endif
1580#ifdef USEAPI_JACK
1581 if (sys_audioapi == API_JACK)
1582 jack_listdevs();
1583 else
1584#endif
1585#ifdef USEAPI_OSS
1586 if (sys_audioapi == API_OSS)
1587 sys_listaudiodevs();
1588 else
1589#endif
1590#ifdef USEAPI_MMIO
1591 if (sys_audioapi == API_MMIO)
1592 sys_listaudiodevs();
1593 else
1594#endif
1595#ifdef USEAPI_ALSA
1596 if (sys_audioapi == API_ALSA)
1597 sys_listaudiodevs();
1598 else
1599#endif
1600 post("unknown API");
1601
1602 sys_listmididevs();
1603}
1604
1605void sys_setblocksize(int n)
1606{
1607 if (n < 1)
1608 n = 1;
1609 if (n != (1 << ilog2(n)))
1610 post("warning: adjusting blocksize to power of 2: %d",
1611 (n = (1 << ilog2(n))));
1612 sys_blocksize = n;
1613}
1614
1615void sys_set_audio_api(int which)
1616{
1617 sys_audioapi = which;
1618 if (sys_verbose)
1619 post("sys_audioapi %d", sys_audioapi);
1620}
1621
1622void glob_audio_setapi(void *dummy, t_floatarg f)
1623{
1624 int newapi = f;
1625 if (newapi)
1626 {
1627 if (newapi == sys_audioapi)
1628 {
1629 if (!audio_isopen())
1630 sys_reopen_audio();
1631 }
1632 else
1633 {
1634 sys_close_audio();
1635 sys_audioapi = newapi;
1636 /* bash device params back to default */
1637 audio_naudioindev = audio_naudiooutdev = 1;
1638 audio_audioindev[0] = audio_audiooutdev[0] = DEFAULTAUDIODEV;
1639 audio_audiochindev[0] = audio_audiochoutdev[0] = SYS_DEFAULTCH;
1640 sys_reopen_audio();
1641 }
1642 glob_audio_properties(0, 0);
1643 }
1644 else if (audio_isopen())
1645 {
1646 sys_close_audio();
1647 audio_state = 0;
1648 sched_set_using_dacs(0);
1649 }
1650}
1651 874
1652 /* start or stop the audio hardware */
1653void sys_set_audio_state(int onoff)
1654{
1655 if (onoff) /* start */
1656 {
1657 if (!audio_isopen())
1658 sys_reopen_audio();
1659 }
1660 else
1661 {
1662 if (audio_isopen())
1663 {
1664 sys_close_audio();
1665 sched_set_using_dacs(0);
1666 }
1667 }
1668 audio_state = onoff;
1669}
1670
1671void sys_get_audio_apis(char *buf)
1672{
1673 int n = 0;
1674 strcpy(buf, "{ ");
1675#ifdef USEAPI_OSS
1676 sprintf(buf + strlen(buf), "{OSS %d} ", API_OSS); n++;
1677#endif
1678#ifdef USEAPI_MMIO
1679 sprintf(buf + strlen(buf), "{\"standard (MMIO)\" %d} ", API_MMIO); n++;
1680#endif
1681#ifdef USEAPI_ALSA
1682 sprintf(buf + strlen(buf), "{ALSA %d} ", API_ALSA); n++;
1683#endif
1684#ifdef USEAPI_PORTAUDIO
1685#ifdef MSW
1686 sprintf(buf + strlen(buf),
1687 "{\"ASIO (via portaudio)\" %d} ", API_PORTAUDIO);
1688#else
1689#ifdef OSX
1690 sprintf(buf + strlen(buf),
1691 "{\"standard (portaudio)\" %d} ", API_PORTAUDIO);
1692#else
1693 sprintf(buf + strlen(buf), "{portaudio %d} ", API_PORTAUDIO);
1694#endif
1695#endif
1696 n++;
1697#endif
1698#ifdef USEAPI_JACK
1699 sprintf(buf + strlen(buf), "{jack %d} ", API_JACK); n++;
1700#endif
1701 strcat(buf, "}");
1702 /* then again, if only one API (or none) we don't offer any choice. */
1703 if (n < 2)
1704 strcpy(buf, "{}");
1705
1706}
1707
1708#ifdef USEAPI_ALSA
1709void alsa_putzeros(int n);
1710void alsa_getzeros(int n);
1711void alsa_printstate( void);
1712#endif
1713
1714 /* debugging */
1715void glob_foo(void *dummy, t_symbol *s, int argc, t_atom *argv)
1716{
1717 t_symbol *arg = atom_getsymbolarg(0, argc, argv);
1718 if (arg == gensym("restart"))
1719 {
1720 int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV];
1721 int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV];
1722 int rate, advance;
1723 sys_get_audio_params(&naudioindev, audioindev, chindev,
1724 &naudiooutdev, audiooutdev, choutdev, &rate, &advance);
1725 sys_close_audio();
1726 sys_open_audio(naudioindev, audioindev, naudioindev, chindev,
1727 naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate, advance,
1728 1);
1729 }
1730#ifdef USEAPI_ALSA
1731 else if (arg == gensym("alsawrite"))
1732 {
1733 int n = atom_getintarg(1, argc, argv);
1734 alsa_putzeros(n);
1735 }
1736 else if (arg == gensym("alsaread"))
1737 {
1738 int n = atom_getintarg(1, argc, argv);
1739 alsa_getzeros(n);
1740 }
1741 else if (arg == gensym("print"))
1742 {
1743 alsa_printstate();
1744 }
1745#endif
1746}