コード例 #1
0
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;
  }
}
コード例 #2
0
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));
    }
  }
}
コード例 #3
0
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);
}
コード例 #4
0
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);
  }
}
コード例 #5
0
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);
  }
}
コード例 #6
0
      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;
コード例 #7
0
void
ags_apply_tact_soundcard(AgsApplyTact *apply_tact, GObject *soundcard)
{
  ags_soundcard_set_delay_factor(AGS_SOUNDCARD(soundcard), apply_tact->tact);
}
コード例 #8
0
				   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);
コード例 #9
0
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);
}
コード例 #10
0
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, &param) == -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
  }
}
コード例 #11
0
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;
  }
}
コード例 #12
0
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{
    }
  }
}