void ags_soundcard_thread_stop(AgsThread *thread) { AgsSoundcardThread *soundcard_thread; AgsThread *main_loop; AgsPollingThread *polling_thread; GObject *soundcard; GList *poll_fd; soundcard_thread = AGS_SOUNDCARD_THREAD(thread); main_loop = ags_thread_get_toplevel(thread); soundcard = soundcard_thread->soundcard; /* stop thread and soundcard */ AGS_THREAD_CLASS(ags_soundcard_thread_parent_class)->stop(thread); //FIXME:JK: is this safe? ags_soundcard_stop(AGS_SOUNDCARD(soundcard)); g_atomic_int_or(&(thread->flags), AGS_THREAD_TIMING); /* find polling thread */ polling_thread = (AgsPollingThread *) ags_thread_find_type(main_loop, AGS_TYPE_POLLING_THREAD); /* remove poll fd */ poll_fd = ags_soundcard_get_poll_fd(AGS_SOUNDCARD(soundcard)); while(poll_fd != NULL){ if(polling_thread != NULL){ gint position; g_object_disconnect(G_OBJECT(poll_fd->data), "any_signal::dispatch", G_CALLBACK(ags_soundcard_thread_dispatch_callback), soundcard_thread, NULL); ags_polling_thread_remove_poll_fd(polling_thread, poll_fd->data); } poll_fd = poll_fd->next; } }
void ags_soundcard_thread_dispatch_callback(AgsPollFd *poll_fd, AgsSoundcardThread *soundcard_thread) { AgsAudioLoop *audio_loop; AgsPollingThread *polling_thread; guint time_spent; audio_loop = (AgsAudioLoop *) ags_thread_get_toplevel((AgsThread *) soundcard_thread); if(ags_soundcard_is_available(AGS_SOUNDCARD(soundcard_thread->soundcard))){ pthread_mutex_lock(audio_loop->timing_mutex); g_atomic_int_set(&(audio_loop->time_spent), audio_loop->time_cycle); pthread_mutex_unlock(audio_loop->timing_mutex); // ags_main_loop_interrupt(AGS_MAIN_LOOP(audio_loop), // AGS_THREAD_SUSPEND_SIG, // 0, &time_spent); polling_thread = (AgsPollingThread *) ags_thread_find_type((AgsThread *) audio_loop, AGS_TYPE_POLLING_THREAD); if(polling_thread != NULL){ g_atomic_int_or(&(polling_thread->flags), AGS_POLLING_THREAD_OMIT); g_atomic_int_inc(&(polling_thread->omit_count)); } } }
void ags_play_wave_channel_run_seek(AgsSeekable *seekable, gint64 offset, guint whence) { AgsPlayWaveChannelRun *play_wave_channel_run; GObject *soundcard; gdouble absolute_delay; guint buffer_size; guint64 x_offset; play_wave_channel_run = AGS_PLAY_WAVE_CHANNEL_RUN(seekable); g_object_get(play_wave_channel_run, "output-soundcard", &soundcard, "buffer-size", &buffer_size, NULL); absolute_delay = ags_soundcard_get_absolute_delay(AGS_SOUNDCARD(soundcard)); switch(whence){ case AGS_SEEK_CUR: { g_object_get(play_wave_channel_run, "x-offset", &x_offset, NULL); if(x_offset + (offset * absolute_delay * buffer_size) < 0){ x_offset = 0; }else{ x_offset = x_offset + (offset * absolute_delay * buffer_size); } g_object_set(play_wave_channel_run, "x-offset", x_offset, NULL); } break; case AGS_SEEK_END: { g_warning("seek from end not implemented"); } break; case AGS_SEEK_SET: { x_offset = offset * absolute_delay * buffer_size; g_object_set(play_wave_channel_run, "x-offset", x_offset, NULL); } break; } g_object_unref(soundcard); }
void ags_soundcard_thread_start(AgsThread *thread) { AgsSoundcardThread *soundcard_thread; AgsThread *main_loop; AgsPollingThread *polling_thread; GObject *soundcard; GList *poll_fd; GError *error; soundcard_thread = AGS_SOUNDCARD_THREAD(thread); main_loop = ags_thread_get_toplevel(thread); soundcard = soundcard_thread->soundcard; /* disable timing */ g_atomic_int_and(&(thread->flags), (~AGS_THREAD_TIMING)); /* find polling thread */ polling_thread = (AgsPollingThread *) ags_thread_find_type(main_loop, AGS_TYPE_POLLING_THREAD); /* add poll fd and connect dispatch */ poll_fd = ags_soundcard_get_poll_fd(AGS_SOUNDCARD(soundcard)); while(poll_fd != NULL){ if(polling_thread != NULL){ gint position; ags_polling_thread_add_poll_fd(polling_thread, poll_fd->data); g_signal_connect(G_OBJECT(poll_fd->data), "dispatch", G_CALLBACK(ags_soundcard_thread_dispatch_callback), soundcard_thread); position = ags_polling_thread_fd_position(polling_thread, AGS_POLL_FD(poll_fd->data)->fd); if(position != -1){ polling_thread->fds[position].events = POLLOUT; } } poll_fd = poll_fd->next; } if((AGS_THREAD_SINGLE_LOOP & (g_atomic_int_get(&(thread->flags)))) == 0){ AGS_THREAD_CLASS(ags_soundcard_thread_parent_class)->start(thread); } }
void ags_soundcard_thread_stopped_all_callback(AgsAudioLoop *audio_loop, AgsSoundcardThread *soundcard_thread) { AgsSoundcard *soundcard; soundcard = AGS_SOUNDCARD(soundcard_thread->soundcard); if(ags_soundcard_is_playing(soundcard)){ ags_thread_stop((AgsThread *) soundcard_thread); } }
break; case AGS_APPLY_SYNTH_SQUARE: ags_synth_square(soundcard, (signed short *) stream->data, offset, frequency, phase, frame_count, volume); break; case AGS_APPLY_SYNTH_TRIANGLE: ags_synth_triangle(soundcard, (signed short *) stream->data, offset, frequency, phase, frame_count, volume); break; default: g_warning("ags_apply_synth_launch_write: warning no wave selected\n\0"); } } apply_synth = AGS_APPLY_SYNTH(task); channel = apply_synth->start_channel; soundcard = AGS_AUDIO(channel->audio)->soundcard; ags_soundcard_get_presets(AGS_SOUNDCARD(soundcard), NULL, &samplerate, &buffer_size, NULL); wave = (gint) apply_synth->wave; g_message("wave = %d\n\0", wave); /* some settings */ frequency = apply_synth->frequency; volume = (double) apply_synth->volume; /* settings which needs to be initialized for factorizing */ attack = apply_synth->attack;
void ags_apply_tact_soundcard(AgsApplyTact *apply_tact, GObject *soundcard) { ags_soundcard_set_delay_factor(AGS_SOUNDCARD(soundcard), apply_tact->tact); }
play_wave_channel_run->audio_signal); ags_connectable_connect(AGS_CONNECTABLE(play_wave_channel_run->audio_signal)); } play_wave_channel_run = (AgsPlayWaveChannelRun *) recall; g_object_get(play_wave_channel_run, "output-soundcard", &output_soundcard, "recall-id", &recall_id, "recall-audio", &play_wave_audio, "recall-channel", &play_wave_channel, "recall-audio-run", &play_wave_audio_run, NULL); delay = ags_soundcard_get_delay(AGS_SOUNDCARD(output_soundcard)); /* get do playback */ g_object_get(play_wave_channel, "do-playback", &port, NULL); g_value_init(&do_playback_value, G_TYPE_BOOLEAN); ags_port_safe_read(port, &do_playback_value); do_playback = g_value_get_boolean(&do_playback_value); g_value_unset(&do_playback_value);
void ags_audio_preferences_reset(AgsApplicable *applicable) { AgsWindow *window; AgsPreferences *preferences; AgsAudioPreferences *audio_preferences; AgsSoundcard *soundcard; GtkListStore *model; GtkTreeIter iter; GList *card_id, *card_name; char *device; int card_num; guint channels, channels_min, channels_max; guint rate, rate_min, rate_max; guint buffer_size, buffer_size_min, buffer_size_max; GError *error; audio_preferences = AGS_AUDIO_PREFERENCES(applicable); /* */ preferences = (AgsPreferences *) gtk_widget_get_ancestor(GTK_WIDGET(audio_preferences), AGS_TYPE_PREFERENCES); window = AGS_WINDOW(preferences->parent); soundcard = AGS_SOUNDCARD(window->soundcard); /* refresh */ ags_soundcard_list_cards(AGS_SOUNDCARD(soundcard), &card_id, &card_name); model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); while(card_id != NULL){ gtk_list_store_append(model, &iter); gtk_list_store_set(model, &iter, 0, card_id->data, 1, card_name->data, -1); card_id = card_id->next; card_name = card_name->next; } g_list_free(card_id); g_list_free(card_name); gtk_combo_box_set_model(audio_preferences->card, GTK_TREE_MODEL(model)); /* */ g_object_get(G_OBJECT(soundcard), "device\0", &device, "pcm-channels\0", &channels, "frequency\0", &rate, "buffer-size\0", &buffer_size, NULL); error = NULL; /* */ sscanf(device, "hw:%i\0", &card_num); // gtk_combo_box_set_active(audio_preferences->card, // card_num); gtk_spin_button_set_value(audio_preferences->audio_channels, (gdouble) channels); gtk_spin_button_set_value(audio_preferences->samplerate, (gdouble) rate); gtk_spin_button_set_value(audio_preferences->buffer_size, (gdouble) buffer_size); /* */ ags_soundcard_pcm_info(soundcard, gtk_combo_box_get_active_text(audio_preferences->card), &channels_min, &channels_max, &rate_min, &rate_max, &buffer_size_min, &buffer_size_max, &error); if(error != NULL){ GtkMessageDialog *dialog; dialog = (GtkMessageDialog *) gtk_message_dialog_new((GtkWindow *) gtk_widget_get_ancestor(GTK_WIDGET(audio_preferences), AGS_TYPE_PREFERENCES), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, error->message); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(GTK_WIDGET(dialog)); gtk_spin_button_set_range(audio_preferences->audio_channels, 0.0, 24.0); gtk_spin_button_set_range(audio_preferences->samplerate, 1.0, 192000.0); gtk_spin_button_set_range(audio_preferences->buffer_size, 1.0, 65535.0); return; } gtk_spin_button_set_range(audio_preferences->audio_channels, channels_min, channels_max); gtk_spin_button_set_range(audio_preferences->samplerate, rate_min, rate_max); gtk_spin_button_set_range(audio_preferences->buffer_size, buffer_size_min, buffer_size_max); }
void ags_soundcard_thread_run(AgsThread *thread) { AgsSoundcardThread *soundcard_thread; GObject *soundcard; GList *poll_fd; gboolean is_playing, is_recording; GError *error; soundcard_thread = AGS_SOUNDCARD_THREAD(thread); soundcard = soundcard_thread->soundcard; /* real-time setup */ #ifdef AGS_WITH_RT if((AGS_THREAD_RT_SETUP & (g_atomic_int_get(&(thread->flags)))) == 0){ struct sched_param param; /* Declare ourself as a real time task */ param.sched_priority = AGS_RT_PRIORITY; if(sched_setscheduler(0, SCHED_FIFO, ¶m) == -1) { perror("sched_setscheduler failed"); } g_atomic_int_or(&(thread->flags), AGS_THREAD_RT_SETUP); } #endif /* playback */ if((AGS_SOUNDCARD_CAPABILITY_PLAYBACK & (soundcard_thread->soundcard_capability)) != 0){ is_playing = ags_soundcard_is_playing(AGS_SOUNDCARD(soundcard)); if(is_playing){ error = NULL; ags_soundcard_play(AGS_SOUNDCARD(soundcard), &error); if(error != NULL){ //TODO:JK: implement me g_warning("%s", error->message); } } } /* capture */ if((AGS_SOUNDCARD_CAPABILITY_CAPTURE & (soundcard_thread->soundcard_capability)) != 0){ is_recording = ags_soundcard_is_recording(AGS_SOUNDCARD(soundcard)); if(is_recording){ error = NULL; ags_soundcard_record(AGS_SOUNDCARD(soundcard), &error); if(error != NULL){ //TODO:JK: implement me g_warning("%s", error->message); } } } /* duplex */ if((AGS_SOUNDCARD_CAPABILITY_DUPLEX & (soundcard_thread->soundcard_capability)) != 0){ //TODO:JK: implement me } }
void ags_soundcard_thread_set_property(GObject *gobject, guint prop_id, const GValue *value, GParamSpec *param_spec) { AgsSoundcardThread *soundcard_thread; soundcard_thread = AGS_SOUNDCARD_THREAD(gobject); switch(prop_id){ case PROP_SOUNDCARD: { GObject *soundcard; guint samplerate; guint buffer_size; soundcard = (GObject *) g_value_get_object(value); if(soundcard_thread->soundcard != NULL){ g_object_unref(G_OBJECT(soundcard_thread->soundcard)); } if(soundcard != NULL){ g_object_ref(G_OBJECT(soundcard)); ags_soundcard_get_presets(AGS_SOUNDCARD(soundcard), NULL, &samplerate, &buffer_size, NULL); g_object_set(soundcard_thread, "frequency", ceil((gdouble) samplerate / (gdouble) buffer_size) + AGS_SOUNDCARD_DEFAULT_OVERCLOCK, NULL); /* playback */ if(AGS_IS_DEVOUT(soundcard)){ g_atomic_int_or(&(AGS_THREAD(soundcard_thread)->flags), (AGS_THREAD_INTERMEDIATE_POST_SYNC)); }else if(AGS_IS_JACK_DEVOUT(soundcard) || AGS_IS_PULSE_DEVOUT(soundcard)){ g_atomic_int_or(&(AGS_THREAD(soundcard_thread)->flags), (AGS_THREAD_INTERMEDIATE_POST_SYNC)); }else if(AGS_IS_CORE_AUDIO_DEVOUT(soundcard)){ g_atomic_int_or(&(AGS_THREAD(soundcard_thread)->flags), (AGS_THREAD_INTERMEDIATE_POST_SYNC)); } /* capture */ if(AGS_IS_DEVIN(soundcard)){ g_atomic_int_or(&(AGS_THREAD(soundcard_thread)->flags), (AGS_THREAD_INTERMEDIATE_PRE_SYNC)); }else if(AGS_IS_JACK_DEVIN(soundcard) || AGS_IS_PULSE_DEVIN(soundcard)){ g_atomic_int_or(&(AGS_THREAD(soundcard_thread)->flags), (AGS_THREAD_INTERMEDIATE_PRE_SYNC)); }else if(AGS_IS_CORE_AUDIO_DEVIN(soundcard)){ g_atomic_int_or(&(AGS_THREAD(soundcard_thread)->flags), (AGS_THREAD_INTERMEDIATE_PRE_SYNC)); } /* duplex */ //TODO:JK: implement me } soundcard_thread->soundcard = G_OBJECT(soundcard); } break; case PROP_SOUNDCARD_CAPABILITY: { soundcard_thread->soundcard_capability = g_value_get_uint(value); } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec); break; } }
void ags_matrix_set_pads(AgsAudio *audio, GType type, guint pads, guint pads_old, gpointer data) { AgsMachine *machine; AgsMatrix *matrix; AgsChannel *channel, *source; AgsAudioSignal *audio_signal; guint i, j; gboolean grow; GValue value = {0,}; if(pads == pads_old){ return; } matrix = (AgsMatrix *) audio->machine_widget; machine = AGS_MACHINE(matrix); if(type == AGS_TYPE_INPUT){ if(pads < AGS_MATRIX_OCTAVE){ gtk_widget_set_size_request((GtkWidget *) matrix->drawing_area, 32 * AGS_MATRIX_CELL_WIDTH +1, pads * AGS_MATRIX_CELL_HEIGHT +1); }else if(pads_old < AGS_MATRIX_OCTAVE){ gtk_widget_set_size_request((GtkWidget *) matrix->drawing_area, 32 * AGS_MATRIX_CELL_WIDTH +1, AGS_MATRIX_OCTAVE * AGS_MATRIX_CELL_HEIGHT +1); } } if(pads_old == pads) return; if(pads_old < pads) grow = TRUE; else grow = FALSE; if(type == AGS_TYPE_INPUT){ AgsPattern *pattern; GList *list, *notation; if(grow){ /* create pattern */ source = ags_channel_nth(audio->input, pads_old); while(source != NULL){ if(source->pattern == NULL){ source->pattern = g_list_alloc(); source->pattern->data = (gpointer) ags_pattern_new(); ags_pattern_set_dim((AgsPattern *) source->pattern->data, 1, 9, 32); } source = source->next; } if((AGS_MACHINE_MAPPED_RECALL & (machine->flags)) != 0){ ags_matrix_input_map_recall(matrix, pads_old); } }else{ } }else{ if(grow){ AgsChannel *current, *output; GList *recall; GList *list; guint stop; source = ags_channel_nth(audio->output, pads_old); if(source != NULL){ AgsAudioSignal *audio_signal; AgsSoundcard *soundcard; gdouble delay; guint stop; soundcard = AGS_SOUNDCARD(AGS_AUDIO(source->audio)->soundcard); delay = ags_soundcard_get_delay(soundcard); stop = (guint) ceil(16.0 * delay * exp2(8.0 - 4.0) + 1.0); audio_signal = ags_audio_signal_new(soundcard, source->first_recycling, NULL); audio_signal->flags |= AGS_AUDIO_SIGNAL_TEMPLATE; // ags_audio_signal_stream_resize(audio_signal, // stop); ags_recycling_add_audio_signal(source->first_recycling, audio_signal); if((AGS_MACHINE_MAPPED_RECALL & (machine->flags)) != 0){ ags_matrix_output_map_recall(matrix, pads_old); } } }else{ } } }