Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <unistd.h>
- #include <libspotify/api.h>
- #include <allegro5/allegro.h>
- #include <allegro5/allegro_audio.h>
- #define DEBUG 0 // change to 1 for debugging information
- extern const uint8_t g_appkey[];
- extern const size_t g_appkey_size;
- extern const char *username;
- extern const char *password;
- static bool g_logged_in;
- static bool g_playing;
- static bool g_running;
- static ALLEGRO_AUDIO_STREAM *stream;
- static ALLEGRO_EVENT_SOURCE sp_notify_event_source;
- ALLEGRO_EVENT sp_notify_event;
- void debug(const char *format, ...)
- {
- if (!DEBUG)
- return;
- va_list argptr;
- va_start(argptr, format);
- vprintf(format, argptr);
- printf("\n");
- }
- void play(sp_session *session, sp_track *track)
- {
- sp_error error = sp_session_player_load(session, track);
- if (error != SP_ERROR_OK) {
- fprintf(stderr, "Error: %s\n", sp_error_message(error));
- exit(1);
- }
- sp_session_player_play(session, 1);
- al_emit_user_event(&sp_notify_event_source, &sp_notify_event, NULL);
- }
- static void on_search_complete(sp_search *search, void *userdata)
- {
- debug("callback: on_search_complete");
- sp_error error = sp_search_error(search);
- if (error != SP_ERROR_OK) {
- fprintf(stderr, "Error: %s\n", sp_error_message(error));
- exit(1);
- }
- int num_tracks = sp_search_num_tracks(search);
- if (num_tracks == 0) {
- fprintf(stderr, "Sorry, couldn't find that track. =/\n\n");
- sp_search_release(search);
- g_playing = 0;
- return;
- }
- sp_track *track = sp_search_track(search, 0);
- play((sp_session*)userdata, track);
- sp_search_release(search);
- }
- static void on_login(sp_session *session, sp_error error)
- {
- debug("callback: on_login");
- if (error != SP_ERROR_OK) {
- fprintf(stderr, "login failed: %s\n", sp_error_message(error));
- exit(2);
- }
- g_logged_in = 1;
- }
- static void on_notify_main_thread(sp_session *session)
- {
- debug("callback: on_notify_main_thread");
- al_emit_user_event(&sp_notify_event_source, &sp_notify_event, NULL);
- }
- static int on_music_delivery(sp_session *session, const sp_audioformat *format, const void *frames, int num_frames)
- {
- debug("callback: on_music_delivery");
- debug(" sample type: %d", format->sample_type);
- debug(" sample rate: %d", format->sample_rate);
- debug(" channels: %d", format->channels);
- void *buffer = al_get_audio_stream_fragment(stream);
- if (buffer == NULL) {
- return 0;
- }
- int max = (num_frames < 2048 ? num_frames : 2048);
- memcpy(buffer, frames, max);
- al_set_audio_stream_fragment(stream, buffer);
- return max;
- }
- static void on_end_of_track(sp_session *session)
- {
- debug("callback: on_end_of_track");
- }
- static void on_log(sp_session *session, const char *data)
- {
- debug("spotify: %s\n", data);
- }
- static sp_session_callbacks session_callbacks = {
- .logged_in = &on_login,
- .notify_main_thread = &on_notify_main_thread,
- .music_delivery = &on_music_delivery,
- .log_message = &on_log,
- .end_of_track = &on_end_of_track
- };
- static sp_session_config spconfig = {
- .api_version = SPOTIFY_API_VERSION,
- .cache_location = "/tmp/spot",
- .settings_location = "/tmp/spot",
- .application_key = g_appkey,
- .application_key_size = 0, // set in main()
- .user_agent = "spot",
- .callbacks = &session_callbacks,
- NULL
- };
- // Initialize the Spotify session.
- sp_session *init_spotify()
- {
- sp_error error;
- sp_session *session;
- spconfig.application_key_size = g_appkey_size;
- if ((error = sp_session_create(&spconfig, &session)) != SP_ERROR_OK) {
- fprintf(stderr, "unable to create session: %s\n", sp_error_message(error));
- exit(1);
- }
- g_logged_in = 0;
- sp_session_login(session, username, password, 0, NULL);
- return session;
- }
- // Initialize Allegro.
- void init_allegro()
- {
- if (!al_init()) {
- printf("failed to start allegro!\n");
- exit(1);
- }
- if (!al_install_audio()) {
- printf("failed to install audio subsystem!\n");
- exit(1);
- }
- if (!al_reserve_samples(1)) {
- printf("failed to reserve an audio sample!\n");
- exit(1);
- }
- al_init_user_event_source(&sp_notify_event_source);
- sp_notify_event.user.type = ALLEGRO_GET_EVENT_TYPE('S', 'P', 'O', 'T');
- ALLEGRO_CHANNEL_CONF chan_conf = ALLEGRO_CHANNEL_CONF_2;
- ALLEGRO_AUDIO_DEPTH depth = ALLEGRO_AUDIO_DEPTH_INT16;
- int bytes_per_fragment = 2048; // no idea what I'm doing here
- int fragment_count = 2;
- int freq = 2048; // again, no idea
- int sample_size = al_get_channel_count(chan_conf) * al_get_audio_depth_size(depth);
- int samples = bytes_per_fragment / sample_size;
- //int buffer_size = bytes_per_fragment * fragment_count;
- stream = al_create_audio_stream(fragment_count, samples, freq, depth, chan_conf);
- al_attach_audio_stream_to_mixer(stream, al_get_default_mixer());
- }
- void play_song(sp_session *session, char *artist, char *track)
- {
- char q[4096];
- sprintf(q, "artist:\"%s\" track:\"%s\"", artist, track);
- sp_search_create(session, q, 0, 1, 0, 0, 0, 0, 0, 0, SP_SEARCH_STANDARD, &on_search_complete, session);
- }
- int main(void)
- {
- sp_session *session = init_spotify();
- play_song(session, "Green Day", "Welcome to Paradise");
- init_allegro();
- ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue();
- al_register_event_source(event_queue, &sp_notify_event_source);
- // main loop
- g_running = 1;
- int next_timeout = 0;
- // start the ball rolling
- sp_session_process_events(session, &next_timeout);
- ALLEGRO_EVENT event;
- while (g_running) {
- al_wait_for_event(event_queue, &event);
- switch (event.type) {
- case ALLEGRO_GET_EVENT_TYPE('S', 'P', 'O', 'T'):
- // process Spotify events
- do {
- sp_session_process_events(session, &next_timeout);
- } while (next_timeout == 0);
- break;
- default:
- break;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement