diff options
author | Peter D'Hoye <peter.dhoye@gmail.com> | 2009-05-24 21:28:16 +0000 |
---|---|---|
committer | Peter D'Hoye <peter.dhoye@gmail.com> | 2009-05-24 21:28:16 +0000 |
commit | 526b5580dabbfed7cfe5439dc3a90ec727f563c2 (patch) | |
tree | 22b1af92348785daad16714ee5e2b633017e0e48 /apps/plugins/pdbox/PDa/src/s_audio.c | |
parent | 4f2dfcc01b260d946044ef2b6af5fe36cb772c8d (diff) | |
download | rockbox-526b5580dabbfed7cfe5439dc3a90ec727f563c2.tar.gz rockbox-526b5580dabbfed7cfe5439dc3a90ec727f563c2.zip |
Cut the files in half and it might work better (note to self: check your tree is really clean before patching)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21070 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/s_audio.c')
-rw-r--r-- | apps/plugins/pdbox/PDa/src/s_audio.c | 872 |
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 | ||
897 | typedef 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. */ | ||
905 | int sys_inchannels; | ||
906 | int sys_outchannels; | ||
907 | int sys_advance_samples; /* scheduler advance in samples */ | ||
908 | int sys_blocksize = 0; /* audio I/O block size in sample frames */ | ||
909 | int sys_audioapi = API_DEFAULT; | ||
910 | |||
911 | static int sys_meters; /* true if we're metering */ | ||
912 | static float sys_inmax; /* max input amplitude */ | ||
913 | static float sys_outmax; /* max output amplitude */ | ||
914 | |||
915 | /* exported variables */ | ||
916 | int sys_schedadvance; /* scheduler advance in microseconds */ | ||
917 | float sys_dacsr; | ||
918 | |||
919 | #ifdef MACOSX | ||
920 | int sys_hipriority = 1; | ||
921 | #else | ||
922 | int sys_hipriority = 0; | ||
923 | #endif | ||
924 | |||
925 | t_sample *sys_soundout; | ||
926 | t_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. */ | ||
931 | static int audio_state; | ||
932 | |||
933 | /* last requested parameters */ | ||
934 | static int audio_naudioindev; | ||
935 | static int audio_audioindev[MAXAUDIOINDEV]; | ||
936 | static int audio_audiochindev[MAXAUDIOINDEV]; | ||
937 | static int audio_naudiooutdev; | ||
938 | static int audio_audiooutdev[MAXAUDIOOUTDEV]; | ||
939 | static int audio_audiochoutdev[MAXAUDIOOUTDEV]; | ||
940 | static int audio_rate; | ||
941 | static int audio_advance; | ||
942 | |||
943 | static 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 | |||
950 | static 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 | |||
968 | static 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 | ||
989 | void oss_init(void); | ||
990 | #endif | ||
991 | |||
992 | static 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 | |||
1005 | static 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 | |||
1041 | void 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 | } | ||
1177 | else | ||
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 | |||
1217 | void 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 */ | ||
1251 | void 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 | |||
1262 | int 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 | |||
1315 | float sys_getsr(void) | ||
1316 | { | ||
1317 | return (sys_dacsr); | ||
1318 | } | ||
1319 | |||
1320 | int sys_get_outchannels(void) | ||
1321 | { | ||
1322 | return (sys_outchannels); | ||
1323 | } | ||
1324 | |||
1325 | int sys_get_inchannels(void) | ||
1326 | { | ||
1327 | return (sys_inchannels); | ||
1328 | } | ||
1329 | |||
1330 | void 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 | |||
1338 | void 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 | |||
1351 | void sys_reportidle(void) | ||
1352 | { | ||
1353 | } | ||
1354 | |||
1355 | #define MAXNDEV 20 | ||
1356 | #define DEVDESCSIZE 80 | ||
1357 | |||
1358 | static 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 | |||
1414 | static 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 */ | ||
1442 | void 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 */ | ||
1523 | void 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 | |||
1573 | void 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 | |||
1605 | void 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 | |||
1615 | void sys_set_audio_api(int which) | ||
1616 | { | ||
1617 | sys_audioapi = which; | ||
1618 | if (sys_verbose) | ||
1619 | post("sys_audioapi %d", sys_audioapi); | ||
1620 | } | ||
1621 | |||
1622 | void 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 */ | ||
1653 | void 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 | |||
1671 | void 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 | ||
1709 | void alsa_putzeros(int n); | ||
1710 | void alsa_getzeros(int n); | ||
1711 | void alsa_printstate( void); | ||
1712 | #endif | ||
1713 | |||
1714 | /* debugging */ | ||
1715 | void 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 | } | ||