finhsing CSpot integration

This commit is contained in:
Philippe G
2021-12-24 21:56:42 -08:00
parent e2bcb041e9
commit 7f894f1635
11 changed files with 102 additions and 89 deletions

View File

@@ -110,7 +110,6 @@ static void cspotTask(void *pvParameters) {
if (token.size() > 0 && cspot.cHandler(CSPOT_SETUP, 44100)) { if (token.size() > 0 && cspot.cHandler(CSPOT_SETUP, 44100)) {
auto audioSink = std::make_shared<ShimAudioSink>(); auto audioSink = std::make_shared<ShimAudioSink>();
// @TODO Actually store this token somewhere
mercuryManager = std::make_shared<MercuryManager>(std::move(session)); mercuryManager = std::make_shared<MercuryManager>(std::move(session));
mercuryManager->startTask(); mercuryManager->startTask();
@@ -120,7 +119,7 @@ static void cspotTask(void *pvParameters) {
switch (event.eventType) { switch (event.eventType) {
case CSpotEventType::TRACK_INFO: { case CSpotEventType::TRACK_INFO: {
TrackInfo track = std::get<TrackInfo>(event.data); TrackInfo track = std::get<TrackInfo>(event.data);
cspot.cHandler(CSPOT_TRACK, 44100, track.artist.c_str(), track.album.c_str(), track.name.c_str()); cspot.cHandler(CSPOT_TRACK, 44100, track.duration, track.artist.c_str(), track.album.c_str(), track.name.c_str());
break; break;
} }
case CSpotEventType::PLAY_PAUSE: { case CSpotEventType::PLAY_PAUSE: {
@@ -129,6 +128,9 @@ static void cspotTask(void *pvParameters) {
else cspot.cHandler(CSPOT_PLAY); else cspot.cHandler(CSPOT_PLAY);
break; break;
} }
case CSpotEventType::LOAD:
cspot.cHandler(CSPOT_LOAD, std::get<int>(event.data), -1);
break;
case CSpotEventType::SEEK: case CSpotEventType::SEEK:
cspot.cHandler(CSPOT_SEEK, std::get<int>(event.data)); cspot.cHandler(CSPOT_SEEK, std::get<int>(event.data));
break; break;
@@ -165,12 +167,11 @@ static void cspotTask(void *pvParameters) {
spircController.reset(); spircController.reset();
} }
// release auth blob // release auth blob and flush files
cspot.blob.reset(); cspot.blob.reset();
// flush files
file->flush(); file->flush();
ESP_LOGW(TAG, "THIS SESSION IS FINISHED %ld %ld %ld", mercuryManager.use_count(), spircController.use_count(), cspot.blob.use_count());
ESP_LOGI(TAG, "Shutting down CSpot player");
} }
// we should not be here // we should not be here

View File

@@ -24,6 +24,7 @@ enum class CSpotEventType {
NEXT, NEXT,
PREV, PREV,
SEEK, SEEK,
LOAD,
}; };
struct CSpotEvent { struct CSpotEvent {

View File

@@ -20,6 +20,7 @@ struct TrackInfo {
std::string album; std::string album;
std::string artist; std::string artist;
std::string imageUrl; std::string imageUrl;
int duration;
}; };
typedef std::function<void(TrackInfo&)> trackChangedCallback; typedef std::function<void(TrackInfo&)> trackChangedCallback;

View File

@@ -34,7 +34,7 @@ message Track {
optional string name = 2; optional string name = 2;
optional Album album = 0x3; optional Album album = 0x3;
repeated Artist artist = 0x4; repeated Artist artist = 0x4;
optional sint32 duration = 7; optional sint32 duration = 0x7;
repeated Restriction restriction = 0xb; repeated Restriction restriction = 0xb;
repeated AudioFile file = 0xc; repeated AudioFile file = 0xc;
repeated Track alternative = 0xd; repeated Track alternative = 0xd;

View File

@@ -9,18 +9,18 @@ ReflectType::ofEnum(/* mine id */ ReflectTypeID::EnumReflectTypeID, /* name */ "
ReflectEnumValue("EnumReflectTypeKind", 4), ReflectEnumValue("EnumReflectTypeKind", 4),
ReflectEnumValue("VectorOfClassReflectField", 5), ReflectEnumValue("VectorOfClassReflectField", 5),
ReflectEnumValue("VectorOfClassReflectEnumValue", 6), ReflectEnumValue("VectorOfClassReflectEnumValue", 6),
ReflectEnumValue("Double", 7), ReflectEnumValue("Int32", 7),
ReflectEnumValue("Uint32", 8), ReflectEnumValue("Int64", 8),
ReflectEnumValue("Char", 9), ReflectEnumValue("Uint32", 9),
ReflectEnumValue("UnsignedChar", 10), ReflectEnumValue("Uint8", 10),
ReflectEnumValue("Float", 11), ReflectEnumValue("Int", 11),
ReflectEnumValue("Bool", 12), ReflectEnumValue("UnsignedChar", 12),
ReflectEnumValue("String", 13), ReflectEnumValue("Float", 13),
ReflectEnumValue("Int32", 14), ReflectEnumValue("String", 14),
ReflectEnumValue("Int64", 15), ReflectEnumValue("Uint64", 15),
ReflectEnumValue("Int", 16), ReflectEnumValue("Char", 16),
ReflectEnumValue("Uint8", 17), ReflectEnumValue("Double", 17),
ReflectEnumValue("Uint64", 18), ReflectEnumValue("Bool", 18),
ReflectEnumValue("VectorOfUint8", 19), ReflectEnumValue("VectorOfUint8", 19),
ReflectEnumValue("EnumCpuFamily", 20), ReflectEnumValue("EnumCpuFamily", 20),
ReflectEnumValue("EnumOs", 21), ReflectEnumValue("EnumOs", 21),
@@ -174,18 +174,18 @@ ReflectType::ofEnum(/* mine id */ ReflectTypeID::EnumReflectTypeKind, /* name */
, ,
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Double, /* name */ "double", /* size */ sizeof(double)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Uint32, /* name */ "uint32_t", /* size */ sizeof(uint32_t)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Char, /* name */ "char", /* size */ sizeof(char)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::UnsignedChar, /* name */ "unsigned char", /* size */ sizeof(unsigned char)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Float, /* name */ "float", /* size */ sizeof(float)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Bool, /* name */ "bool", /* size */ sizeof(bool)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::String, /* name */ "std::string", /* size */ sizeof(std::string)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Int32, /* name */ "int32_t", /* size */ sizeof(int32_t)), ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Int32, /* name */ "int32_t", /* size */ sizeof(int32_t)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Int64, /* name */ "int64_t", /* size */ sizeof(int64_t)), ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Int64, /* name */ "int64_t", /* size */ sizeof(int64_t)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Int, /* name */ "int", /* size */ sizeof(int)), ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Uint32, /* name */ "uint32_t", /* size */ sizeof(uint32_t)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Uint8, /* name */ "uint8_t", /* size */ sizeof(uint8_t)), ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Uint8, /* name */ "uint8_t", /* size */ sizeof(uint8_t)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Int, /* name */ "int", /* size */ sizeof(int)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::UnsignedChar, /* name */ "unsigned char", /* size */ sizeof(unsigned char)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Float, /* name */ "float", /* size */ sizeof(float)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::String, /* name */ "std::string", /* size */ sizeof(std::string)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Uint64, /* name */ "uint64_t", /* size */ sizeof(uint64_t)), ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Uint64, /* name */ "uint64_t", /* size */ sizeof(uint64_t)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Char, /* name */ "char", /* size */ sizeof(char)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Double, /* name */ "double", /* size */ sizeof(double)),
ReflectType::ofPrimitive(/* type id */ ReflectTypeID::Bool, /* name */ "bool", /* size */ sizeof(bool)),
ReflectType::ofVector( ReflectType::ofVector(
/* mine typeId */ ReflectTypeID::VectorOfUint8, /* mine typeId */ ReflectTypeID::VectorOfUint8,

View File

@@ -11,18 +11,18 @@ ClassReflectType = 3,
EnumReflectTypeKind = 4, EnumReflectTypeKind = 4,
VectorOfClassReflectField = 5, VectorOfClassReflectField = 5,
VectorOfClassReflectEnumValue = 6, VectorOfClassReflectEnumValue = 6,
Double = 7, Int32 = 7,
Uint32 = 8, Int64 = 8,
Char = 9, Uint32 = 9,
UnsignedChar = 10, Uint8 = 10,
Float = 11, Int = 11,
Bool = 12, UnsignedChar = 12,
String = 13, Float = 13,
Int32 = 14, String = 14,
Int64 = 15, Uint64 = 15,
Int = 16, Char = 16,
Uint8 = 17, Double = 17,
Uint64 = 18, Bool = 18,
VectorOfUint8 = 19, VectorOfUint8 = 19,
EnumCpuFamily = 20, EnumCpuFamily = 20,
EnumOs = 21, EnumOs = 21,

View File

@@ -113,14 +113,20 @@ class Frame;
if constexpr(std::is_same<T, std::vector<ReflectEnumValue>>::value) { if constexpr(std::is_same<T, std::vector<ReflectEnumValue>>::value) {
return ReflectTypeID::VectorOfClassReflectEnumValue == this->typeID; return ReflectTypeID::VectorOfClassReflectEnumValue == this->typeID;
} else } else
if constexpr(std::is_same<T, double>::value) { if constexpr(std::is_same<T, int32_t>::value) {
return ReflectTypeID::Double == this->typeID; return ReflectTypeID::Int32 == this->typeID;
} else
if constexpr(std::is_same<T, int64_t>::value) {
return ReflectTypeID::Int64 == this->typeID;
} else } else
if constexpr(std::is_same<T, uint32_t>::value) { if constexpr(std::is_same<T, uint32_t>::value) {
return ReflectTypeID::Uint32 == this->typeID; return ReflectTypeID::Uint32 == this->typeID;
} else } else
if constexpr(std::is_same<T, char>::value) { if constexpr(std::is_same<T, uint8_t>::value) {
return ReflectTypeID::Char == this->typeID; return ReflectTypeID::Uint8 == this->typeID;
} else
if constexpr(std::is_same<T, int>::value) {
return ReflectTypeID::Int == this->typeID;
} else } else
if constexpr(std::is_same<T, unsigned char>::value) { if constexpr(std::is_same<T, unsigned char>::value) {
return ReflectTypeID::UnsignedChar == this->typeID; return ReflectTypeID::UnsignedChar == this->typeID;
@@ -128,27 +134,21 @@ class Frame;
if constexpr(std::is_same<T, float>::value) { if constexpr(std::is_same<T, float>::value) {
return ReflectTypeID::Float == this->typeID; return ReflectTypeID::Float == this->typeID;
} else } else
if constexpr(std::is_same<T, bool>::value) {
return ReflectTypeID::Bool == this->typeID;
} else
if constexpr(std::is_same<T, std::string>::value) { if constexpr(std::is_same<T, std::string>::value) {
return ReflectTypeID::String == this->typeID; return ReflectTypeID::String == this->typeID;
} else } else
if constexpr(std::is_same<T, int32_t>::value) {
return ReflectTypeID::Int32 == this->typeID;
} else
if constexpr(std::is_same<T, int64_t>::value) {
return ReflectTypeID::Int64 == this->typeID;
} else
if constexpr(std::is_same<T, int>::value) {
return ReflectTypeID::Int == this->typeID;
} else
if constexpr(std::is_same<T, uint8_t>::value) {
return ReflectTypeID::Uint8 == this->typeID;
} else
if constexpr(std::is_same<T, uint64_t>::value) { if constexpr(std::is_same<T, uint64_t>::value) {
return ReflectTypeID::Uint64 == this->typeID; return ReflectTypeID::Uint64 == this->typeID;
} else } else
if constexpr(std::is_same<T, char>::value) {
return ReflectTypeID::Char == this->typeID;
} else
if constexpr(std::is_same<T, double>::value) {
return ReflectTypeID::Double == this->typeID;
} else
if constexpr(std::is_same<T, bool>::value) {
return ReflectTypeID::Bool == this->typeID;
} else
if constexpr(std::is_same<T, std::vector<uint8_t>>::value) { if constexpr(std::is_same<T, std::vector<uint8_t>>::value) {
return ReflectTypeID::VectorOfUint8 == this->typeID; return ReflectTypeID::VectorOfUint8 == this->typeID;
} else } else
@@ -296,14 +296,20 @@ class Frame;
if constexpr(std::is_same<T, std::vector<ReflectEnumValue>>::value) { if constexpr(std::is_same<T, std::vector<ReflectEnumValue>>::value) {
typeID = ReflectTypeID::VectorOfClassReflectEnumValue; typeID = ReflectTypeID::VectorOfClassReflectEnumValue;
} else } else
if constexpr(std::is_same<T, double>::value) { if constexpr(std::is_same<T, int32_t>::value) {
typeID = ReflectTypeID::Double; typeID = ReflectTypeID::Int32;
} else
if constexpr(std::is_same<T, int64_t>::value) {
typeID = ReflectTypeID::Int64;
} else } else
if constexpr(std::is_same<T, uint32_t>::value) { if constexpr(std::is_same<T, uint32_t>::value) {
typeID = ReflectTypeID::Uint32; typeID = ReflectTypeID::Uint32;
} else } else
if constexpr(std::is_same<T, char>::value) { if constexpr(std::is_same<T, uint8_t>::value) {
typeID = ReflectTypeID::Char; typeID = ReflectTypeID::Uint8;
} else
if constexpr(std::is_same<T, int>::value) {
typeID = ReflectTypeID::Int;
} else } else
if constexpr(std::is_same<T, unsigned char>::value) { if constexpr(std::is_same<T, unsigned char>::value) {
typeID = ReflectTypeID::UnsignedChar; typeID = ReflectTypeID::UnsignedChar;
@@ -311,27 +317,21 @@ class Frame;
if constexpr(std::is_same<T, float>::value) { if constexpr(std::is_same<T, float>::value) {
typeID = ReflectTypeID::Float; typeID = ReflectTypeID::Float;
} else } else
if constexpr(std::is_same<T, bool>::value) {
typeID = ReflectTypeID::Bool;
} else
if constexpr(std::is_same<T, std::string>::value) { if constexpr(std::is_same<T, std::string>::value) {
typeID = ReflectTypeID::String; typeID = ReflectTypeID::String;
} else } else
if constexpr(std::is_same<T, int32_t>::value) {
typeID = ReflectTypeID::Int32;
} else
if constexpr(std::is_same<T, int64_t>::value) {
typeID = ReflectTypeID::Int64;
} else
if constexpr(std::is_same<T, int>::value) {
typeID = ReflectTypeID::Int;
} else
if constexpr(std::is_same<T, uint8_t>::value) {
typeID = ReflectTypeID::Uint8;
} else
if constexpr(std::is_same<T, uint64_t>::value) { if constexpr(std::is_same<T, uint64_t>::value) {
typeID = ReflectTypeID::Uint64; typeID = ReflectTypeID::Uint64;
} else } else
if constexpr(std::is_same<T, char>::value) {
typeID = ReflectTypeID::Char;
} else
if constexpr(std::is_same<T, double>::value) {
typeID = ReflectTypeID::Double;
} else
if constexpr(std::is_same<T, bool>::value) {
typeID = ReflectTypeID::Bool;
} else
if constexpr(std::is_same<T, std::vector<uint8_t>>::value) { if constexpr(std::is_same<T, std::vector<uint8_t>>::value) {
typeID = ReflectTypeID::VectorOfUint8; typeID = ReflectTypeID::VectorOfUint8;
} else } else
@@ -473,18 +473,18 @@ class Frame;
ReflectTypeKind *u_EnumReflectTypeKind; ReflectTypeKind *u_EnumReflectTypeKind;
std::vector<ReflectField> *u_VectorOfClassReflectField; std::vector<ReflectField> *u_VectorOfClassReflectField;
std::vector<ReflectEnumValue> *u_VectorOfClassReflectEnumValue; std::vector<ReflectEnumValue> *u_VectorOfClassReflectEnumValue;
double *u_Double;
uint32_t *u_Uint32;
char *u_Char;
unsigned char *u_UnsignedChar;
float *u_Float;
bool *u_Bool;
std::string *u_String;
int32_t *u_Int32; int32_t *u_Int32;
int64_t *u_Int64; int64_t *u_Int64;
int *u_Int; uint32_t *u_Uint32;
uint8_t *u_Uint8; uint8_t *u_Uint8;
int *u_Int;
unsigned char *u_UnsignedChar;
float *u_Float;
std::string *u_String;
uint64_t *u_Uint64; uint64_t *u_Uint64;
char *u_Char;
double *u_Double;
bool *u_Bool;
std::vector<uint8_t> *u_VectorOfUint8; std::vector<uint8_t> *u_VectorOfUint8;
CpuFamily *u_EnumCpuFamily; CpuFamily *u_EnumCpuFamily;
Os *u_EnumOs; Os *u_EnumOs;

View File

@@ -182,6 +182,7 @@ void SpircController::handleFrame(std::vector<uint8_t> &data) {
} }
void SpircController::loadTrack(uint32_t position_ms, bool isPaused) { void SpircController::loadTrack(uint32_t position_ms, bool isPaused) {
sendEvent(CSpotEventType::LOAD, (int) position_ms);
state->setPlaybackState(PlaybackState::Loading); state->setPlaybackState(PlaybackState::Loading);
std::function<void()> loadedLambda = [=]() { std::function<void()> loadedLambda = [=]() {
// Loading finished, notify that playback started // Loading finished, notify that playback started
@@ -216,6 +217,7 @@ void SpircController::setEventHandler(cspotEventHandler callback) {
info.artist = track.artist; info.artist = track.artist;
info.imageUrl = track.imageUrl; info.imageUrl = track.imageUrl;
info.name = track.name; info.name = track.name;
info.duration = track.duration;
this->sendEvent(CSpotEventType::TRACK_INFO, info); this->sendEvent(CSpotEventType::TRACK_INFO, info);
}); });

View File

@@ -99,12 +99,13 @@ void SpotifyTrack::trackInformationCallback(std::unique_ptr<MercuryResponse> res
if (trackInfoReceived != nullptr) if (trackInfoReceived != nullptr)
{ {
CSPOT_LOG(info, "Calling %d", trackInfo.album.value().cover_group.value().image.size());
TrackInfo simpleTrackInfo = { TrackInfo simpleTrackInfo = {
.name = trackInfo.name.value(), .name = trackInfo.name.value(),
.album = trackInfo.album.value().name.value(), .album = trackInfo.album.value().name.value(),
.artist = trackInfo.artist[0].name.value(), .artist = trackInfo.artist[0].name.value(),
.imageUrl = "https://i.scdn.co/image/" + bytesToHexString(trackInfo.album.value().cover_group.value().image[0].file_id.value()) .imageUrl = "https://i.scdn.co/image/" + bytesToHexString(trackInfo.album.value().cover_group.value().image[0].file_id.value()),
.duration = trackInfo.duration.value(),
}; };
trackInfoReceived(simpleTrackInfo); trackInfoReceived(simpleTrackInfo);

View File

@@ -90,6 +90,7 @@ const static actrls_t controls = {
*/ */
static bool cmd_handler(cspot_event_t event, ...) { static bool cmd_handler(cspot_event_t event, ...) {
va_list args; va_list args;
static bool loaded = false;
va_start(args, event); va_start(args, event);
@@ -115,14 +116,20 @@ static bool cmd_handler(cspot_event_t event, ...) {
actrls_unset(); actrls_unset();
displayer_control(DISPLAYER_SUSPEND); displayer_control(DISPLAYER_SUSPEND);
break; break;
case CSPOT_LOAD:
// this message only appears if we load in the middle of a track
loaded = true;
__attribute__ ((fallthrough));
case CSPOT_SEEK: case CSPOT_SEEK:
displayer_timer(DISPLAYER_ELAPSED, va_arg(args, int), -1); displayer_timer(DISPLAYER_ELAPSED, va_arg(args, int), -1);
break; break;
case CSPOT_TRACK: { case CSPOT_TRACK: {
uint32_t sample_rate = va_arg(args, uint32_t); uint32_t sample_rate = va_arg(args, uint32_t);
int duration = va_arg(args, int);
char *artist = va_arg(args, char*), *album = va_arg(args, char*), *title = va_arg(args, char*); char *artist = va_arg(args, char*), *album = va_arg(args, char*), *title = va_arg(args, char*);
displayer_metadata(artist, album, title); displayer_metadata(artist, album, title);
displayer_timer(DISPLAYER_ELAPSED, 0, -1); displayer_timer(DISPLAYER_ELAPSED, loaded ? -1 : 0, duration);
loaded = false;
break; break;
} }
// nothing to do on CSPOT_FLUSH // nothing to do on CSPOT_FLUSH

View File

@@ -16,7 +16,7 @@ extern "C"
#endif #endif
// STOP means remove playlist, FLUSH means flush audio buffer, DISC means bye-bye // STOP means remove playlist, FLUSH means flush audio buffer, DISC means bye-bye
typedef enum { CSPOT_SETUP, CSPOT_DISC, CSPOT_FLUSH, CSPOT_STOP, CSPOT_PLAY, CSPOT_PAUSE, CSPOT_SEEK, CSPOT_TRACK, typedef enum { CSPOT_SETUP, CSPOT_DISC, CSPOT_FLUSH, CSPOT_STOP, CSPOT_PLAY, CSPOT_PAUSE, CSPOT_SEEK, CSPOT_TRACK, CSPOT_LOAD,
CSPOT_VOLUME, CSPOT_VOLUME_UP, CSPOT_VOLUME_DOWN, CSPOT_NEXT, CSPOT_PREV, CSPOT_TOGGLE, CSPOT_VOLUME, CSPOT_VOLUME_UP, CSPOT_VOLUME_DOWN, CSPOT_NEXT, CSPOT_PREV, CSPOT_TOGGLE,
} cspot_event_t; } cspot_event_t;