int main(int argc, char **argv) { ps8_t volume_name = NULL; u128 volume_size = 0; u128 cluster_size = 0; struct mfs_volume* volume = NULL; static int auto_create_loopback_flag = 0; while(1) { int c; static const struct option long_options[] = { { "auto", no_argument, &auto_create_loopback_flag, 1 }, { "name", required_argument, NULL, 'n' }, { "size", required_argument, NULL, 's' }, { "clustersize", required_argument, NULL, 'c' }, { NULL, 0, NULL, 0 } }; c = getopt_long(argc, argv, "n:s:c:", long_options, NULL); if (c < 0) break; switch(c) { case 0: break; case 'n': volume_name = strdup(optarg); break; case 's': volume_size = parse_size(optarg); break; case 'c': cluster_size = parse_size(optarg); break; case GETOPT_VAL_HELP: default: print_usage(c != GETOPT_VAL_HELP); } } if (auto_create_loopback_flag) { if (volume_name == NULL) { printf("ERROR: Set the volume name\n"); exit(1); } if (volume_size <= 0) { printf("ERROR: Set the correct volume size\n"); exit(1); } volume = create_loopback(volume_name); } else { char* device_name = argv[optind]; if (device_name == NULL) { printf("ERROR: Set the correct device name\n"); exit(1); } volume = open_device(device_name, &volume_size); } if (cluster_size <= 0) { printf("ERROR: Set the correct cluster size\n"); exit(1); } create_volume(volume, volume_name, volume_size, cluster_size); if (volume != NULL) { print_volume_status(volume); free_volume(volume); } return 0; }
static int parse_config(int argc, char *argv[], snd_output_t *output, int cmdline) { struct option long_option[] = { {"help", 0, NULL, 'h'}, {"config", 1, NULL, 'g'}, {"daemonize", 0, NULL, 'd'}, {"pdevice", 1, NULL, 'P'}, {"cdevice", 1, NULL, 'C'}, {"pctl", 1, NULL, 'X'}, {"cctl", 1, NULL, 'Y'}, {"latency", 1, NULL, 'l'}, {"tlatency", 1, NULL, 't'}, {"format", 1, NULL, 'f'}, {"channels", 1, NULL, 'c'}, {"rate", 1, NULL, 'r'}, {"buffer", 1, NULL, 'B'}, {"period", 1, NULL, 'E'}, {"seconds", 1, NULL, 's'}, {"nblock", 0, NULL, 'b'}, {"effect", 0, NULL, 'e'}, {"verbose", 0, NULL, 'v'}, {"resample", 0, NULL, 'n'}, {"samplerate", 1, NULL, 'A'}, {"sync", 1, NULL, 'S'}, {"slave", 1, NULL, 'a'}, {"thread", 1, NULL, 'T'}, {"mixer", 1, NULL, 'm'}, {"ossmixer", 1, NULL, 'O'}, {"workaround", 1, NULL, 'w'}, {"xrun", 0, NULL, 'U'}, {NULL, 0, NULL, 0}, }; int err, morehelp; char *arg_config = NULL; char *arg_pdevice = NULL; char *arg_cdevice = NULL; char *arg_pctl = NULL; char *arg_cctl = NULL; unsigned int arg_latency_req = 0; unsigned int arg_latency_reqtime = 10000; snd_pcm_format_t arg_format = SND_PCM_FORMAT_S16_LE; unsigned int arg_channels = 2; unsigned int arg_rate = 48000; snd_pcm_uframes_t arg_buffer_size = 0; snd_pcm_uframes_t arg_period_size = 0; unsigned long arg_loop_time = ~0UL; int arg_nblock = 0; int arg_effect = 0; int arg_resample = 0; int arg_samplerate = SRC_SINC_FASTEST + 1; int arg_sync = SYNC_TYPE_AUTO; int arg_slave = SLAVE_TYPE_AUTO; int arg_thread = 0; struct loopback *loop = NULL; char *arg_mixers[MAX_MIXERS]; int arg_mixers_count = 0; char *arg_ossmixers[MAX_MIXERS]; int arg_ossmixers_count = 0; int arg_xrun = arg_default_xrun; int arg_wake = arg_default_wake; morehelp = 0; while (1) { int c; if ((c = getopt_long(argc, argv, "hdg:P:C:X:Y:l:t:F:f:c:r:s:benvA:S:a:m:T:O:w:UW:", long_option, NULL)) < 0) break; switch (c) { case 'h': morehelp++; break; case 'g': arg_config = strdup(optarg); break; case 'd': daemonize = 1; use_syslog = 1; openlog("alsaloop", LOG_NDELAY|LOG_PID, LOG_DAEMON); break; case 'P': arg_pdevice = strdup(optarg); break; case 'C': arg_cdevice = strdup(optarg); break; case 'X': arg_pctl = strdup(optarg); break; case 'Y': arg_cctl = strdup(optarg); break; case 'l': err = atoi(optarg); arg_latency_req = err >= 4 ? err : 4; break; case 't': err = atoi(optarg); arg_latency_reqtime = err >= 500 ? err : 500; break; case 'f': arg_format = snd_pcm_format_value(optarg); if (arg_format == SND_PCM_FORMAT_UNKNOWN) { logit(LOG_WARNING, "Unknown format, setting to default S16_LE\n"); arg_format = SND_PCM_FORMAT_S16_LE; } break; case 'c': err = atoi(optarg); arg_channels = err >= 1 && err < 1024 ? err : 1; break; case 'r': err = atoi(optarg); arg_rate = err >= 4000 && err < 200000 ? err : 44100; break; case 'B': err = atoi(optarg); arg_buffer_size = err >= 32 && err < 200000 ? err : 0; break; case 'E': err = atoi(optarg); arg_period_size = err >= 32 && err < 200000 ? err : 0; break; case 's': err = atoi(optarg); arg_loop_time = err >= 1 && err <= 100000 ? err : 30; break; case 'b': arg_nblock = 1; break; case 'e': arg_effect = 1; break; case 'n': arg_resample = 1; break; case 'A': if (strcasecmp(optarg, "sincbest") == 0) arg_samplerate = SRC_SINC_BEST_QUALITY; else if (strcasecmp(optarg, "sincmedium") == 0) arg_samplerate = SRC_SINC_MEDIUM_QUALITY; else if (strcasecmp(optarg, "sincfastest") == 0) arg_samplerate = SRC_SINC_FASTEST; else if (strcasecmp(optarg, "zerohold") == 0) arg_samplerate = SRC_ZERO_ORDER_HOLD; else if (strcasecmp(optarg, "linear") == 0) arg_samplerate = SRC_LINEAR; else arg_samplerate = atoi(optarg); if (arg_samplerate < 0 || arg_samplerate > SRC_LINEAR) arg_sync = SRC_SINC_FASTEST; arg_samplerate += 1; break; case 'S': if (strcasecmp(optarg, "samplerate") == 0) arg_sync = SYNC_TYPE_SAMPLERATE; else if (optarg[0] == 'n') arg_sync = SYNC_TYPE_NONE; else if (optarg[0] == 's') arg_sync = SYNC_TYPE_SIMPLE; else if (optarg[0] == 'c') arg_sync = SYNC_TYPE_CAPTRATESHIFT; else if (optarg[0] == 'p') arg_sync = SYNC_TYPE_PLAYRATESHIFT; else if (optarg[0] == 'r') arg_sync = SYNC_TYPE_SAMPLERATE; else arg_sync = atoi(optarg); if (arg_sync < 0 || arg_sync > SYNC_TYPE_LAST) arg_sync = SYNC_TYPE_AUTO; break; case 'a': if (optarg[0] == 'a') arg_slave = SLAVE_TYPE_AUTO; else if (strcasecmp(optarg, "on") == 0) arg_slave = SLAVE_TYPE_ON; else if (strcasecmp(optarg, "off") == 0) arg_slave = SLAVE_TYPE_OFF; else arg_slave = atoi(optarg); if (arg_slave < 0 || arg_slave > SLAVE_TYPE_LAST) arg_slave = SLAVE_TYPE_AUTO; break; case 'T': arg_thread = atoi(optarg); if (arg_thread < 0) arg_thread = 10000000 + loopbacks_count; break; case 'm': if (arg_mixers_count >= MAX_MIXERS) { logit(LOG_CRIT, "Maximum redirected mixer controls reached (max %i)\n", (int)MAX_MIXERS); return EXIT_FAILURE; } arg_mixers[arg_mixers_count++] = optarg; break; case 'O': if (arg_ossmixers_count >= MAX_MIXERS) { logit(LOG_CRIT, "Maximum redirected mixer controls reached (max %i)\n", (int)MAX_MIXERS); return EXIT_FAILURE; } arg_ossmixers[arg_ossmixers_count++] = optarg; break; case 'v': verbose++; break; case 'w': if (strcasecmp(optarg, "serialopen") == 0) workarounds |= WORKAROUND_SERIALOPEN; break; case 'U': arg_xrun = 1; if (cmdline) arg_default_xrun = 1; break; case 'W': arg_wake = atoi(optarg); if (cmdline) arg_default_wake = arg_wake; break; } } if (morehelp) { help(); return EXIT_SUCCESS; } if (arg_config == NULL) { struct loopback_handle *play; struct loopback_handle *capt; err = create_loopback_handle(&play, arg_pdevice, arg_pctl, "playback"); if (err < 0) { logit(LOG_CRIT, "Unable to create playback handle.\n"); return EXIT_FAILURE; } err = create_loopback_handle(&capt, arg_cdevice, arg_cctl, "capture"); if (err < 0) { logit(LOG_CRIT, "Unable to create capture handle.\n"); return EXIT_FAILURE; } err = create_loopback(&loop, play, capt, output); if (err < 0) { logit(LOG_CRIT, "Unable to create loopback handle.\n"); return EXIT_FAILURE; } play->format = capt->format = arg_format; play->rate = play->rate_req = capt->rate = capt->rate_req = arg_rate; play->channels = capt->channels = arg_channels; play->buffer_size_req = capt->buffer_size_req = arg_buffer_size; play->period_size_req = capt->period_size_req = arg_period_size; play->resample = capt->resample = arg_resample; play->nblock = capt->nblock = arg_nblock ? 1 : 0; loop->latency_req = arg_latency_req; loop->latency_reqtime = arg_latency_reqtime; loop->sync = arg_sync; loop->slave = arg_slave; loop->thread = arg_thread; loop->xrun = arg_xrun; loop->wake = arg_wake; err = add_mixers(loop, arg_mixers, arg_mixers_count); if (err < 0) { logit(LOG_CRIT, "Unable to add mixer controls.\n"); return EXIT_FAILURE; } err = add_oss_mixers(loop, arg_ossmixers, arg_ossmixers_count); if (err < 0) { logit(LOG_CRIT, "Unable to add ossmixer controls.\n"); return EXIT_FAILURE; } #ifdef USE_SAMPLERATE loop->src_enable = arg_samplerate > 0; if (loop->src_enable) loop->src_converter_type = arg_samplerate - 1; #else if (arg_samplerate > 0) { logit(LOG_CRIT, "No libsamplerate support.\n"); return EXIT_FAILURE; } #endif set_loop_time(loop, arg_loop_time); add_loop(loop); return 0; } return parse_config_file(arg_config, output); }