static void spotify_cb_play_token_lost (sp_session *session) { GST_CAT_ERROR_OBJECT (gst_spot_src_debug_cb, ugly_spot, "Play_token_lost callback"); ugly_spot->play_token_lost = TRUE; g_signal_emit (ugly_spot, gst_spot_signals[SIGNAL_PLAY_TOKEN_LOST], 0); }
static gboolean gst_spot_src_get_size (GstBaseSrc * basesrc, guint64 * size) { GstSpotSrc *spot; guint64 duration = 0; spot = GST_SPOT_SRC (basesrc); /* duration in ms */ duration = run_spot_cmd (spot, SPOT_CMD_DURATION, 0); /* duration in ns */ duration = 1000000 * duration; if (!duration) { GST_CAT_ERROR_OBJECT (gst_spot_src_debug_audio, spot, "No duration error"); goto no_duration; } *size = (duration/1000000000) * 44100 * 4; GST_CAT_LOG_OBJECT (gst_spot_src_debug_audio, spot, "Duration=%" G_GUINT64_FORMAT " => size=%" G_GUINT64_FORMAT, duration, *size); return TRUE; no_duration: return FALSE; }
static void gst_spot_src_init (GstSpotSrc * spot, GstSpotSrcClass * g_class) { GError *err; spot->read_position = 0; /* its childish to use static global variables */ ugly_spot = GST_SPOT_SRC (spot); GST_SPOT_SRC_URI (spot) = g_strdup (DEFAULT_URI); GST_SPOT_SRC_BUFFER_TIME (spot) = BUFFER_TIME_DEFAULT; GST_SPOT_SRC_ADAPTER_MUTEX (spot) = g_mutex_new (); GST_SPOT_SRC_ADAPTER_COND (spot) = g_cond_new (); GST_SPOT_SRC_ADAPTER (spot) = gst_adapter_new (); /* initiate format to default format */ GST_SPOT_SRC_FORMAT (spot) = g_malloc0 (sizeof (sp_audioformat)); GST_SPOT_SRC_FORMAT (spot)->sample_rate = SPOTIFY_DEFAULT_SAMPLE_RATE; GST_SPOT_SRC_FORMAT (spot)->channels = SPOTIFY_DEFAULT_NUMBER_CHANNELS; GST_SPOT_SRC_FORMAT (spot)->sample_type = SP_SAMPLETYPE_INT16_NATIVE_ENDIAN; /* initiate state varables */ spot->spot_works = NULL; spot->play_token_lost = FALSE; spot->end_of_track = FALSE; spot->unlock_state = FALSE; /* initiate user settings */ spot->user = g_strdup (DEFAULT_USER); spot->pass = g_strdup (DEFAULT_PASS); spot->uri = g_strdup (DEFAULT_URI); spot->logged_in = FALSE; /* intiate worker thread and its state variables */ spot->keep_spotify_thread = TRUE; spot->spotify_thread_initiated = FALSE; spot->process_events_mutex = g_mutex_new (); spot->process_events_cond = g_cond_new (); spot->process_events_thread = g_thread_create ((GThreadFunc)spotify_thread_func, spot, TRUE, &err); if (spot->process_events_thread == NULL) { GST_CAT_ERROR_OBJECT (gst_spot_src_debug_threads, spot,"G_thread_create failed: %s!", err->message ); g_error_free (err) ; } /* make sure spotify thread is up and running, before continuing. */ GST_CAT_DEBUG_OBJECT (gst_spot_src_debug_threads, spot, "Broadcast process_events_cond"); g_cond_broadcast (spot->process_events_cond); while (!spot->spotify_thread_initiated) { /* ugly but hey it yields right. */ usleep (40); GST_CAT_DEBUG_OBJECT (gst_spot_src_debug_threads, spot, "Broadcast process_events_cond, in loop"); g_cond_broadcast (spot->process_events_cond); } }
static void spotify_cb_logged_in (sp_session *spotify_session, sp_error error) { if (SP_ERROR_OK != error) { GST_CAT_ERROR_OBJECT (gst_spot_src_debug_cb, ugly_spot, "Failed to log in to Spotify: %s", sp_error_message (error)); return; } sp_user *me = sp_session_user (spotify_session); const char *my_name = (sp_user_is_loaded (me) ? sp_user_display_name (me) : sp_user_canonical_name (me)); GST_CAT_DEBUG_OBJECT (gst_spot_src_debug_cb, ugly_spot, "Logged_in callback, user=%s", my_name); /* set default bitrate to audiofility */ sp_session_preferred_bitrate(spotify_session, SP_BITRATE_320k); GST_SPOT_SRC_LOGGED_IN (ugly_spot) = TRUE; }
gint main (gint argc, gchar * argv[]) { gst_init (&argc, &argv); GST_DEBUG_CATEGORY_INIT (cat_default, "GST_Check_default", 0, "default category for this test"); GST_DEBUG_CATEGORY_INIT (cat2, "GST_Check_2", 0, "second category for this test"); #ifndef GST_DISABLE_GST_DEBUG g_assert (gst_debug_remove_log_function (gst_debug_log_default) == 1); #endif gst_debug_add_log_function (check_message, NULL); count = 0; GST_ERROR ("This is an error."); ++count; GST_WARNING ("This is a warning."); ++count; GST_INFO ("This is an info message."); ++count; GST_DEBUG ("This is a debug message."); ++count; GST_LOG ("This is a log message."); ++count; GST_CAT_ERROR (cat2, "This is an error with category."); ++count; GST_CAT_WARNING (cat2, "This is a warning with category."); ++count; GST_CAT_INFO (cat2, "This is an info message with category."); ++count; GST_CAT_DEBUG (cat2, "This is a debug message with category."); ++count; GST_CAT_LOG (cat2, "This is a log message with category."); count = -1; pipeline = gst_element_factory_make ("pipeline", "testelement"); count = 10; GST_ERROR_OBJECT (pipeline, "This is an error with object."); ++count; GST_WARNING_OBJECT (pipeline, "This is a warning with object."); ++count; GST_INFO_OBJECT (pipeline, "This is an info message with object."); ++count; GST_DEBUG_OBJECT (pipeline, "This is a debug message with object."); ++count; GST_LOG_OBJECT (pipeline, "This is a log message with object."); ++count; GST_CAT_ERROR_OBJECT (cat2, pipeline, "This is an error with category and object."); ++count; GST_CAT_WARNING_OBJECT (cat2, pipeline, "This is a warning with category and object."); ++count; GST_CAT_INFO_OBJECT (cat2, pipeline, "This is an info message with category and object."); ++count; GST_CAT_DEBUG_OBJECT (cat2, pipeline, "This is a debug message with category and object."); ++count; GST_CAT_LOG_OBJECT (cat2, pipeline, "This is a log message with category and object."); count = -1; #ifndef GST_DISABLE_GST_DEBUG g_assert (gst_debug_remove_log_function (check_message) == 1); #endif return 0; }
static GstFlowReturn gst_spot_src_create_read (GstSpotSrc * spot, guint64 offset, guint length, GstBuffer ** buffer) { if (spot->unlock_state) { return GST_FLOW_WRONG_STATE; } if (G_UNLIKELY (spot->read_position != offset)) { sp_error error; /* implement spotify seek here */ gint sample_rate = GST_SPOT_SRC_FORMAT (spot)->sample_rate; gint channels = GST_SPOT_SRC_FORMAT (spot)->channels; gint64 frames = offset / (channels * sizeof (int16_t)); gint64 seek_usec = frames / ((float)sample_rate / 1000); GST_CAT_DEBUG_OBJECT (gst_spot_src_debug_audio, spot, "Seek_usec = (%" G_GINT64_FORMAT ") = frames (%" G_GINT64_FORMAT ") / sample_rate (%d/1000)", seek_usec, frames, sample_rate); GST_CAT_DEBUG_OBJECT (gst_spot_src_debug_audio, spot, "Perform seek to %" G_GINT64_FORMAT " bytes and %" G_GINT64_FORMAT " usec", offset, seek_usec); error = run_spot_cmd (spot, SPOT_CMD_SEEK, seek_usec); g_mutex_lock (GST_SPOT_SRC_ADAPTER_MUTEX (spot)); gst_adapter_clear (GST_SPOT_SRC_ADAPTER (spot)); g_mutex_unlock (GST_SPOT_SRC_ADAPTER_MUTEX (spot)); run_spot_cmd (spot, SPOT_CMD_PLAY, 0); if (error != SP_ERROR_OK) { GST_CAT_ERROR_OBJECT (gst_spot_src_debug_audio, spot, "Seek failed"); goto create_seek_failed; } spot->read_position = offset; } /* see if we have bytes to write */ GST_CAT_DEBUG_OBJECT (gst_spot_src_debug_audio, spot, "Length=%u offset=%" G_GINT64_FORMAT " end=%" G_GINT64_FORMAT " read_position=%" G_GINT64_FORMAT, length, offset, offset+length, spot->read_position); g_mutex_lock (GST_SPOT_SRC_ADAPTER_MUTEX (spot)); while (1) { *buffer = gst_adapter_take_buffer (GST_SPOT_SRC_ADAPTER (spot), length); if (*buffer) { spot->read_position += length; GST_BUFFER_SIZE (*buffer) = length; GST_BUFFER_OFFSET (*buffer) = offset; GST_BUFFER_OFFSET_END (*buffer) = offset + length; g_mutex_unlock (GST_SPOT_SRC_ADAPTER_MUTEX (spot)); return GST_FLOW_OK; } if (spot->end_of_track) { g_mutex_unlock (GST_SPOT_SRC_ADAPTER_MUTEX (spot)); do_end_of_track (spot); GST_CAT_DEBUG_OBJECT (gst_spot_src_debug_audio, spot, "End of track"); return GST_FLOW_WRONG_STATE; } //should be used in a tight conditional while g_cond_wait (GST_SPOT_SRC_ADAPTER_COND (spot), GST_SPOT_SRC_ADAPTER_MUTEX (spot)); if (spot->unlock_state) { g_mutex_unlock (GST_SPOT_SRC_ADAPTER_MUTEX (spot)); return GST_FLOW_WRONG_STATE; } } GST_CAT_ERROR_OBJECT (gst_spot_src_debug_audio, spot, "Create_read failed"); create_seek_failed: return GST_FLOW_ERROR; }
static void spotify_cb_connection_error (sp_session *spotify_session, sp_error error) { GST_CAT_ERROR_OBJECT (gst_spot_src_debug_cb, ugly_spot, "Connection_error callback %s", sp_error_message (error)); }