From 524abb97453f2140fcd3a7fa66d9d43851af19e1 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Wed, 6 Jun 2012 21:13:43 +0200 Subject: piano: Select quality instead of audio format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pandora limited the audio formats we can request explicitly. Don’t rely on this and use the formats available with the given partner credentials. Closes #271. --- src/libpiano/piano.c | 4 ++++ src/libpiano/piano.h | 12 +++++++++--- src/libpiano/request.c | 31 ------------------------------- src/libpiano/response.c | 35 +++++++++++++++++++++++++++++++++-- src/main.c | 2 +- src/player.c | 4 ---- src/settings.c | 24 ++++++++---------------- src/settings.h | 2 +- 8 files changed, 56 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/libpiano/piano.c b/src/libpiano/piano.c index 74ab3ed..042121e 100644 --- a/src/libpiano/piano.c +++ b/src/libpiano/piano.c @@ -254,6 +254,10 @@ const char *PianoErrorToStr (PianoReturn_t ret) { return "Wrong email address or password."; break; + case PIANO_RET_QUALITY_UNAVAILABLE: + return "Selected audio quality is not available."; + break; + /* pandora error messages */ case PIANO_RET_P_INTERNAL: return "Internal error."; diff --git a/src/libpiano/piano.h b/src/libpiano/piano.h index d8bebcc..4ea164d 100644 --- a/src/libpiano/piano.h +++ b/src/libpiano/piano.h @@ -65,10 +65,15 @@ typedef enum { PIANO_AF_UNKNOWN = 0, PIANO_AF_AACPLUS = 1, PIANO_AF_MP3 = 2, - PIANO_AF_MP3_HI = 3, - PIANO_AF_AACPLUS_LO = 4, } PianoAudioFormat_t; +typedef enum { + PIANO_AQ_UNKNOWN = 0, + PIANO_AQ_LOW = 1, + PIANO_AQ_MEDIUM = 2, + PIANO_AQ_HIGH = 3, +} PianoAudioQuality_t; + typedef struct PianoSong { char *artist; char *stationId; @@ -178,7 +183,7 @@ typedef struct { typedef struct { PianoStation_t *station; - PianoAudioFormat_t format; + PianoAudioQuality_t quality; PianoSong_t *retPlaylist; } PianoRequestDataGetPlaylist_t; @@ -245,6 +250,7 @@ typedef enum { PIANO_RET_CONTINUE_REQUEST = 3, PIANO_RET_OUT_OF_MEMORY = 4, PIANO_RET_INVALID_LOGIN = 5, + PIANO_RET_QUALITY_UNAVAILABLE = 6, /* pandora error codes */ PIANO_RET_P_INTERNAL = PIANO_RET_OFFSET+0, diff --git a/src/libpiano/request.c b/src/libpiano/request.c index 35124f4..871620d 100644 --- a/src/libpiano/request.c +++ b/src/libpiano/request.c @@ -36,34 +36,6 @@ THE SOFTWARE. #include "piano.h" #include "crypt.h" -/* convert audio format id to string - * @param format id - * @return constant string - */ -static const char *PianoAudioFormatToString (PianoAudioFormat_t format) { - switch (format) { - case PIANO_AF_AACPLUS_LO: - return "HTTP_32_AACPLUS"; - break; - - case PIANO_AF_AACPLUS: - return "HTTP_64_AACPLUS"; - break; - - case PIANO_AF_MP3: - return "HTTP_128_MP3"; - break; - - case PIANO_AF_MP3_HI: - return "HTTP_192_MP3"; - break; - - default: - return NULL; - break; - } -} - /* prepare piano request (initializes request type, urlpath and postData) * @param piano handle * @param request structure @@ -156,14 +128,11 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req, assert (reqData != NULL); assert (reqData->station != NULL); assert (reqData->station->id != NULL); - assert (reqData->format != PIANO_AF_UNKNOWN); req->secure = true; json_object_object_add (j, "stationToken", json_object_new_string (reqData->station->id)); - json_object_object_add (j, "additionalAudioUrl", - json_object_new_string (PianoAudioFormatToString (reqData->format))); method = "station.getPlaylist"; break; diff --git a/src/libpiano/response.c b/src/libpiano/response.c index 73b223a..659ed2d 100644 --- a/src/libpiano/response.c +++ b/src/libpiano/response.c @@ -228,6 +228,7 @@ PianoReturn_t PianoResponse (PianoHandle_t *ph, PianoRequest_t *req) { assert (req->responseData != NULL); assert (reqData != NULL); + assert (reqData->quality != PIANO_AQ_UNKNOWN); json_object *items = json_object_object_get (result, "items"); assert (items != NULL); @@ -245,7 +246,37 @@ PianoReturn_t PianoResponse (PianoHandle_t *ph, PianoRequest_t *req) { continue; } - song->audioUrl = PianoJsonStrdup (s, "additionalAudioUrl"); + /* get audio url based on selected quality */ + static const char *qualityMap[] = {"", "lowQuality", "mediumQuality", + "highQuality"}; + assert (reqData->quality < sizeof (qualityMap)/sizeof (*qualityMap)); + static const char *formatMap[] = {"", "aacplus", "mp3"}; + json_object *map = json_object_object_get (s, "audioUrlMap"); + assert (map != NULL); + + if (map != NULL) { + map = json_object_object_get (map, qualityMap[reqData->quality]); + + if (map != NULL) { + const char *encoding = json_object_get_string ( + json_object_object_get (map, "encoding")); + assert (encoding != NULL); + for (size_t k = 0; k < sizeof (formatMap)/sizeof (*formatMap); k++) { + if (strcmp (formatMap[k], encoding) == 0) { + song->audioFormat = k; + break; + } + } + song->audioUrl = PianoJsonStrdup (map, "audioUrl"); + } else { + /* requested quality is not available */ + ret = PIANO_RET_QUALITY_UNAVAILABLE; + free (song); + PianoDestroyPlaylist (playlist); + goto cleanup; + } + } + song->artist = PianoJsonStrdup (s, "artistName"); song->album = PianoJsonStrdup (s, "albumName"); song->title = PianoJsonStrdup (s, "songName"); @@ -255,7 +286,6 @@ PianoReturn_t PianoResponse (PianoHandle_t *ph, PianoRequest_t *req) { song->detailUrl = PianoJsonStrdup (s, "songDetailUrl"); song->fileGain = json_object_get_double ( json_object_object_get (s, "trackGain")); - song->audioFormat = reqData->format; switch (json_object_get_int (json_object_object_get (s, "songRating"))) { case 1: @@ -665,6 +695,7 @@ PianoReturn_t PianoResponse (PianoHandle_t *ph, PianoRequest_t *req) { } } +cleanup: json_object_put (j); return ret; diff --git a/src/main.c b/src/main.c index b140e20..2e957dd 100644 --- a/src/main.c +++ b/src/main.c @@ -163,7 +163,7 @@ static void BarMainGetPlaylist (BarApp_t *app) { WaitressReturn_t wRet; PianoRequestDataGetPlaylist_t reqData; reqData.station = app->curStation; - reqData.format = app->settings.audioFormat; + reqData.quality = app->settings.audioQuality; BarUiMsg (&app->settings, MSG_INFO, "Receiving new playlist... "); if (!BarUiPianoCall (app, PIANO_REQUEST_GET_PLAYLIST, diff --git a/src/player.c b/src/player.c index 3877906..0e249dc 100644 --- a/src/player.c +++ b/src/player.c @@ -428,7 +428,6 @@ void *BarPlayerThread (void *data) { switch (player->audioFormat) { #ifdef ENABLE_FAAD - case PIANO_AF_AACPLUS_LO: case PIANO_AF_AACPLUS: player->aacHandle = NeAACDecOpen(); /* set aac conf */ @@ -443,7 +442,6 @@ void *BarPlayerThread (void *data) { #ifdef ENABLE_MAD case PIANO_AF_MP3: - case PIANO_AF_MP3_HI: mad_stream_init (&player->mp3Stream); mad_frame_init (&player->mp3Frame); mad_synth_init (&player->mp3Synth); @@ -472,7 +470,6 @@ void *BarPlayerThread (void *data) { switch (player->audioFormat) { #ifdef ENABLE_FAAD - case PIANO_AF_AACPLUS_LO: case PIANO_AF_AACPLUS: NeAACDecClose(player->aacHandle); free (player->sampleSize); @@ -481,7 +478,6 @@ void *BarPlayerThread (void *data) { #ifdef ENABLE_MAD case PIANO_AF_MP3: - case PIANO_AF_MP3_HI: mad_synth_finish (&player->mp3Synth); mad_frame_finish (&player->mp3Frame); mad_stream_finish (&player->mp3Stream); diff --git a/src/settings.c b/src/settings.c index 3541e28..058c3a7 100644 --- a/src/settings.c +++ b/src/settings.c @@ -121,13 +121,7 @@ void BarSettingsRead (BarSettings_t *settings) { sizeof (dispatchActions) / sizeof (*dispatchActions)); /* apply defaults */ - #ifdef ENABLE_FAAD - settings->audioFormat = PIANO_AF_AACPLUS; - #else - #ifdef ENABLE_MAD - settings->audioFormat = PIANO_AF_MP3; - #endif - #endif + settings->audioQuality = PIANO_AQ_HIGH; settings->autoselect = true; settings->history = 5; settings->volume = 0; @@ -226,15 +220,13 @@ void BarSettingsRead (BarSettings_t *settings) { break; } } - } else if (streq ("audio_format", key)) { - if (streq (val, "aacplus")) { - settings->audioFormat = PIANO_AF_AACPLUS; - } else if (streq (val, "aacplus-lofi")) { - settings->audioFormat = PIANO_AF_AACPLUS_LO; - } else if (streq (val, "mp3")) { - settings->audioFormat = PIANO_AF_MP3; - } else if (streq (val, "mp3-hifi")) { - settings->audioFormat = PIANO_AF_MP3_HI; + } else if (streq ("audio_quality", key)) { + if (streq (val, "low")) { + settings->audioQuality = PIANO_AQ_LOW; + } else if (streq (val, "medium")) { + settings->audioQuality = PIANO_AQ_MEDIUM; + } else if (streq (val, "high")) { + settings->audioQuality = PIANO_AQ_HIGH; } } else if (streq ("autostart_station", key)) { settings->autostartStation = strdup (val); diff --git a/src/settings.h b/src/settings.h index ac31653..a466b72 100644 --- a/src/settings.h +++ b/src/settings.h @@ -84,7 +84,7 @@ typedef struct { unsigned int history; int volume; BarStationSorting_t sortOrder; - PianoAudioFormat_t audioFormat; + PianoAudioQuality_t audioQuality; char *username; char *password; char *controlProxy; /* non-american listeners need this */ -- cgit v1.2.3