Пример #1
0
void
swfdec_playback_close (SwfdecPlayback *sound)
{
  pa_operation *op;

#define REMOVE_HANDLER_FULL(obj,func,data,count) G_STMT_START {\
  if (g_signal_handlers_disconnect_by_func ((obj), \
	G_CALLBACK (func), (data)) != (count)) { \
    g_assert_not_reached (); \
  } \
} G_STMT_END
#define REMOVE_HANDLER(obj,func,data) REMOVE_HANDLER_FULL (obj, func, data, 1)

  while (sound->streams)
    swfdec_playback_stream_close (sound->streams->data);
  REMOVE_HANDLER (sound->player, advance_before, sound);
  REMOVE_HANDLER (sound->player, audio_added, sound);
  REMOVE_HANDLER (sound->player, audio_removed, sound);

  if (sound->pa != NULL) {
    op = pa_context_drain (sound->pa, context_drain_complete, NULL);
    if (op == NULL) {
      pa_context_disconnect (sound->pa);
      pa_context_unref (sound->pa);
    } else {
      pa_operation_unref (op);
    }
    pa_glib_mainloop_free (sound->pa_mainloop);
  }

  g_main_context_unref (sound->context);
  g_free (sound);
}
Пример #2
0
static void
audio_removed (SwfdecPlayer *player, SwfdecAudio *audio, SwfdecPlayback *sound)
{
  GList *walk;

  for (walk = sound->streams; walk; walk = walk->next) {
    Stream *stream = walk->data;
    if (stream->audio == audio) {
      swfdec_playback_stream_close (stream);
      return;
    }
  }
}
Пример #3
0
void
swfdec_playback_close (SwfdecPlayback *sound)
{
#define REMOVE_HANDLER_FULL(obj,func,data,count) G_STMT_START {\
  if (g_signal_handlers_disconnect_by_func ((obj), \
	G_CALLBACK (func), (data)) != (count)) { \
    g_assert_not_reached (); \
  } \
} G_STMT_END
#define REMOVE_HANDLER(obj,func,data) REMOVE_HANDLER_FULL (obj, func, data, 1)

  while (sound->streams)
    swfdec_playback_stream_close (sound->streams->data);
  REMOVE_HANDLER (sound->player, advance_before, sound);
  REMOVE_HANDLER (sound->player, audio_added, sound);
  REMOVE_HANDLER (sound->player, audio_removed, sound);
  g_main_context_unref (sound->context);
  g_free (sound);
}
Пример #4
0
static void
swfdec_playback_stream_open (SwfdecPlayback *sound, SwfdecAudio *audio)
{
  Stream *stream;
  pa_sample_spec spec = {
    .format = PA_SAMPLE_S16LE,
    .rate = 44100,
    .channels = CHANNELS,
  };
  int err;

  stream = g_new0 (Stream, 1);
  stream->sound = sound;
  stream->audio = g_object_ref (audio);
  sound->streams = g_list_prepend (sound->streams, stream);

  /* If we failed to initialize the context, don't try to create the stream.
   * We still have to get put in the list, because swfdec_playback.c expects
   * to find it in the list for removal later.
   */
  if (sound->pa == NULL)
    return;

  /* Create our stream */
  stream->pa = pa_stream_new(sound->pa,
			     "swfdec stream",
			     &spec,
			     NULL /* Default channel map */
			     );
  if (stream->pa == NULL) {
    g_printerr("Failed to create PA stream\n");
    swfdec_playback_stream_close(stream);
    return;
  }

  /* Start at default volume */
  pa_cvolume_set(&stream->volume, CHANNELS, PA_VOLUME_NORM);

  /* Hook up our stream write callback for when new data is needed */
  pa_stream_set_state_callback(stream->pa, stream_state_callback, stream);
  pa_stream_set_write_callback(stream->pa, stream_write_callback, stream);

  /* Connect it up as a playback stream. */
  err = pa_stream_connect_playback(stream->pa,
				   NULL, /* Default device */
				   NULL /* Default buffering */,
				   0, /* No flags */
				   &stream->volume,
				   NULL /* Don't sync to any stream */
				   );
  if (err != 0) {
    g_printerr ("Failed to connect PA stream: %s\n",
		pa_strerror(pa_context_errno(sound->pa)));
    swfdec_playback_stream_close(stream);
    return;
  }
}

/*** SOUND ***/

static void
advance_before (SwfdecPlayer *player, guint msecs, guint audio_samples, gpointer data)
{
  SwfdecPlayback *sound = data;
  GList *walk;

  for (walk = sound->streams; walk; walk = walk->next) {
    Stream *stream = walk->data;
    if (audio_samples >= stream->offset) {
      stream->offset = 0;
    } else {
      stream->offset -= audio_samples;
    }
  }
}