Console implemented, DAC stabilized, BT stabilized

This commit is contained in:
Sebastien Leclerc
2019-06-20 17:29:19 -04:00
parent 8500b2180d
commit e5921154f1
9 changed files with 188 additions and 135 deletions

View File

@@ -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);
SET_MIN_MAX(bytes_to_send_i2s,i2savailable);
}
// 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);
output.device_frames =0;
output.updated = gettime_ms();
output.frames_played_dmp = output.frames_played;
/*
* Statistics reporting
*/
//wait_for_frames(BYTES_TO_FRAME(i2s_bytes_written));
/*
* Statistics reporting
*/
#define STATS_PERIOD_MS 5000
count++;
TIMED_SECTION_START_MS(STATS_PERIOD_MS);
if(state>OUTPUT_STOPPED){
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;
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;
}