krad_mixer_portgroup_t *krad_mixer_portgroup_create (krad_mixer_t *krad_mixer, char *sysname, int direction, krad_mixer_output_t output_type, int channels, float volume, krad_mixer_mixbus_t *mixbus, krad_mixer_portgroup_io_t io_type, void *io_ptr, krad_audio_api_t api) { int p; int c; krad_mixer_portgroup_t *portgroup; portgroup = NULL; /* prevent dupe names */ for (p = 0; p < KRAD_MIXER_MAX_PORTGROUPS; p++) { if (krad_mixer->portgroup[p]->active != 0) { if (strncmp(sysname, krad_mixer->portgroup[p]->sysname, strlen(sysname)) == 0) { return NULL; } } } //FIXME race here if portgroup being created via ipc and transponder at same moment for (p = 0; p < KRAD_MIXER_MAX_PORTGROUPS; p++) { if (krad_mixer->portgroup[p]->active == 0) { portgroup = krad_mixer->portgroup[p]; break; } } if (portgroup == NULL) { return NULL; } /* Prevent multiple JACK direct outputs as this is redundant */ if ((api == JACK) && (direction == OUTPUT) && (output_type == DIRECT)) { for (p = 0; p < KRAD_MIXER_MAX_PORTGROUPS; p++) { if ((krad_mixer->portgroup[p]->active == 1) || (krad_mixer->portgroup[p]->active == 2)) { if ((krad_mixer_portgroup_is_jack(krad_mixer->portgroup[p])) && (krad_mixer->portgroup[p]->direction == OUTPUT) && (krad_mixer->portgroup[p]->output_type == DIRECT)) { return NULL; } } } } portgroup->krad_mixer = krad_mixer; strcpy (portgroup->sysname, sysname); portgroup->channels = channels; portgroup->io_type = io_type; portgroup->output_type = output_type; portgroup->mixbus = mixbus; portgroup->direction = direction; portgroup->address.path.unit = KR_MIXER; portgroup->address.path.subunit.mixer_subunit = KR_PORTGROUP; strcpy (portgroup->address.id.name, portgroup->sysname); for (c = 0; c < KRAD_MIXER_MAX_CHANNELS; c++) { if (c < portgroup->channels) { portgroup->mixmap[c] = c; } else { portgroup->mixmap[c] = -1; } portgroup->map[c] = c; portgroup->mapped_samples[c] = &portgroup->samples[c]; if ((portgroup->direction != OUTPUT) || (portgroup->output_type == AUX)) { portgroup->volume[c] = volume; } else { portgroup->volume[c] = 100.0f; } portgroup->volume_actual[c] = (float)(portgroup->volume[c]/100.0f); portgroup->volume_actual[c] *= portgroup->volume_actual[c]; portgroup->new_volume_actual[c] = portgroup->volume_actual[c]; switch ( portgroup->io_type ) { case KRAD_TONE: portgroup->samples[c] = calloc (1, 16384); break; case MIXBUS: portgroup->samples[c] = calloc (1, 16384); break; case KRAD_AUDIO: break; case KRAD_LINK: portgroup->samples[c] = calloc (1, 16384); break; case KLOCALSHM: break; } } switch ( portgroup->io_type ) { case KRAD_TONE: portgroup->io_ptr = krad_tone_create (krad_mixer->sample_rate); case MIXBUS: break; case KRAD_AUDIO: portgroup->io_ptr = krad_audio_portgroup_create (krad_mixer->krad_audio, portgroup->sysname, portgroup->direction, portgroup->channels, api); break; case KRAD_LINK: portgroup->io_ptr = io_ptr; break; case KLOCALSHM: portgroup->io_ptr = io_ptr; break; } if (portgroup->io_type != KRAD_LINK) { portgroup->krad_tags = krad_tags_create (portgroup->sysname); //if ((portgroup->krad_tags != NULL) && (krad_mixer->krad_ipc != NULL)) { // krad_tags_set_set_tag_callback (portgroup->krad_tags, krad_mixer->krad_ipc, // (void (*)(void *, char *, char *, char *, int))krad_ipc_server_broadcast_tag); //} } else { portgroup->krad_tags = krad_link_get_tags (portgroup->io_ptr); } if (portgroup->krad_tags == NULL) { failfast ("Oh I couldn't find me tags"); } portgroup->effects = kr_effects_create (portgroup->channels, portgroup->krad_mixer->sample_rate); if (portgroup->effects == NULL) { failfast ("Oh I couldn't make effects"); } if (portgroup->direction == INPUT) { kr_effects_effect_add2 (portgroup->effects, kr_effects_string_to_effect ("eq"), portgroup->krad_mixer, portgroup->sysname); kr_effects_effect_add2 (portgroup->effects, kr_effects_string_to_effect ("lowpass"), portgroup->krad_mixer, portgroup->sysname); kr_effects_effect_add2 (portgroup->effects, kr_effects_string_to_effect ("highpass"), portgroup->krad_mixer, portgroup->sysname); kr_effects_effect_add2 (portgroup->effects, kr_effects_string_to_effect ("analog"), portgroup->krad_mixer, portgroup->sysname); } if (portgroup->io_type != KLOCALSHM) { portgroup->active = 1; } return portgroup; }
int main (int argc, char *argv[]) { int i; int ret; kr_client_t *client; kr_audioport_t *audioport; krad_mixer_portgroup_direction_t direction; uint32_t sample_rate; ret = 0; direction = INPUT; if (argc != 2) { if (argc > 2) { fprintf (stderr, "Only takes station argument.\n"); } else { fprintf (stderr, "No station specified.\n"); } return 1; } client = kr_client_create ("krad audioport client"); if (client == NULL) { fprintf (stderr, "Could not create KR client.\n"); return 1; } kr_connect (client, argv[1]); if (!kr_connected (client)) { fprintf (stderr, "Could not connect to %s krad radio daemon.\n", argv[1]); kr_client_destroy (&client); return 1; } if (kr_mixer_get_info_wait (client, &sample_rate, NULL) != 1) { fprintf (stderr, "Could not get mixer info!\n"); kr_client_destroy (&client); return 1; } if (direction == INPUT) { krad_tone = krad_tone_create (sample_rate); krad_tone_add_preset (krad_tone, "3"); krad_tone2 = krad_tone_create (sample_rate); krad_tone_add_preset (krad_tone2, "3"); } audioport = kr_audioport_create (client, direction); if (audioport == NULL) { fprintf (stderr, "Could not make audioport.\n"); kr_client_destroy (&client); return 1; } else { printf ("Working!\n"); } kr_audioport_set_callback (audioport, audioport_process, audioport); signal (SIGINT, signal_recv); signal (SIGTERM, signal_recv); kr_audioport_activate (audioport); for (i = 0; i < 40; i++) { usleep (30000); if (destroy == 1) { printf ("Got signal!\n"); break; } if (kr_audioport_error (audioport)) { printf ("Error: %s\n", "Audioport Error"); ret = 1; break; } } kr_audioport_deactivate (audioport); kr_audioport_destroy (audioport); if (direction == INPUT) { krad_tone_destroy (krad_tone); krad_tone_destroy (krad_tone2); } kr_client_destroy (&client); if (ret == 0) { printf ("Worked!\n"); } return ret; }