134 lines
4.0 KiB
C++
134 lines
4.0 KiB
C++
#pragma once
|
|
|
|
extern std::vector<uint16_t> melody_steps;
|
|
|
|
void PublishMqtt(const char * data);
|
|
|
|
class Player {
|
|
public:
|
|
uint16_t id; // The (internal) ID of the selected melody. Not specificly used anywhere atm. Might be used later.
|
|
std::string name = "melody1"; // Name of the Melody saved. Will be used to read the file: /name.bin
|
|
uint16_t speed = 500; // Time to wait per beat. (In Miliseconds)
|
|
uint32_t duration = 15000; // Total Duration that program will run (In Miliseconds)
|
|
uint32_t loop_duration = 0; // Duration of the playback per segment
|
|
uint32_t interval = 0; // Indicates the Duration of the Interval between finished segments, IF "inf" is true
|
|
bool infinite_play = false; // Infinite Loop Indicator (If True the melody will loop forever or until stoped, with pauses of "interval" in between loops)
|
|
bool isPlaying = false; // Indicates if the Melody is actually Playing right now.
|
|
bool isPaused = false; // If playing, indicates if the Melody is Paused
|
|
uint64_t startTime = 0; // The time-point the Melody started Playing
|
|
uint64_t loopStartTime = 0; // The time-point the current segment started Playing
|
|
bool hardStop = false; // Flags a hardstop, immediately.
|
|
uint64_t pauseTime = 0; // The time-point the melody paused
|
|
|
|
void play() {
|
|
isPlaying = true;
|
|
hardStop = false;
|
|
startTime = loopStartTime = millis();
|
|
LOG_DEBUG("Plbck: PLAY");
|
|
}
|
|
|
|
void forceStop() {
|
|
hardStop = true;
|
|
isPlaying = false;
|
|
LOG_DEBUG("Plbck: FORCE STOP");
|
|
}
|
|
|
|
void stop() {
|
|
hardStop = false;
|
|
isPlaying = false;
|
|
LOG_DEBUG("Plbck: STOP");
|
|
}
|
|
|
|
void pause() {
|
|
isPaused = true;
|
|
LOG_DEBUG("Plbck: PAUSE");
|
|
}
|
|
|
|
void unpause() {
|
|
isPaused = false;
|
|
loopStartTime = millis();
|
|
LOG_DEBUG("Plbck: RESUME");
|
|
}
|
|
|
|
// Handles Incoming Commands to PLAY or STOP
|
|
void command(JsonVariant content){
|
|
String action = content["action"];
|
|
LOG_DEBUG("Incoming Command: %s", action);
|
|
if (action == "play") {
|
|
play();
|
|
PublishMqtt("OK - PLAY");
|
|
} else if (action == "stop") {
|
|
forceStop();
|
|
PublishMqtt("OK - STOP");
|
|
}
|
|
}
|
|
|
|
// Sets incoming Attributes for the Melody, into the class' variables.
|
|
void setMelodyAttributes(JsonVariant doc){
|
|
|
|
if (doc.containsKey("name")) {
|
|
name = doc["name"].as<const char*>();
|
|
}
|
|
if (doc.containsKey("id")) {
|
|
id = doc["id"].as<uint16_t>();
|
|
}
|
|
if (doc.containsKey("duration")) {
|
|
duration = doc["duration"].as<uint32_t>();
|
|
}
|
|
if (doc.containsKey("infinite")) {
|
|
infinite_play = doc["infinite"].as<bool>();
|
|
}
|
|
if (doc.containsKey("interval")) {
|
|
interval = doc["interval"].as<uint32_t>();
|
|
}
|
|
if (doc.containsKey("speed")) {
|
|
speed = doc["speed"].as<uint16_t>();
|
|
}
|
|
if (doc.containsKey("loop_dur")) {
|
|
loop_duration = doc["loop_dur"].as<uint32_t>();
|
|
}
|
|
// Print Just for Debugging Purposes
|
|
LOG_DEBUG("Name: %s, ID: %d, Total Duration: %lu, Loop Duration: %lu, Interval: %d, Speed: %d, Inf: %s\n",
|
|
name.c_str(),
|
|
id,
|
|
duration,
|
|
loop_duration,
|
|
interval,
|
|
speed,
|
|
infinite_play ? "true" : "false"
|
|
);
|
|
}
|
|
|
|
|
|
// Loads the Selected melody from a .bin file on SD into RAM
|
|
void loadMelodyInRAM(std::vector<uint16_t> &melody_steps) {
|
|
String filePath = "/melodies/" + String(name.c_str()) + ".bin";
|
|
|
|
File bin_file = SD.open(filePath.c_str(), FILE_READ);
|
|
if (!bin_file) {
|
|
LOG_ERROR("Failed to open file: %s", filePath.c_str());
|
|
return;
|
|
}
|
|
|
|
size_t fileSize = bin_file.size();
|
|
if (fileSize % 2 != 0) {
|
|
LOG_ERROR("Invalid file size: %u (not a multiple of 2)", fileSize);
|
|
bin_file.close();
|
|
return;
|
|
}
|
|
|
|
melody_steps.resize(fileSize / 2);
|
|
|
|
for (size_t i = 0; i < melody_steps.size(); i++) {
|
|
uint8_t high = bin_file.read();
|
|
uint8_t low = bin_file.read();
|
|
melody_steps[i] = (high << 8) | low;
|
|
}
|
|
|
|
LOG_INFO("Melody Load Successful");
|
|
|
|
bin_file.close();
|
|
}
|
|
|
|
};
|