player_queue_090
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
//#include <SPIFFS.h>
|
||||
#include "display.h"
|
||||
#include "player.h"
|
||||
#include "netserver.h"
|
||||
|
||||
Config config;
|
||||
|
||||
@@ -236,6 +237,8 @@ void Config::saveVolume(){
|
||||
|
||||
byte Config::setVolume(byte val) {
|
||||
store.volume = val;
|
||||
display.putRequest(DRAWVOL);
|
||||
netserver.requestOnChange(VOLUME, 0);
|
||||
return store.volume;
|
||||
}
|
||||
|
||||
@@ -280,6 +283,8 @@ void Config::setTitle(const char* title) {
|
||||
memset(config.station.title, 0, BUFLEN);
|
||||
strlcpy(config.station.title, title, BUFLEN);
|
||||
u8fix(config.station.title);
|
||||
netserver.requestOnChange(TITLE, 0);
|
||||
netserver.loop();
|
||||
display.putRequest(NEWTITLE);
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ void encodersLoop(yoEncoder *enc, bool first){
|
||||
int nv = config.store.volume+encoderDelta;
|
||||
if(nv<0) nv=0;
|
||||
if(nv>254) nv=254;
|
||||
player.setVol((byte)nv, false);
|
||||
player.setVol((uint8_t)nv);
|
||||
}else{
|
||||
if(encoderDelta > 0) player.next(); else player.prev();
|
||||
}
|
||||
@@ -199,7 +199,7 @@ void encoder2Loop() {
|
||||
#if IR_PIN!=255
|
||||
void irBlink() {
|
||||
if(LED_BUILTIN==255) return;
|
||||
if (player.mode == STOPPED) {
|
||||
if (player.status() == STOPPED) {
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
|
||||
delay(100);
|
||||
@@ -249,7 +249,7 @@ void irLoop() {
|
||||
irBlink();
|
||||
if (display.mode() == NUMBERS) {
|
||||
display.putRequest(NEWMODE, PLAYER);
|
||||
player.play(display.numOfNextStation);
|
||||
player.sendCommand({PR_PLAY, display.numOfNextStation});
|
||||
display.numOfNextStation = 0;
|
||||
break;
|
||||
}
|
||||
@@ -439,7 +439,7 @@ void controlsEvent(bool toRight, int8_t volDelta) {
|
||||
int nv = config.store.volume+volDelta;
|
||||
if(nv<0) nv=0;
|
||||
if(nv>254) nv=254;
|
||||
player.setVol((byte)nv, false);
|
||||
player.setVol((uint8_t)nv);
|
||||
}else{
|
||||
player.stepVol(toRight);
|
||||
}
|
||||
@@ -472,7 +472,7 @@ void onBtnClick(int id) {
|
||||
}
|
||||
if (display.mode() == STATIONS) {
|
||||
display.putRequest(NEWMODE, PLAYER);
|
||||
player.play(display.currentPlItem);
|
||||
player.sendCommand({PR_PLAY, display.currentPlItem});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -416,7 +416,7 @@ void Display::loop() {
|
||||
#endif*/
|
||||
break;
|
||||
}
|
||||
case DSPRSSI: if(_rssi){ _setRSSI(request.payload); } if (_heapbar && config.store.audioinfo) _heapbar->setValue(player.inBufferFilled()); break;
|
||||
case DSPRSSI: if(_rssi){ _setRSSI(request.payload); } if (_heapbar && config.store.audioinfo) _heapbar->setValue(player.isRunning()?player.inBufferFilled():0); break;
|
||||
case PSTART: _layoutChange(true); break;
|
||||
case PSTOP: _layoutChange(false); break;
|
||||
case DSP_START: _start(); break;
|
||||
|
||||
@@ -39,7 +39,7 @@ void mqttPublishStatus() {
|
||||
memset(topic, 0, 140);
|
||||
memset(status, 0, BUFLEN*3);
|
||||
sprintf(topic, "%s%s", MQTT_ROOT_TOPIC, "status");
|
||||
sprintf(status, "{\"status\": %d, \"station\": %d, \"name\": \"%s\", \"title\": \"%s\", \"on\": %d}", player.mode==PLAYING?1:0, config.store.lastStation, config.station.name, config.station.title, config.store.dspon);
|
||||
sprintf(status, "{\"status\": %d, \"station\": %d, \"name\": \"%s\", \"title\": \"%s\", \"on\": %d}", player.status()==PLAYING?1:0, config.store.lastStation, config.station.name, config.station.title, config.store.dspon);
|
||||
mqttClient.publish(topic, 0, true, status);
|
||||
}
|
||||
}
|
||||
@@ -87,12 +87,12 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties
|
||||
return;
|
||||
}
|
||||
if (strcmp(buf, "stop") == 0) {
|
||||
player.mode = STOPPED;
|
||||
telnet.info();
|
||||
player.sendCommand({PR_STOP, 0});
|
||||
//telnet.info();
|
||||
return;
|
||||
}
|
||||
if (strcmp(buf, "start") == 0 || strcmp(buf, "play") == 0) {
|
||||
player.request.station = config.store.lastStation;
|
||||
player.sendCommand({PR_PLAY, config.store.lastStation});
|
||||
return;
|
||||
}
|
||||
if (strcmp(buf, "boot") == 0 || strcmp(buf, "reboot") == 0) {
|
||||
@@ -110,8 +110,8 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties
|
||||
if (strcmp(buf, "turnoff") == 0) {
|
||||
uint8_t sst = config.store.smartstart;
|
||||
config.setDspOn(0);
|
||||
player.mode = STOPPED;
|
||||
telnet.info();
|
||||
player.sendCommand({PR_STOP, 0});
|
||||
//telnet.info();
|
||||
delay(100);
|
||||
config.store.smartstart = sst;
|
||||
config.save();
|
||||
@@ -119,22 +119,21 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties
|
||||
}
|
||||
if (strcmp(buf, "turnon") == 0) {
|
||||
config.setDspOn(1);
|
||||
if (config.store.smartstart == 1) player.request.station = config.store.lastStation;
|
||||
if (config.store.smartstart == 1) player.sendCommand({PR_PLAY, config.store.lastStation});
|
||||
return;
|
||||
}
|
||||
int volume;
|
||||
if ( sscanf(buf, "vol %d", &volume) == 1) {
|
||||
if (volume < 0) volume = 0;
|
||||
if (volume > 254) volume = 254;
|
||||
player.setVol(volume, false);
|
||||
player.setVol(volume);
|
||||
return;
|
||||
}
|
||||
int sb;
|
||||
if (sscanf(buf, "play %d", &sb) == 1 ) {
|
||||
if (sb < 1) sb = 1;
|
||||
if (sb >= config.store.countStation) sb = config.store.countStation;
|
||||
player.request.station = (uint16_t)sb;
|
||||
player.request.doSave = true;
|
||||
player.sendCommand({PR_PLAY, (uint16_t)sb});
|
||||
return;
|
||||
}
|
||||
if (strstr(buf, "http")==buf){
|
||||
|
||||
@@ -116,7 +116,7 @@ void handleUpdate(AsyncWebServerRequest *request, String filename, size_t index,
|
||||
if (!index) {
|
||||
int target = (request->getParam("updatetarget", true)->value() == "spiffs") ? U_SPIFFS : U_FLASH;
|
||||
Serial.printf("Update Start: %s\n", filename.c_str());
|
||||
player.mode = STOPPED;
|
||||
player.sendCommand({PR_STOP, 0});
|
||||
display.putRequest(NEWMODE, UPDATING);
|
||||
if (!Update.begin(UPDATE_SIZE_UNKNOWN, target)) {
|
||||
Update.printError(Serial);
|
||||
@@ -186,11 +186,15 @@ void NetServer::chunkedHtmlPage(const String& contentType, AsyncWebServerRequest
|
||||
#define SHOW_WEATHER false
|
||||
#endif
|
||||
|
||||
#ifndef NS_QUEUE_TICKS
|
||||
#define NS_QUEUE_TICKS 2
|
||||
#endif
|
||||
|
||||
char wsbuf[BUFLEN * 2];
|
||||
void NetServer::processQueue(){
|
||||
if(nsQueue==NULL) return;
|
||||
nsRequestParams_t request;
|
||||
if(xQueueReceive(nsQueue, &request, 5)){
|
||||
if(xQueueReceive(nsQueue, &request, NS_QUEUE_TICKS)){
|
||||
memset(wsbuf, 0, BUFLEN * 2);
|
||||
uint8_t clientId = request.clientId;
|
||||
switch (request.type) {
|
||||
@@ -239,13 +243,13 @@ void NetServer::processQueue(){
|
||||
case STATIONNAME: sprintf (wsbuf, "{\"nameset\": \"%s\"}", config.station.name); break;
|
||||
case ITEM: sprintf (wsbuf, "{\"current\": %d}", config.store.lastStation); break;
|
||||
case TITLE: sprintf (wsbuf, "{\"meta\": \"%s\"}", config.station.title); if (player.requestToStart) { telnet.info(); player.requestToStart = false; } else { telnet.printf("##CLI.META#: %s\n> ", config.station.title); } break;
|
||||
case VOLUME: sprintf (wsbuf, "{\"vol\": %d}", config.store.volume); break;
|
||||
case VOLUME: sprintf (wsbuf, "{\"vol\": %d}", config.store.volume); telnet.printf("##CLI.VOL#: %d\n", config.store.volume); break;
|
||||
case NRSSI: sprintf (wsbuf, "{\"rssi\": %d}", rssi); /*rssi = 255;*/ break;
|
||||
case SDPOS: sprintf (wsbuf, "{\"sdpos\": %d,\"sdend\": %d,\"sdtpos\": %d,\"sdtend\": %d}", player.getFilePos(), player.getFileSize(), player.getAudioCurrentTime(), player.getAudioFileDuration()); break;
|
||||
case SDLEN: sprintf (wsbuf, "{\"sdmin\": %d,\"sdmax\": %d}", player.sd_min, player.sd_max); break;
|
||||
case SDSNUFFLE: sprintf (wsbuf, "{\"snuffle\": %d}", config.sdSnuffle); break;
|
||||
case BITRATE: sprintf (wsbuf, "{\"bitrate\": %d}", config.station.bitrate); break;
|
||||
case MODE: sprintf (wsbuf, "{\"mode\": \"%s\"}", player.mode == PLAYING ? "playing" : "stopped"); break;
|
||||
case MODE: sprintf (wsbuf, "{\"mode\": \"%s\"}", player.status() == PLAYING ? "playing" : "stopped"); break;
|
||||
case EQUALIZER: sprintf (wsbuf, "{\"bass\": %d, \"middle\": %d, \"trebble\": %d}", config.store.bass, config.store.middle, config.store.trebble); break;
|
||||
case BALANCE: sprintf (wsbuf, "{\"balance\": %d}", config.store.balance); break;
|
||||
default: break;
|
||||
@@ -520,13 +524,14 @@ void NetServer::onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t client
|
||||
} /* EOF RESETS */
|
||||
if (strcmp(cmd, "volume") == 0) {
|
||||
byte v = atoi(val);
|
||||
player.setVol(v, false);
|
||||
player.setVol(v);
|
||||
}
|
||||
if (strcmp(cmd, "sdpos") == 0) {
|
||||
if (config.store.play_mode==PM_SDCARD){
|
||||
config.sdResumePos = 0;
|
||||
if(!player.isRunning()){
|
||||
player.play(config.store.lastStation, atoi(val)-player.sd_min);
|
||||
player.setResumeFilePos(atoi(val)-player.sd_min);
|
||||
player.sendCommand({PR_PLAY, config.store.lastStation});
|
||||
}else{
|
||||
player.setFilePos(atoi(val)-player.sd_min);
|
||||
}
|
||||
@@ -575,8 +580,7 @@ void NetServer::onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t client
|
||||
#endif
|
||||
// xSemaphoreGive(player.playmutex);
|
||||
if (player.isRunning()) {
|
||||
player.request.station = config.store.lastStation;
|
||||
player.request.doSave = false;
|
||||
player.sendCommand({PR_PLAY, -config.store.lastStation});
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -653,7 +657,6 @@ bool NetServer::importPlaylist() {
|
||||
}
|
||||
|
||||
void NetServer::requestOnChange(requestType_e request, uint8_t clientId) {
|
||||
//char buf[BUFLEN * 2] = { 0 };
|
||||
nsRequestParams_t nsrequest;
|
||||
nsrequest.type = request;
|
||||
nsrequest.clientId = clientId;
|
||||
@@ -744,8 +747,8 @@ void handleHTTPArgs(AsyncWebServerRequest * request) {
|
||||
}
|
||||
if (network.status == CONNECTED) {
|
||||
bool commandFound=false;
|
||||
if (request->hasArg("start")) { player.request.station = config.store.lastStation; commandFound=true; }
|
||||
if (request->hasArg("stop")) { player.mode = STOPPED; config.setTitle(const_PlStopped); commandFound=true; }
|
||||
if (request->hasArg("start")) { player.sendCommand({PR_PLAY, config.store.lastStation}); commandFound=true; }
|
||||
if (request->hasArg("stop")) { player.sendCommand({PR_STOP, 0}); commandFound=true; }
|
||||
if (request->hasArg("toggle")) { player.toggle(); commandFound=true; }
|
||||
if (request->hasArg("prev")) { player.prev(); commandFound=true; }
|
||||
if (request->hasArg("next")) { player.next(); commandFound=true; }
|
||||
@@ -777,8 +780,7 @@ void handleHTTPArgs(AsyncWebServerRequest * request) {
|
||||
int id = atoi(p->value().c_str());
|
||||
if (id < 1) id = 1;
|
||||
if (id > config.store.countStation) id = config.store.countStation;
|
||||
player.request.station = id;
|
||||
player.request.doSave = true;
|
||||
player.sendCommand({PR_PLAY, id});
|
||||
commandFound=true;
|
||||
DBGVB("[%s] play=%d", __func__, id);
|
||||
}
|
||||
@@ -788,7 +790,7 @@ void handleHTTPArgs(AsyncWebServerRequest * request) {
|
||||
if (v < 0) v = 0;
|
||||
if (v > 254) v = 254;
|
||||
config.store.volume = v;
|
||||
player.setVol(v, false);
|
||||
player.setVol(v);
|
||||
commandFound=true;
|
||||
DBGVB("[%s] vol=%d", __func__, v);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef options_h
|
||||
#define options_h
|
||||
|
||||
#define YOVERSION "0.9.084"
|
||||
#define YOVERSION "0.9.090"
|
||||
|
||||
/*******************************************************
|
||||
DO NOT EDIT THIS FILE.
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "netserver.h"
|
||||
|
||||
Player player;
|
||||
QueueHandle_t playerQueue;
|
||||
|
||||
#if VS1053_CS!=255 && !I2S_INTERNAL
|
||||
#if VS_HSPI
|
||||
@@ -34,6 +35,8 @@ Player player;
|
||||
|
||||
void Player::init() {
|
||||
Serial.print("##[BOOT]#\tplayer.init\t");
|
||||
playerQueue=NULL;
|
||||
playerQueue = xQueueCreate( 5, sizeof( playerRequestParams_t ) );
|
||||
#ifdef MQTT_ROOT_TOPIC
|
||||
memset(burl, 0, MQTT_BURL_SIZE);
|
||||
#endif
|
||||
@@ -50,30 +53,36 @@ void Player::init() {
|
||||
setBalance(config.store.balance);
|
||||
setTone(config.store.bass, config.store.middle, config.store.trebble);
|
||||
setVolume(0);
|
||||
mode = STOPPED;
|
||||
_status = STOPPED;
|
||||
setOutputPins(false);
|
||||
requestToStart = true;
|
||||
volTimer=false;
|
||||
zeroRequest();
|
||||
_volTimer=false;
|
||||
playmutex = xSemaphoreCreateMutex();
|
||||
randomSeed(analogRead(0));
|
||||
#if PLAYER_FORCE_MONO
|
||||
forceMono(true);
|
||||
#endif
|
||||
_loadVol(config.store.volume);
|
||||
Serial.println("done");
|
||||
}
|
||||
|
||||
void Player::sendCommand(playerRequestParams_t request){
|
||||
if(playerQueue==NULL) return;
|
||||
xQueueSend(playerQueue, &request, portMAX_DELAY);
|
||||
}
|
||||
|
||||
void Player::stopInfo() {
|
||||
config.setSmartStart(0);
|
||||
telnet.info();
|
||||
//telnet.info();
|
||||
netserver.requestOnChange(MODE, 0);
|
||||
requestToStart = true;
|
||||
}
|
||||
|
||||
void Player::stop(const char *nttl){
|
||||
void Player::_stop(){
|
||||
if(config.store.play_mode==PM_SDCARD) config.sdResumePos = player.getFilePos();
|
||||
mode = STOPPED;
|
||||
_status = STOPPED;
|
||||
setOutputPins(false);
|
||||
if(nttl) config.setTitle(nttl);
|
||||
else config.setTitle((display.mode()==LOST || display.mode()==UPDATING)?"":const_PlStopped);
|
||||
netserver.requestOnChange(TITLE, 0);
|
||||
config.setTitle((display.mode()==LOST || display.mode()==UPDATING)?"":const_PlStopped);
|
||||
config.station.bitrate = 0;
|
||||
#ifdef USE_NEXTION
|
||||
nextion.bitrate(config.station.bitrate);
|
||||
@@ -81,7 +90,9 @@ void Player::stop(const char *nttl){
|
||||
netserver.requestOnChange(BITRATE, 0);
|
||||
display.putRequest(DBITRATE);
|
||||
display.putRequest(PSTOP);
|
||||
//setDefaults();
|
||||
#ifdef CLEAR_BUFFERS
|
||||
setDefaults();
|
||||
#endif
|
||||
stopSong();
|
||||
stopInfo();
|
||||
if (player_on_stop_play) player_on_stop_play();
|
||||
@@ -91,40 +102,45 @@ void Player::initHeaders(const char *file) {
|
||||
if(strlen(file)==0) return;
|
||||
connecttoFS(SD,file);
|
||||
eofHeader = false;
|
||||
//for(int c=0;c<20;c++) player.loopreader();
|
||||
while(!eofHeader) Audio::loop();
|
||||
//netserver.requestOnChange(SDPOS, 0);
|
||||
setDefaults();
|
||||
}
|
||||
|
||||
#ifndef PL_QUEUE_TICKS
|
||||
#define PL_QUEUE_TICKS 2
|
||||
#endif
|
||||
|
||||
void Player::loop() {
|
||||
if (mode == PLAYING) {
|
||||
xSemaphoreTake(playmutex, portMAX_DELAY);
|
||||
Audio::loop();
|
||||
xSemaphoreGive(playmutex);
|
||||
} else {
|
||||
if (isRunning()) stop();
|
||||
}
|
||||
if (request.station > 0) {
|
||||
if (request.doSave) {
|
||||
config.setLastStation(request.station);
|
||||
if(playerQueue==NULL) return;
|
||||
playerRequestParams_t requestP;
|
||||
if(xQueueReceive(playerQueue, &requestP, PL_QUEUE_TICKS)){
|
||||
switch (requestP.type){
|
||||
case PR_STOP: _stop(); break;
|
||||
case PR_PLAY: {
|
||||
if (requestP.payload>0) {
|
||||
config.setLastStation((uint16_t)requestP.payload);
|
||||
}
|
||||
_play((uint16_t)abs(requestP.payload));
|
||||
if (player_on_station_change) player_on_station_change();
|
||||
break;
|
||||
}
|
||||
case PR_VOL: {
|
||||
config.setVolume(requestP.payload);
|
||||
Audio::setVolume(volToI2S(requestP.payload));
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
play(request.station);
|
||||
if (player_on_station_change) player_on_station_change();
|
||||
zeroRequest();
|
||||
}
|
||||
if (request.volume >= 0) {
|
||||
config.setVolume(request.volume);
|
||||
telnet.printf("##CLI.VOL#: %d\n", config.store.volume);
|
||||
Audio::setVolume(volToI2S(request.volume));
|
||||
zeroRequest();
|
||||
display.putRequest(DRAWVOL);
|
||||
netserver.requestOnChange(VOLUME, 0);
|
||||
}
|
||||
if(volTimer){
|
||||
if((millis()-volTicks)>3000){
|
||||
xSemaphoreTake(playmutex, portMAX_DELAY);
|
||||
Audio::loop();
|
||||
xSemaphoreGive(playmutex);
|
||||
|
||||
if(_volTimer){
|
||||
if((millis()-_volTicks)>3000){
|
||||
config.saveVolume();
|
||||
volTimer=false;
|
||||
_volTimer=false;
|
||||
}
|
||||
}
|
||||
#ifdef MQTT_ROOT_TOPIC
|
||||
@@ -134,36 +150,26 @@ void Player::loop() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void Player::zeroRequest() {
|
||||
request.station = 0;
|
||||
request.volume = -1;
|
||||
request.doSave = false;
|
||||
}
|
||||
|
||||
void Player::setOutputPins(bool isPlaying) {
|
||||
if(LED_BUILTIN!=255) digitalWrite(LED_BUILTIN, LED_INVERT?!isPlaying:isPlaying);
|
||||
if(MUTE_PIN!=255) digitalWrite(MUTE_PIN, isPlaying?!MUTE_VAL:MUTE_VAL);
|
||||
}
|
||||
|
||||
void Player::play(uint16_t stationId, uint32_t filePos) {
|
||||
void Player::_play(uint16_t stationId) {
|
||||
remoteStationName = false;
|
||||
config.setDspOn(1);
|
||||
display.putRequest(PSTOP);
|
||||
setDefaults();
|
||||
setOutputPins(false);
|
||||
config.setTitle(config.store.play_mode==PM_WEB?const_PlConnect:"");
|
||||
config.station.bitrate=0;
|
||||
netserver.requestOnChange(TITLE, 0);
|
||||
config.loadStation(stationId);
|
||||
setVol(config.store.volume, true);
|
||||
_loadVol(config.store.volume);
|
||||
display.putRequest(NEWSTATION);
|
||||
netserver.requestOnChange(STATION, 0);
|
||||
telnet.printf("##CLI.NAMESET#: %d %s\n", config.store.lastStation, config.station.name);
|
||||
if (config.store.play_mode==PM_WEB?connecttohost(config.station.url):connecttoFS(SD,config.station.url,config.sdResumePos==0?filePos:config.sdResumePos-player.sd_min)) {
|
||||
mode = PLAYING;
|
||||
if (config.store.play_mode==PM_WEB?connecttohost(config.station.url):connecttoFS(SD,config.station.url,config.sdResumePos==0?_resumeFilePos:config.sdResumePos-player.sd_min)) {
|
||||
_status = PLAYING;
|
||||
if(config.store.play_mode==PM_SDCARD) config.sdResumePos = 0;
|
||||
config.setTitle("");
|
||||
netserver.requestOnChange(TITLE, 0);
|
||||
config.setSmartStart(1);
|
||||
netserver.requestOnChange(MODE, 0);
|
||||
setOutputPins(true);
|
||||
@@ -179,16 +185,14 @@ void Player::play(uint16_t stationId, uint32_t filePos) {
|
||||
void Player::browseUrl(){
|
||||
remoteStationName = true;
|
||||
config.setDspOn(1);
|
||||
resumeAfterUrl = mode==PLAYING;
|
||||
resumeAfterUrl = _status==PLAYING;
|
||||
display.putRequest(PSTOP);
|
||||
// setDefaults();
|
||||
setOutputPins(false);
|
||||
config.setTitle(const_PlConnect);
|
||||
netserver.requestOnChange(TITLE, 0);
|
||||
if (connecttohost(burl)){
|
||||
mode = PLAYING;
|
||||
_status = PLAYING;
|
||||
config.setTitle("");
|
||||
netserver.requestOnChange(TITLE, 0);
|
||||
netserver.requestOnChange(MODE, 0);
|
||||
setOutputPins(true);
|
||||
requestToStart = true;
|
||||
@@ -205,8 +209,7 @@ void Player::prev() {
|
||||
if(config.store.play_mode==PM_WEB || !config.sdSnuffle){
|
||||
if (config.store.lastStation == 1) config.store.lastStation = config.store.countStation; else config.store.lastStation--;
|
||||
}
|
||||
request.station = config.store.lastStation;
|
||||
request.doSave = true;
|
||||
sendCommand({PR_PLAY, config.store.lastStation});
|
||||
}
|
||||
|
||||
void Player::next() {
|
||||
@@ -215,48 +218,46 @@ void Player::next() {
|
||||
}else{
|
||||
config.store.lastStation = random(1, config.store.countStation);
|
||||
}
|
||||
request.station = config.store.lastStation;
|
||||
request.doSave = true;
|
||||
sendCommand({PR_PLAY, config.store.lastStation});
|
||||
}
|
||||
|
||||
void Player::toggle() {
|
||||
if (mode == PLAYING) {
|
||||
mode = STOPPED;
|
||||
if (_status == PLAYING) {
|
||||
sendCommand({PR_STOP, 0});
|
||||
} else {
|
||||
request.station = config.store.lastStation;
|
||||
sendCommand({PR_PLAY, config.store.lastStation});
|
||||
}
|
||||
}
|
||||
|
||||
void Player::stepVol(bool up) {
|
||||
if (up) {
|
||||
if (config.store.volume <= 254 - config.store.volsteps) {
|
||||
setVol(config.store.volume + config.store.volsteps, false);
|
||||
setVol(config.store.volume + config.store.volsteps);
|
||||
}else{
|
||||
setVol(254, false);
|
||||
setVol(254);
|
||||
}
|
||||
} else {
|
||||
if (config.store.volume >= config.store.volsteps) {
|
||||
setVol(config.store.volume - config.store.volsteps, false);
|
||||
setVol(config.store.volume - config.store.volsteps);
|
||||
}else{
|
||||
setVol(0, false);
|
||||
setVol(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte Player::volToI2S(byte volume) {
|
||||
uint8_t Player::volToI2S(uint8_t volume) {
|
||||
int vol = map(volume, 0, 254 - config.station.ovol * 3 , 0, 254);
|
||||
if (vol > 254) vol = 254;
|
||||
if (vol < 0) vol = 0;
|
||||
return vol;
|
||||
}
|
||||
|
||||
void Player::setVol(byte volume, bool inside) {
|
||||
if (inside) {
|
||||
setVolume(volToI2S(volume));
|
||||
} else {
|
||||
volTicks = millis();
|
||||
volTimer = true;
|
||||
request.volume = volume;
|
||||
request.doSave = true;
|
||||
}
|
||||
void Player::_loadVol(uint8_t volume) {
|
||||
setVolume(volToI2S(volume));
|
||||
}
|
||||
|
||||
void Player::setVol(uint8_t volume) {
|
||||
_volTicks = millis();
|
||||
_volTimer = true;
|
||||
player.sendCommand({PR_VOL, volume});
|
||||
}
|
||||
|
||||
@@ -12,23 +12,27 @@
|
||||
#define MQTT_BURL_SIZE 512
|
||||
#endif
|
||||
|
||||
enum audioMode_e { PLAYING, STOPPED };
|
||||
|
||||
struct audiorequest_t
|
||||
enum playerRequestType_e : uint8_t { PR_PLAY = 1, PR_STOP = 2, PR_PREV = 3, PR_NEXT = 4, PR_VOL = 5 };
|
||||
struct playerRequestParams_t
|
||||
{
|
||||
uint16_t station;
|
||||
int volume;
|
||||
bool doSave;
|
||||
playerRequestType_e type;
|
||||
int payload;
|
||||
};
|
||||
|
||||
enum plStatus_e : uint8_t{ PLAYING = 1, STOPPED = 2 };
|
||||
|
||||
class Player: public Audio {
|
||||
private:
|
||||
uint32_t volTicks; /* delayed volume save */
|
||||
bool volTimer; /* delayed volume save */
|
||||
uint32_t _volTicks; /* delayed volume save */
|
||||
bool _volTimer; /* delayed volume save */
|
||||
uint32_t _resumeFilePos;
|
||||
plStatus_e _status;
|
||||
private:
|
||||
void _stop();
|
||||
void _play(uint16_t stationId);
|
||||
void _loadVol(uint8_t volume);
|
||||
public:
|
||||
audioMode_e mode;
|
||||
audiorequest_t request;
|
||||
bool requestToStart;
|
||||
void zeroRequest();
|
||||
SemaphoreHandle_t playmutex=NULL;
|
||||
bool lockOutput = true;
|
||||
bool resumeAfterUrl = false;
|
||||
@@ -41,20 +45,21 @@ class Player: public Audio {
|
||||
void init();
|
||||
void loop();
|
||||
void initHeaders(const char *file);
|
||||
void play(uint16_t stationId, uint32_t filePos=0);
|
||||
void sendCommand(playerRequestParams_t request);
|
||||
#ifdef MQTT_ROOT_TOPIC
|
||||
void browseUrl();
|
||||
#endif
|
||||
bool remoteStationName = false;
|
||||
void stop(const char *nttl = NULL);
|
||||
plStatus_e status() { return _status; }
|
||||
void prev();
|
||||
void next();
|
||||
void toggle();
|
||||
void stepVol(bool up);
|
||||
void setVol(byte volume, bool inside);
|
||||
byte volToI2S(byte volume);
|
||||
void setVol(uint8_t volume);
|
||||
uint8_t volToI2S(uint8_t volume);
|
||||
void stopInfo();
|
||||
void setOutputPins(bool isPlaying);
|
||||
void setResumeFilePos(uint32_t pos) { _resumeFilePos = pos; }
|
||||
};
|
||||
|
||||
extern Player player;
|
||||
|
||||
@@ -124,7 +124,7 @@ void Telnet::printf(const char *format, ...) {
|
||||
clients[id].print(buf);
|
||||
}
|
||||
}
|
||||
Serial.print(buf);
|
||||
if(strstr(buf,"> ")==NULL) Serial.print(buf);
|
||||
}
|
||||
|
||||
void Telnet::printf(byte id, const char *format, ...) {
|
||||
@@ -153,11 +153,11 @@ void Telnet::info() {
|
||||
strftime(timeStringBuff, sizeof(timeStringBuff), "%Y-%m-%dT%H:%M:%S+03:00", &network.timeinfo);
|
||||
telnet.printf("##SYS.DATE#: %s\n", timeStringBuff); //TODO timezone offset
|
||||
telnet.printf("##CLI.NAMESET#: %d %s\n", config.store.lastStation, config.station.name);
|
||||
if (player.mode == PLAYING) {
|
||||
if (player.status() == PLAYING) {
|
||||
telnet.printf("##CLI.META#: %s\n", config.station.title);
|
||||
}
|
||||
telnet.printf("##CLI.VOL#: %d\n", config.store.volume);
|
||||
if (player.mode == PLAYING) {
|
||||
if (player.status() == PLAYING) {
|
||||
telnet.printf("##CLI.PLAYING#\n");
|
||||
} else {
|
||||
telnet.printf("##CLI.STOPPED#\n");
|
||||
@@ -181,12 +181,12 @@ void Telnet::on_input(const char* str, byte clientId) {
|
||||
return;
|
||||
}
|
||||
if (strcmp(str, "cli.stop") == 0 || strcmp(str, "stop") == 0) {
|
||||
player.mode = STOPPED;
|
||||
info();
|
||||
player.sendCommand({PR_STOP, 0});
|
||||
//info();
|
||||
return;
|
||||
}
|
||||
if (strcmp(str, "cli.start") == 0 || strcmp(str, "start") == 0 || strcmp(str, "cli.play") == 0 || strcmp(str, "play") == 0) {
|
||||
player.play(config.store.lastStation);
|
||||
player.sendCommand({PR_PLAY, config.store.lastStation});
|
||||
return;
|
||||
}
|
||||
if (strcmp(str, "cli.vol") == 0 || strcmp(str, "vol") == 0) {
|
||||
@@ -209,7 +209,7 @@ void Telnet::on_input(const char* str, byte clientId) {
|
||||
if (sscanf(str, "vol(%d)", &volume) == 1 || sscanf(str, "cli.vol(\"%d\")", &volume) == 1 || sscanf(str, "vol %d", &volume) == 1) {
|
||||
if (volume < 0) volume = 0;
|
||||
if (volume > 254) volume = 254;
|
||||
player.setVol(volume, false);
|
||||
player.setVol(volume);
|
||||
return;
|
||||
}
|
||||
if (strcmp(str, "cli.audioinfo") == 0 || strcmp(str, "audioinfo") == 0) {
|
||||
@@ -263,11 +263,11 @@ void Telnet::on_input(const char* str, byte clientId) {
|
||||
printf(clientId, "##SYS.DATE#: %s+%02d:%02d\n", timeStringBuff, config.store.tzHour, config.store.tzMin);
|
||||
}
|
||||
printf(clientId, "##CLI.NAMESET#: %d %s\n", config.store.lastStation, config.station.name);
|
||||
if (player.mode == PLAYING) {
|
||||
if (player.status() == PLAYING) {
|
||||
printf(clientId, "##CLI.META#: %s\n", config.station.title);
|
||||
}
|
||||
printf(clientId, "##CLI.VOL#: %d\n", config.store.volume);
|
||||
if (player.mode == PLAYING) {
|
||||
if (player.status() == PLAYING) {
|
||||
printf(clientId, "##CLI.PLAYING#\n");
|
||||
} else {
|
||||
printf(clientId, "##CLI.STOPPED#\n");
|
||||
@@ -279,7 +279,7 @@ void Telnet::on_input(const char* str, byte clientId) {
|
||||
if (sscanf(str, "play(%d)", &sb) == 1 || sscanf(str, "cli.play(\"%d\")", &sb) == 1 || sscanf(str, "play %d", &sb) == 1 ) {
|
||||
if (sb < 1) sb = 1;
|
||||
if (sb >= config.store.countStation) sb = config.store.countStation;
|
||||
player.play((uint16_t)sb);
|
||||
player.sendCommand({PR_PLAY, (uint16_t)sb});
|
||||
return;
|
||||
}
|
||||
if (strcmp(str, "sys.tzo") == 0 || strcmp(str, "tzo") == 0) {
|
||||
|
||||
@@ -222,7 +222,7 @@ void Nextion::loop() {
|
||||
}
|
||||
if(strcmp(scanBuf, "go") == 0) {
|
||||
display.putRequest(NEWMODE, PLAYER);
|
||||
player.request.station=display.currentPlItem;
|
||||
player.sendCommand({PR_PLAY, display.currentPlItem});
|
||||
}
|
||||
if(strcmp(scanBuf, "toggle") == 0) {
|
||||
player.toggle();
|
||||
@@ -230,8 +230,7 @@ void Nextion::loop() {
|
||||
}
|
||||
if (sscanf(rxbuf, "vol=%d", &scanDigit) == 1){
|
||||
_volInside = true;
|
||||
player.request.volume=scanDigit;
|
||||
player.request.doSave=true;
|
||||
player.sendCommand({PR_VOL, scanDigit});
|
||||
}
|
||||
if (sscanf(rxbuf, "balance=%d", &scanDigit) == 1){
|
||||
config.setBalance((int8_t)scanDigit);
|
||||
|
||||
@@ -45,10 +45,6 @@ void setup() {
|
||||
}
|
||||
netserver.begin();
|
||||
telnet.begin();
|
||||
#if PLAYER_FORCE_MONO
|
||||
player.forceMono(true);
|
||||
#endif
|
||||
player.setVol(config.store.volume, true);
|
||||
initControls();
|
||||
display.putRequest(DSP_START);
|
||||
while(!display.ready()) delay(10);
|
||||
@@ -57,7 +53,7 @@ void setup() {
|
||||
#endif
|
||||
if (config.store.play_mode==PM_SDCARD) player.initHeaders(config.station.url);
|
||||
player.lockOutput=false;
|
||||
if (config.store.smartstart == 1) player.play(config.store.lastStation);
|
||||
if (config.store.smartstart == 1) player.sendCommand({PR_PLAY, config.store.lastStation});
|
||||
}
|
||||
|
||||
void loop() {
|
||||
@@ -75,7 +71,7 @@ void checkConnection(){
|
||||
static uint32_t checkInterval = 3000;
|
||||
if ((WiFi.status() != WL_CONNECTED) && (millis() - checkMillis >=checkInterval)) {
|
||||
bool playing = player.isRunning();
|
||||
if (playing) player.mode = STOPPED;
|
||||
if (playing) player.sendCommand({PR_STOP, 0});
|
||||
display.putRequest(NEWMODE, LOST);
|
||||
Serial.println("Lost connection, reconnecting...");
|
||||
while(true){
|
||||
@@ -85,7 +81,7 @@ void checkConnection(){
|
||||
delay(3000);
|
||||
}
|
||||
display.putRequest(NEWMODE, PLAYER);
|
||||
if (playing) player.request.station = config.store.lastStation;
|
||||
if (playing) player.sendCommand({PR_PLAY, config.store.lastStation});
|
||||
checkMillis = millis();
|
||||
#ifdef MQTT_ROOT_TOPIC
|
||||
connectToMqtt();
|
||||
@@ -103,12 +99,12 @@ void audio_info(const char *info) {
|
||||
#ifdef USE_NEXTION
|
||||
nextion.audioinfo(info);
|
||||
#endif
|
||||
if (strstr(info, "skip metadata") != NULL){
|
||||
config.setTitle(config.station.name);
|
||||
netserver.requestOnChange(TITLE, 0);
|
||||
if (strstr(info, "skip metadata") != NULL) config.setTitle(config.station.name);
|
||||
if (strstr(info, "failed!") != NULL || strstr(info, "address is empty") != NULL || strstr(info, "not supported") != NULL || strstr(info, "Account already in use") != NULL || strstr(info, "HTTP/1.0 401") != NULL) {
|
||||
//config.setTitle(info);
|
||||
telnet.printf("##ERROR#:\t%s\n", info);
|
||||
player.sendCommand({PR_STOP, 0});
|
||||
}
|
||||
if (strstr(info, "failed!") != NULL || strstr(info, "address is empty") != NULL) player.stop(info);
|
||||
if (strstr(info, "not supported") != NULL || strstr(info, "Account already in use") != NULL || strstr(info, "HTTP/1.0 401") != NULL) player.stop(info);
|
||||
char* ici; char b[20]={0};
|
||||
if ((ici = strstr(info, "BitRate: ")) != NULL) {
|
||||
strlcpy(b, ici + 9, 50);
|
||||
@@ -141,7 +137,6 @@ void audio_showstation(const char *info) {
|
||||
if (strlen(info) > 0) {
|
||||
bool p = printable(info);
|
||||
config.setTitle(p?info:config.station.name);
|
||||
netserver.requestOnChange(TITLE, 0);
|
||||
if(player.remoteStationName){
|
||||
config.setStation(p?info:config.station.name);
|
||||
display.putRequest(NEWSTATION);
|
||||
@@ -153,7 +148,9 @@ void audio_showstation(const char *info) {
|
||||
void audio_showstreamtitle(const char *info) {
|
||||
DBGH();
|
||||
if (strstr(info, "Account already in use") != NULL || strstr(info, "HTTP/1.0 401") != NULL){
|
||||
player.stop(info);
|
||||
//config.setTitle(info);
|
||||
telnet.printf("##ERROR#:\t%s\n", info);
|
||||
player.sendCommand({PR_STOP, 0});
|
||||
return;
|
||||
}
|
||||
if (strlen(info) > 0) {
|
||||
@@ -163,7 +160,6 @@ void audio_showstreamtitle(const char *info) {
|
||||
#else
|
||||
config.setTitle(p?info:config.station.name);
|
||||
#endif
|
||||
netserver.requestOnChange(TITLE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +182,6 @@ void audio_id3album(const char *info){
|
||||
strlcat(out, info, BUFLEN);
|
||||
config.setTitle(out);
|
||||
}
|
||||
netserver.requestOnChange(TITLE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +191,6 @@ void audio_id3title(const char *info){
|
||||
|
||||
void audio_beginSDread(){
|
||||
config.setTitle("");
|
||||
netserver.requestOnChange(TITLE, 0);
|
||||
}
|
||||
|
||||
void audio_id3data(const char *info){ //id3 metadata
|
||||
@@ -207,19 +201,20 @@ void audio_id3data(const char *info){ //id3 metadata
|
||||
void audio_eof_mp3(const char *info){ //end of file
|
||||
config.sdResumePos = 0;
|
||||
if(config.sdSnuffle){
|
||||
player.play(random(1, config.store.countStation));
|
||||
player.sendCommand({PR_PLAY, random(1, config.store.countStation)});
|
||||
}else{
|
||||
player.next();
|
||||
}
|
||||
}
|
||||
|
||||
void audio_eof_stream(const char *info){
|
||||
player.stop();
|
||||
player.sendCommand({PR_STOP, 0});
|
||||
if(!player.resumeAfterUrl) return;
|
||||
if (config.store.play_mode==PM_WEB){
|
||||
player.play(config.store.lastStation);
|
||||
player.sendCommand({PR_PLAY, config.store.lastStation});
|
||||
}else{
|
||||
player.play(config.store.lastStation, config.sdResumePos==0?0:config.sdResumePos-player.sd_min);
|
||||
player.setResumeFilePos( config.sdResumePos==0?0:config.sdResumePos-player.sd_min);
|
||||
player.sendCommand({PR_PLAY, config.store.lastStation});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user