瀏覽代碼

Console implemented, DAC stabilized, BT stabilized

Sebastien Leclerc 5 年之前
父節點
當前提交
e5921154f1

+ 11 - 2
components/cmd_nvs/cmd_nvs.c

@@ -7,7 +7,10 @@
    CONDITIONS OF ANY KIND, either express or implied.
 */
 
-
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "nvs_flash.h"
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
@@ -22,6 +25,7 @@
 #include "cmd_nvs.h"
 #include "nvs.h"
 
+
 typedef struct {
     nvs_type_t type;
     const char *str;
@@ -297,7 +301,7 @@ static esp_err_t get_value_from_nvs(const char *key, const char *str_type)
             printf("Value associated with key '%s' is %llu \n", key, value);
         }
     } else if (type == NVS_TYPE_STR) {
-        size_t len;
+        size_t len=0;
         if ( (err = nvs_get_str(nvs, key, NULL, &len)) == ESP_OK) {
             char *str = (char *)malloc(len);
             if ( (err = nvs_get_str(nvs, key, str, &len)) == ESP_OK) {
@@ -456,6 +460,7 @@ static int set_namespace(int argc, char **argv)
     ESP_LOGI(TAG, "Namespace set to '%s'", current_namespace);
     return 0;
 }
+
 #ifdef ESP_IDF_COMMIT_bde1c30 // this commit added support for listing nvs entries
 
 static int list(const char *part, const char *name, const char *str_type)
@@ -563,6 +568,7 @@ void register_nvs()
         .func = &set_namespace,
         .argtable = &namespace_args
     };
+
 #ifdef ESP_IDF_COMMIT_bde1c30 // this commit added support for listing nvs entries
     const esp_console_cmd_t list_entries_cmd = {
            .command = "nvs_list",
@@ -582,3 +588,6 @@ void register_nvs()
     ESP_ERROR_CHECK(esp_console_cmd_register(&namespace_cmd));
     ESP_ERROR_CHECK(esp_console_cmd_register(&erase_namespace_cmd));
 }
+#ifdef __cplusplus
+extern }
+#endif

+ 1 - 1
components/platform_esp32/bt_app_core.c

@@ -105,7 +105,7 @@ void bt_app_task_start_up(void)
 
     s_bt_app_task_queue = xQueueCreate(10, sizeof(bt_app_msg_t));
     assert(s_bt_app_task_queue!=NULL);
-    assert(xTaskCreate(bt_app_task_handler, "BtAppT", 2048, NULL, configMAX_PRIORITIES - 3, &s_bt_app_task_handle)==pdPASS);
+    assert(xTaskCreate(bt_app_task_handler, "BtAppT", 4096, NULL, configMAX_PRIORITIES - 3, &s_bt_app_task_handle)==pdPASS);
     return;
 }
 

+ 14 - 13
components/platform_esp32/console.c

@@ -110,28 +110,29 @@ void run_command(char * line);
 //	ESP_ERROR_CHECK( esp_console_cmd_register(&config_list) );
 //
 //}
+
 void process_autoexec(){
 	int i=1;
 	char autoexec_name[21]={0};
 	char * autoexec_value=NULL;
-	int * autoexec_flag = get_nvs_value_alloc(NVS_TYPE_U8, "autoexec");
-	if(autoexec_flag!=NULL)
-	{
-		ESP_LOGI(TAG,"autoexec flag value found with value %d", *autoexec_flag);
-		printf("printf -- autoexec flag value found with value %d", *autoexec_flag);
-		if(*autoexec_flag == 1)
-		{
+	uint8_t * autoexec_flag=NULL;
+
+	autoexec_flag = get_nvs_value_alloc(NVS_TYPE_U8, "autoexec");
+
+	if(autoexec_flag!=NULL ){
+		ESP_LOGI(TAG,"autoexec flag value found with value %u", *autoexec_flag);
+		if(*autoexec_flag == 1) {
 			do {
 				snprintf(autoexec_name,sizeof(autoexec_name)-1,"autoexec%u",i++);
 				ESP_LOGD(TAG,"Getting command name %s", autoexec_name);
 				autoexec_value= get_nvs_value_alloc(NVS_TYPE_STR, autoexec_name);
-				if(autoexec_value!=NULL){
+				if(autoexec_value!=NULL ){
 					ESP_LOGI(TAG,"Running command %s = %s", autoexec_name, autoexec_value);
 					run_command(autoexec_value);
+					ESP_LOGD(TAG,"Freeing memory for command %s name", autoexec_name);
 					free(autoexec_value);
 				}
-				else
-				{
+				else {
 					ESP_LOGD(TAG,"No matching command found for name %s", autoexec_name);
 					break;
 				}
@@ -143,11 +144,11 @@ void process_autoexec(){
 	{
 		ESP_LOGD(TAG,"No matching command found for name autoexec. Adding default entries");
 		uint8_t autoexec_dft=0;
-		char autoexec1_dft[]="join " CONFIG_WIFI_SSID CONFIG_WIFI_PASSWORD;
+		char autoexec1_dft[]="join MySSID MyPASSWORD";
 		char autoexec2_dft[]="squeezelite -o \"DAC\" -b 500:2000 -d all=debug -M esp32 -r \"44100,4800\" -N \"playername.txt\"";
 		store_nvs_value(NVS_TYPE_U8,"autoexec",&autoexec_dft);
-		store_nvs_value(NVS_TYPE_U8,"autoexec1",autoexec1_dft);
-		store_nvs_value(NVS_TYPE_U8,"autoexec2",autoexec2_dft);
+		store_nvs_value(NVS_TYPE_STR,"autoexec1",autoexec1_dft);
+		store_nvs_value(NVS_TYPE_STR,"autoexec2",autoexec2_dft);
 	}
 }
 static void initialize_filesystem() {

+ 45 - 11
components/platform_esp32/nvs_utilities.c

@@ -16,7 +16,40 @@
 
 extern char current_namespace[];
 static const char * TAG = "platform_esp32";
+bool isNameValid(char * key){
+	bool bFound=false;
+	nvs_handle nvs;
+	esp_err_t err;
+	int8_t val=0;
 
+	err = nvs_open(current_namespace, NVS_READONLY, &nvs);
+	if (err != ESP_OK) {
+		ESP_LOGE(TAG,"Error opening nvs storage for namespace %s",current_namespace);
+		return false;
+	}
+	err = nvs_get_i8(nvs, key,  &val);
+	if(err==ESP_OK || err== ESP_ERR_NVS_INVALID_LENGTH){
+		bFound=true;
+	}
+	else {
+		ESP_LOGD(TAG,"Search for key %s in namespace %s returned %#08X",key,current_namespace,err);
+	}
+//	 nvs_iterator_t it = nvs_entry_find(NVS_DEFAULT_PART_NAME, current_namespace, NVS_TYPE_ANY);
+//	  while (it != NULL) {
+//	          nvs_entry_info_t info;
+//	          nvs_entry_info(it, &info);
+//	          it = nvs_entry_next(it);
+//	          if(!strcmp(info.key,key)){
+//	        	  bFound=true;
+//	          }
+//	          printf("key '%s', type '%d' \n", info.key, info.type);
+//	  };
+//	  // Note: no need to release iterator obtained from nvs_entry_find function when
+//	  //       nvs_entry_find or nvs_entry_next function return NULL, indicating no other
+//	  //       element for specified criteria was found.
+	nvs_close(nvs);
+	  return bFound;
+}
 esp_err_t store_nvs_value(nvs_type_t type, const char *key, void * data) {
 	if (type == NVS_TYPE_BLOB)
 		return ESP_ERR_NVS_TYPE_MISMATCH;
@@ -73,25 +106,22 @@ void * get_nvs_value_alloc(nvs_type_t type, const char *key) {
 
 	err = nvs_open(current_namespace, NVS_READONLY, &nvs);
 	if (err != ESP_OK) {
-		return value;
+		ESP_LOGE(TAG,"Could not open the nvs storage.");
+		return NULL;
 	}
 
 	if (type == NVS_TYPE_I8) {
 		value=malloc(sizeof(int8_t));
 		err = nvs_get_i8(nvs, key, (int8_t *) value);
-		printf("value found = %d\n",*(int8_t *)value);
 	} else if (type == NVS_TYPE_U8) {
 		value=malloc(sizeof(uint8_t));
 		err = nvs_get_u8(nvs, key, (uint8_t *) value);
-		printf("value found = %u\n",*(uint8_t *)value);
 	} else if (type == NVS_TYPE_I16) {
 		value=malloc(sizeof(int16_t));
 		err = nvs_get_i16(nvs, key, (int16_t *) value);
-		printf("value found = %d\n",*(int16_t *)value);
 	} else if (type == NVS_TYPE_U16) {
 		value=malloc(sizeof(uint16_t));
 		err = nvs_get_u16(nvs, key, (uint16_t *) value);
-		printf("value found = %u\n",*(uint16_t *)value);
 	} else if (type == NVS_TYPE_I32) {
 		value=malloc(sizeof(int32_t));
 		err = nvs_get_i32(nvs, key, (int32_t *) value);
@@ -105,20 +135,24 @@ void * get_nvs_value_alloc(nvs_type_t type, const char *key) {
 		value=malloc(sizeof(uint64_t));
 		err = nvs_get_u64(nvs, key, (uint64_t *) value);
 	} else if (type == NVS_TYPE_STR) {
-		size_t len;
-		if ((err = nvs_get_str(nvs, key, NULL, &len)) == ESP_OK) {
-			value=malloc(sizeof(len+1));
+		size_t len=0;
+		err = nvs_get_str(nvs, key, NULL, &len);
+		if (err == ESP_OK) {
+			value=malloc(len);
 			err = nvs_get_str(nvs, key, value, &len);
 			}
 	} else if (type == NVS_TYPE_BLOB) {
 		size_t len;
-		if ((err = nvs_get_blob(nvs, key, NULL, &len)) == ESP_OK) {
-			value=malloc(sizeof(len+1));
+		err = nvs_get_blob(nvs, key, NULL, &len);
+		if (err == ESP_OK) {
+			value=malloc(len+1);
 			err = nvs_get_blob(nvs, key, value, &len);
 		}
 	}
 	if(err!=ESP_OK){
-		free(value);
+		ESP_LOGD(TAG,"Value not found for key %s",key);
+		if(value!=NULL)
+			free(value);
 		value=NULL;
 	}
 	nvs_close(nvs);

+ 1 - 0
components/platform_esp32/nvs_utilities.h

@@ -4,6 +4,7 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+bool isNameValid(char * key);
 esp_err_t store_nvs_value_len(nvs_type_t type, const char *key, void * data, size_t data_len);
 esp_err_t store_nvs_value(nvs_type_t type, const char *key, void * data);
 esp_err_t get_nvs_value(nvs_type_t type, const char *key, void*value, const uint8_t buf_size);

+ 19 - 19
components/platform_esp32/platform_esp32.c

@@ -352,10 +352,10 @@ void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
         break;
     }
     case ESP_BT_GAP_RMT_SRVCS_EVT:
-    	ESP_LOG_DEBUG_EVENT(TAG,ESP_BT_GAP_RMT_SRVCS_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(ESP_BT_GAP_RMT_SRVCS_EVT));
     	break;
     case ESP_BT_GAP_RMT_SRVC_REC_EVT:
-    	ESP_LOG_DEBUG_EVENT(TAG,ESP_BT_GAP_RMT_SRVC_REC_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(ESP_BT_GAP_RMT_SRVC_REC_EVT));
         break;
     case ESP_BT_GAP_AUTH_CMPL_EVT: {
     	if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) {
@@ -733,7 +733,7 @@ static void bt_app_av_media_proc(uint16_t event, void *param)
         break;
     }
     case APP_AV_MEDIA_STATE_STOPPING: {
-    	ESP_LOG_DEBUG_EVENT(TAG,APP_AV_MEDIA_STATE_STOPPING);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(APP_AV_MEDIA_STATE_STOPPING));
         if (event == ESP_A2D_MEDIA_CTRL_ACK_EVT) {
             a2d = (esp_a2d_cb_param_t *)(param);
             if (a2d->media_ctrl_stat.cmd == ESP_A2D_MEDIA_CTRL_STOP &&
@@ -774,7 +774,7 @@ static void bt_app_av_state_unconnected(uint16_t event, void *param)
 //	UNLOCK;
 	switch (event) {
     case ESP_A2D_CONNECTION_STATE_EVT:
-    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_CONNECTION_STATE_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(ESP_A2D_CONNECTION_STATE_EVT));
     	// this could happen if connection was established
     	// right after we timed out. Pass the call down to the connecting
     	// handler.
@@ -785,14 +785,14 @@ static void bt_app_av_state_unconnected(uint16_t event, void *param)
 
     	break;
     case ESP_A2D_AUDIO_STATE_EVT:
-    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_AUDIO_STATE_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(ESP_A2D_AUDIO_STATE_EVT));
 
     	break;
     case ESP_A2D_AUDIO_CFG_EVT:
-    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_AUDIO_CFG_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(ESP_A2D_AUDIO_CFG_EVT));
     	break;
     case ESP_A2D_MEDIA_CTRL_ACK_EVT:
-    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_MEDIA_CTRL_ACK_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(ESP_A2D_MEDIA_CTRL_ACK_EVT));
     	break;
     case BT_APP_HEART_BEAT_EVT: {
        // uint8_t *p = s_peer_bda;
@@ -856,13 +856,13 @@ static void bt_app_av_state_connecting(uint16_t event, void *param)
         break;
     }
     case ESP_A2D_AUDIO_STATE_EVT:
-    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_AUDIO_STATE_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(ESP_A2D_AUDIO_STATE_EVT));
     	break;
     case ESP_A2D_AUDIO_CFG_EVT:
-    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_AUDIO_CFG_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(ESP_A2D_AUDIO_CFG_EVT));
     	break;
     case ESP_A2D_MEDIA_CTRL_ACK_EVT:
-    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_MEDIA_CTRL_ACK_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(ESP_A2D_MEDIA_CTRL_ACK_EVT));
     	break;
     case BT_APP_HEART_BEAT_EVT:
     	if (IS_A2DP_TIMER_OVER)
@@ -894,7 +894,7 @@ static void bt_app_av_state_connected(uint16_t event, void *param)
         break;
     }
     case ESP_A2D_AUDIO_STATE_EVT: {
-    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_AUDIO_STATE_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(ESP_A2D_AUDIO_STATE_EVT));
         a2d = (esp_a2d_cb_param_t *)(param);
         if (ESP_A2D_AUDIO_STATE_STARTED == a2d->audio_stat.state) {
             s_pkt_cnt = 0;
@@ -903,15 +903,15 @@ static void bt_app_av_state_connected(uint16_t event, void *param)
     }
     case ESP_A2D_AUDIO_CFG_EVT:
         // not suppposed to occur for A2DP source
-    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_AUDIO_CFG_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(ESP_A2D_AUDIO_CFG_EVT));
         break;
     case ESP_A2D_MEDIA_CTRL_ACK_EVT:{
-    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_MEDIA_CTRL_ACK_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(ESP_A2D_MEDIA_CTRL_ACK_EVT));
             bt_app_av_media_proc(event, param);
             break;
         }
     case BT_APP_HEART_BEAT_EVT: {
-    	ESP_LOG_DEBUG_EVENT(TAG,BT_APP_HEART_BEAT_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(BT_APP_HEART_BEAT_EVT));
         bt_app_av_media_proc(event, param);
         break;
     }
@@ -926,7 +926,7 @@ static void bt_app_av_state_disconnecting(uint16_t event, void *param)
     esp_a2d_cb_param_t *a2d = NULL;
     switch (event) {
     case ESP_A2D_CONNECTION_STATE_EVT: {
-    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_CONNECTION_STATE_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(ESP_A2D_CONNECTION_STATE_EVT));
         a2d = (esp_a2d_cb_param_t *)(param);
         if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) {
             ESP_LOGI(TAG,"a2dp disconnected");
@@ -936,16 +936,16 @@ static void bt_app_av_state_disconnecting(uint16_t event, void *param)
         break;
     }
     case ESP_A2D_AUDIO_STATE_EVT:
-    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_AUDIO_STATE_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(ESP_A2D_AUDIO_STATE_EVT));
     	break;
     case ESP_A2D_AUDIO_CFG_EVT:
-    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_AUDIO_CFG_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(ESP_A2D_AUDIO_CFG_EVT));
     	break;
     case ESP_A2D_MEDIA_CTRL_ACK_EVT:
-    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_MEDIA_CTRL_ACK_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(ESP_A2D_MEDIA_CTRL_ACK_EVT));
     	break;
     case BT_APP_HEART_BEAT_EVT:
-    	ESP_LOG_DEBUG_EVENT(TAG,BT_APP_HEART_BEAT_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,QUOTE(BT_APP_HEART_BEAT_EVT));
     	break;
     default:
         ESP_LOGE(TAG,"%s unhandled evt %d", __func__, event);

+ 1 - 1
components/platform_esp32/platform_esp32.h

@@ -63,7 +63,7 @@ extern pthread_t wifi_connect_suspend_mutex;
 //		"\n",
 //		""
 //};
-#define ESP_LOG_DEBUG_EVENT(tag,e) ESP_LOGD(tag,"evt: " QUOTE(e))
+#define ESP_LOG_DEBUG_EVENT(tag,e) ESP_LOGD(tag,"evt: " e)
 typedef struct {
 	char * optName;
 	char * cmdLinePrefix;

+ 76 - 68
main/output_dac.c

@@ -5,15 +5,17 @@
 
 
 #define DECLARE_ALL_MIN_MAX \
-	DECLARE_MIN_MAX(req); \
-	DECLARE_MIN_MAX(rec); \
-	DECLARE_MIN_MAX(over); \
 	DECLARE_MIN_MAX(o); \
 	DECLARE_MIN_MAX(s); \
 	DECLARE_MIN_MAX(loci2sbuf); \
-	DECLARE_MIN_MAX(buffering); \
+	DECLARE_MIN_MAX(req); \
+	DECLARE_MIN_MAX(rec); \
+	DECLARE_MIN_MAX(over); \
+	DECLARE_MIN_MAX(i2savailable);\
 	DECLARE_MIN_MAX(i2s_time); \
-	DECLARE_MIN_MAX(i2savailable);
+	DECLARE_MIN_MAX(buffering);
+
+
 #define RESET_ALL_MIN_MAX \
 	RESET_MIN_MAX(o); \
 	RESET_MIN_MAX(s); \
@@ -21,9 +23,10 @@
 	RESET_MIN_MAX(req);  \
 	RESET_MIN_MAX(rec);  \
 	RESET_MIN_MAX(over);  \
-	RESET_MIN_MAX(over);  \
 	RESET_MIN_MAX(i2savailable);\
-	RESET_MIN_MAX(i2s_time);
+	RESET_MIN_MAX(i2s_time);\
+	RESET_MIN_MAX(buffering);
+#define STATS_PERIOD_MS 5000
 
 // Prevent compile errors if dac output is
 // included in the build and not actually activated in menuconfig
@@ -138,8 +141,10 @@ void output_init_dac(log_level level, char *device, unsigned output_buf_size, ch
 	i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT;           //2-channels
 	i2s_config.communication_format = I2S_COMM_FORMAT_I2S| I2S_COMM_FORMAT_I2S_MSB;
 	// todo: tune this parameter. Expressed in number of samples. Byte size depends on bit depth.
-	i2s_config.dma_buf_count = 64; //todo: tune this parameter. Expressed in numbrer of buffers.
-	i2s_config.dma_buf_len =  128;
+	i2s_config.dma_buf_count = 10;
+	// From the I2S driver source, the DMA buffer size is 4092 bytes.
+	// so buf_len * 2 channels * 2 bytes/sample should be < 4092 or else it will be resized.
+	i2s_config.dma_buf_len =  FRAME_BLOCK/2;
 	i2s_config.use_apll = false;
 	i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1; //Interrupt level 1
 
@@ -154,7 +159,7 @@ void output_init_dac(log_level level, char *device, unsigned output_buf_size, ch
 	isI2SStarted=false;
 	i2s_stop(CONFIG_I2S_NUM);
 
-	dac_buffer_size = 10*FRAME_BLOCK*get_bytes_per_frame(output.format);
+	dac_buffer_size = 5*FRAME_BLOCK*get_bytes_per_frame(output.format);
 	LOG_DEBUG("Allocating local DAC transfer buffer of %u bytes.",dac_buffer_size);
 
 	buf_init(dacbuffer,dac_buffer_size );
@@ -257,9 +262,11 @@ static void *output_thread_dac() {
 	frames_t frames=0;
 	frames_t available_frames_space=0;
 	size_t bytes_to_send_i2s=0, // Contiguous buffer which can be addressed
-		 i2s_bytes_written = 0; //actual size that the i2s port was able to write
+		 i2s_bytes_written = 0,
+		 i2s_total_bytes_written=0; //actual size that the i2s port was able to write
 	uint32_t timer_start=0;
 	static int count = 0;
+	output_state state;
 
 	DECLARE_ALL_MIN_MAX;
 
@@ -270,8 +277,8 @@ static void *output_thread_dac() {
 		bytes_to_send_i2s=0, // Contiguous buffer which can be addressed
 		i2s_bytes_written = 0; //actual size that the i2s port was able to write
 		TIME_MEASUREMENT_START(timer_start);
-
 		LOCK;
+		state =output.state;
 		if (output.state == OUTPUT_OFF) {
 			UNLOCK;
 			LOG_INFO("Output state is off.");
@@ -284,22 +291,34 @@ static void *output_thread_dac() {
 			continue;
 		}
 		LOG_SDEBUG("Current buffer free: %10d, cont read: %10d",_buf_space(dacbuffer),_buf_cont_read(dacbuffer));
-		available_frames_space = min(BYTES_TO_FRAME(min(_buf_space(dacbuffer), _buf_cont_write(dacbuffer))),FRAME_BLOCK);
-		frames = _output_frames( available_frames_space ); // Keep the transfer buffer full
+
+		do{
+			// fill our buffer
+			available_frames_space = BYTES_TO_FRAME(min(_buf_space(dacbuffer), _buf_cont_write(dacbuffer)));
+			if(available_frames_space)
+			{
+				frames = _output_frames( available_frames_space ); // Keep the transfer buffer full
+				SET_MIN_MAX( available_frames_space,req);
+				SET_MIN_MAX(frames,rec);
+			}
+		}while(available_frames_space>0 && frames>0);
+
+		SET_MIN_MAX_SIZED(_buf_used(outputbuf),o,outputbuf->size);
+		SET_MIN_MAX_SIZED(_buf_used(streambuf),s,streambuf->size);
 		UNLOCK;
 		LOG_SDEBUG("Current buffer free: %10d, cont read: %10d",_buf_space(dacbuffer),_buf_cont_read(dacbuffer));
-		SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),buffering);
-		SET_MIN_MAX( available_frames_space,req);
-		SET_MIN_MAX(frames,rec);
 
+		SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),buffering);
 
 		SET_MIN_MAX_SIZED(_buf_used(dacbuffer),loci2sbuf,dacbuffer->size);
 		bytes_to_send_i2s = _buf_cont_read(dacbuffer);
 		SET_MIN_MAX(bytes_to_send_i2s,i2savailable);
 		int pass=0;
-		while (bytes_to_send_i2s>0 && pass++ < 1 )
+		i2s_total_bytes_written=0;
+
+		while (bytes_to_send_i2s>0 )
 		{
-			// now pass twice
+			// now send all the data
 			TIME_MEASUREMENT_START(timer_start);
 			if(!isI2SStarted)
 			{
@@ -325,70 +344,59 @@ static void *output_thread_dac() {
 			}
 			LOG_SDEBUG("DONE Outputting to I2S. Wrote: %d bytes out of %d", i2s_bytes_written,bytes_to_send_i2s);
 			LOG_SDEBUG("Current buffer free: %10d, cont read: %10d",_buf_space(dacbuffer),_buf_cont_read(dacbuffer));
-
-
-			output.device_frames =0;
-			output.updated = gettime_ms();
-			output.frames_played_dmp = output.frames_played;
+			i2s_total_bytes_written+=i2s_bytes_written;
 			SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),i2s_time);
+			if(bytes_to_send_i2s>0) {
+				SET_MIN_MAX(bytes_to_send_i2s-i2s_bytes_written,over);
+			}
 			bytes_to_send_i2s = _buf_cont_read(dacbuffer);
-		}
-//		if(frames>0){
-//				//LOG_DEBUG("Frames available : %u.",frames);
-//		}
-//		else
-//		{
-//			//LOG_DEBUG("No frame available");
-//			usleep(10000);
-//		}
-		SET_MIN_MAX(bytes_to_send_i2s-i2s_bytes_written,over);
-		SET_MIN_MAX_SIZED(_buf_used(outputbuf),o,outputbuf->size);
-		SET_MIN_MAX_SIZED(_buf_used(streambuf),s,streambuf->size);
+			SET_MIN_MAX(bytes_to_send_i2s,i2savailable);
 
-		/*
-		 * Statistics reporting
-		 */
+		}
+		output.device_frames =0;
+		output.updated = gettime_ms();
+		output.frames_played_dmp = output.frames_played;
 
-		//wait_for_frames(BYTES_TO_FRAME(i2s_bytes_written));
 
 		/*
 		 * Statistics reporting
 		 */
-#define STATS_PERIOD_MS 5000
 		count++;
 		TIMED_SECTION_START_MS(STATS_PERIOD_MS);
-
-		LOG_INFO( "count:%d, current sample rate: %d, bytes per frame: %d, avg cycle duration (ms): %d",count,output.current_sample_rate, out_bytes_per_frame,STATS_PERIOD_MS/count);
-		LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD1);
-		LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD2);
-		LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD3);
-		LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD4);
-		LOG_INFO(LINE_MIN_MAX_FORMAT_STREAM, LINE_MIN_MAX_STREAM("stream",s));
-		LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("output",o));
-		LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("local free",loci2sbuf));
-		LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER);
-		LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("i2swrite",i2savailable));
-		LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("requested",req));
-		LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("received",rec));
-		LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("overflow",over));
-		LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER);
-		LOG_INFO("");
-		LOG_INFO("              ----------+----------+-----------+-----------+  ");
-		LOG_INFO("              max (us)  | min (us) |   avg(us) |  count    |  ");
-		LOG_INFO("              ----------+----------+-----------+-----------+  ");
-		LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("Buffering(us)",buffering));
-		LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("i2s tfr(us)",i2s_time));
-		LOG_INFO("              ----------+----------+-----------+-----------+");
-
-
-
-		RESET_ALL_MIN_MAX;
+		if(state>OUTPUT_STOPPED){
+
+			LOG_INFO( "count:%d, Output State: %d, current sample rate: %d, bytes per frame: %d, avg cycle duration (ms): %d",count,state,output.current_sample_rate, out_bytes_per_frame,STATS_PERIOD_MS/count);
+			LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD1);
+			LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD2);
+			LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD3);
+			LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD4);
+			LOG_INFO(LINE_MIN_MAX_FORMAT_STREAM, LINE_MIN_MAX_STREAM("stream",s));
+			LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("output",o));
+			LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("dac buf used",loci2sbuf));
+			LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER);
+			LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("i2swrite",i2savailable));
+			LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("requested",req));
+			LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("received",rec));
+			LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("overflow",over));
+			LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER);
+			LOG_INFO("");
+			LOG_INFO("              ----------+----------+-----------+-----------+  ");
+			LOG_INFO("              max (us)  | min (us) |   avg(us) |  count    |  ");
+			LOG_INFO("              ----------+----------+-----------+-----------+  ");
+			LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("Buffering(us)",buffering));
+			LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("i2s tfr(us)",i2s_time));
+			LOG_INFO("              ----------+----------+-----------+-----------+");
+			RESET_ALL_MIN_MAX;
+		}
+		else {
+			LOG_INFO( "count:%d, Output State: %d",count,state);
+		}
 		count=0;
 		TIMED_SECTION_END;
 		/*
 		 * End Statistics reporting
 		 */
-//		wait_for_frames(BYTES_TO_FRAME(i2s_bytes_written),75);
+
 	}
 	return 0;
 }

+ 20 - 20
sdkconfig

@@ -77,8 +77,6 @@ CONFIG_LOGGING_SLIMPROTO="debug"
 CONFIG_LOGGING_STREAM="debug"
 CONFIG_LOGGING_DECODE="debug"
 CONFIG_LOGGING_OUTPUT="debug"
-CONFIG_WIFI_SSID="Abyssin"
-CONFIG_WIFI_PASSWORD="san92121diego"
 CONFIG_WIFI_FAST_SCAN=y
 # CONFIG_WIFI_ALL_CHANNEL_SCAN is not set
 CONFIG_WIFI_CONNECT_AP_BY_SIGNAL=y
@@ -204,17 +202,19 @@ CONFIG_SPIRAM_TYPE_AUTO=y
 # CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set
 # CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set
 CONFIG_SPIRAM_SIZE=-1
-CONFIG_SPIRAM_SPEED_40M=y
-# CONFIG_SPIRAM_SPEED_80M is not set
+# CONFIG_SPIRAM_SPEED_40M is not set
+CONFIG_SPIRAM_SPEED_80M=y
 CONFIG_SPIRAM_MEMTEST=y
 CONFIG_SPIRAM_CACHE_WORKAROUND=y
 CONFIG_SPIRAM_BANKSWITCH_ENABLE=y
 CONFIG_SPIRAM_BANKSWITCH_RESERVE=8
-CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=2048
+CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=1024
 # CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP is not set
 CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768
 # CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY is not set
 # CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set
+# CONFIG_SPIRAM_OCCUPY_HSPI_HOST is not set
+CONFIG_SPIRAM_OCCUPY_VSPI_HOST=y
 CONFIG_D0WD_PSRAM_CLK_IO=17
 CONFIG_D0WD_PSRAM_CS_IO=16
 CONFIG_D2WD_PSRAM_CLK_IO=9
@@ -271,7 +271,7 @@ CONFIG_ADC_CAL_LUT_ENABLE=y
 CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
 CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32
 CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304
-CONFIG_ESP_MAIN_TASK_STACK_SIZE=10240
+CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
 CONFIG_ESP_IPC_TASK_STACK_SIZE=1024
 CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584
 CONFIG_ESP_CONSOLE_UART_DEFAULT=y
@@ -300,10 +300,10 @@ CONFIG_HTTPD_PURGE_BUF_LEN=32
 # CONFIG_OTA_ALLOW_HTTP is not set
 CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y
 # CONFIG_ESP32_WIFI_SW_COEXIST_PREFERENCE_WIFI is not set
-CONFIG_ESP32_WIFI_SW_COEXIST_PREFERENCE_BT=y
-# CONFIG_ESP32_WIFI_SW_COEXIST_PREFERENCE_BALANCE is not set
-CONFIG_ESP32_WIFI_SW_COEXIST_PREFERENCE_VALUE=1
-CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10
+# CONFIG_ESP32_WIFI_SW_COEXIST_PREFERENCE_BT is not set
+CONFIG_ESP32_WIFI_SW_COEXIST_PREFERENCE_BALANCE=y
+CONFIG_ESP32_WIFI_SW_COEXIST_PREFERENCE_VALUE=2
+CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=16
 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=64
 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y
 CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0
@@ -424,7 +424,7 @@ CONFIG_LOG_DEFAULT_LEVEL_INFO=y
 # CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set
 CONFIG_LOG_DEFAULT_LEVEL=3
 CONFIG_LOG_COLORS=y
-# CONFIG_LWIP_L2_TO_L3_COPY is not set
+CONFIG_LWIP_L2_TO_L3_COPY=y
 # CONFIG_LWIP_IRAM_OPTIMIZATION is not set
 CONFIG_LWIP_MAX_SOCKETS=10
 # CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set
@@ -453,8 +453,8 @@ CONFIG_LWIP_TCP_SYNMAXRTX=6
 CONFIG_LWIP_TCP_MSS=1440
 CONFIG_LWIP_TCP_MSL=60000
 CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744
-CONFIG_LWIP_TCP_WND_DEFAULT=5744
-CONFIG_LWIP_TCP_RECVMBOX_SIZE=6
+CONFIG_LWIP_TCP_WND_DEFAULT=16384
+CONFIG_LWIP_TCP_RECVMBOX_SIZE=32
 CONFIG_LWIP_TCP_QUEUE_OOSEQ=y
 # CONFIG_LWIP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set
 CONFIG_LWIP_TCP_OVERSIZE_MSS=y
@@ -698,7 +698,7 @@ CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y
 # CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set
 CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
 CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304
-CONFIG_MAIN_TASK_STACK_SIZE=10240
+CONFIG_MAIN_TASK_STACK_SIZE=8192
 CONFIG_IPC_TASK_STACK_SIZE=1024
 CONFIG_TIMER_TASK_STACK_SIZE=3584
 CONFIG_CONSOLE_UART_DEFAULT=y
@@ -719,9 +719,9 @@ CONFIG_POST_EVENTS_FROM_ISR=y
 CONFIG_POST_EVENTS_FROM_IRAM_ISR=y
 CONFIG_SW_COEXIST_ENABLE=y
 # CONFIG_SW_COEXIST_PREFERENCE_WIFI is not set
-CONFIG_SW_COEXIST_PREFERENCE_BT=y
-# CONFIG_SW_COEXIST_PREFERENCE_BALANCE is not set
-CONFIG_SW_COEXIST_PREFERENCE_VALUE=1
+# CONFIG_SW_COEXIST_PREFERENCE_BT is not set
+CONFIG_SW_COEXIST_PREFERENCE_BALANCE=y
+CONFIG_SW_COEXIST_PREFERENCE_VALUE=2
 CONFIG_DMA_RX_BUF_NUM=10
 CONFIG_DMA_TX_BUF_NUM=10
 CONFIG_EMAC_L2_TO_L3_RX_BUF_MODE=y
@@ -747,7 +747,7 @@ CONFIG_SUPPORT_STATIC_ALLOCATION=y
 CONFIG_TIMER_TASK_PRIORITY=1
 CONFIG_TIMER_TASK_STACK_DEPTH=2048
 CONFIG_TIMER_QUEUE_LENGTH=10
-# CONFIG_L2_TO_L3_COPY is not set
+CONFIG_L2_TO_L3_COPY=y
 # CONFIG_USE_ONLY_LWIP_SELECT is not set
 CONFIG_ESP_GRATUITOUS_ARP=y
 CONFIG_GARP_TMR_INTERVAL=60
@@ -757,8 +757,8 @@ CONFIG_TCP_SYNMAXRTX=6
 CONFIG_TCP_MSS=1440
 CONFIG_TCP_MSL=60000
 CONFIG_TCP_SND_BUF_DEFAULT=5744
-CONFIG_TCP_WND_DEFAULT=5744
-CONFIG_TCP_RECVMBOX_SIZE=6
+CONFIG_TCP_WND_DEFAULT=16384
+CONFIG_TCP_RECVMBOX_SIZE=32
 CONFIG_TCP_QUEUE_OOSEQ=y
 # CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set
 CONFIG_TCP_OVERSIZE_MSS=y