mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-08 04:27:12 +03:00
add analogue VU - release
This commit is contained in:
@@ -158,7 +158,9 @@ bool GDS_Init( struct GDS_Device* Device ) {
|
|||||||
void GDS_SetContrast( struct GDS_Device* Device, uint8_t Contrast ) { if (Device->SetContrast) Device->SetContrast( Device, Contrast); }
|
void GDS_SetContrast( struct GDS_Device* Device, uint8_t Contrast ) { if (Device->SetContrast) Device->SetContrast( Device, Contrast); }
|
||||||
void GDS_SetHFlip( struct GDS_Device* Device, bool On ) { if (Device->SetHFlip) Device->SetHFlip( Device, On ); }
|
void GDS_SetHFlip( struct GDS_Device* Device, bool On ) { if (Device->SetHFlip) Device->SetHFlip( Device, On ); }
|
||||||
void GDS_SetVFlip( struct GDS_Device* Device, bool On ) { if (Device->SetVFlip) Device->SetVFlip( Device, On ); }
|
void GDS_SetVFlip( struct GDS_Device* Device, bool On ) { if (Device->SetVFlip) Device->SetVFlip( Device, On ); }
|
||||||
|
void GDS_SetDirty( struct GDS_Device* Device ) { Device->Dirty = true; }
|
||||||
int GDS_GetWidth( struct GDS_Device* Device ) { return Device->Width; }
|
int GDS_GetWidth( struct GDS_Device* Device ) { return Device->Width; }
|
||||||
int GDS_GetHeight( struct GDS_Device* Device ) { return Device->Height; }
|
int GDS_GetHeight( struct GDS_Device* Device ) { return Device->Height; }
|
||||||
|
int GDS_GetDepth( struct GDS_Device* Device ) { return Device->Depth; }
|
||||||
void GDS_DisplayOn( struct GDS_Device* Device ) { if (Device->DisplayOn) Device->DisplayOn( Device ); }
|
void GDS_DisplayOn( struct GDS_Device* Device ) { if (Device->DisplayOn) Device->DisplayOn( Device ); }
|
||||||
void GDS_DisplayOff( struct GDS_Device* Device ) { if (Device->DisplayOff) Device->DisplayOff( Device ); }
|
void GDS_DisplayOff( struct GDS_Device* Device ) { if (Device->DisplayOff) Device->DisplayOff( Device ); }
|
||||||
@@ -35,8 +35,10 @@ void GDS_DisplayOff( struct GDS_Device* Device );
|
|||||||
void GDS_Update( struct GDS_Device* Device );
|
void GDS_Update( struct GDS_Device* Device );
|
||||||
void GDS_SetHFlip( struct GDS_Device* Device, bool On );
|
void GDS_SetHFlip( struct GDS_Device* Device, bool On );
|
||||||
void GDS_SetVFlip( struct GDS_Device* Device, bool On );
|
void GDS_SetVFlip( struct GDS_Device* Device, bool On );
|
||||||
|
void GDS_SetDirty( struct GDS_Device* Device );
|
||||||
int GDS_GetWidth( struct GDS_Device* Device );
|
int GDS_GetWidth( struct GDS_Device* Device );
|
||||||
int GDS_GetHeight( struct GDS_Device* Device );
|
int GDS_GetHeight( struct GDS_Device* Device );
|
||||||
|
int GDS_GetDepth( struct GDS_Device* Device );
|
||||||
void GDS_ClearExt( struct GDS_Device* Device, bool full, ...);
|
void GDS_ClearExt( struct GDS_Device* Device, bool full, ...);
|
||||||
void GDS_Clear( struct GDS_Device* Device, int Color );
|
void GDS_Clear( struct GDS_Device* Device, int Color );
|
||||||
void GDS_ClearWindow( struct GDS_Device* Device, int x1, int y1, int x2, int y2, int Color );
|
void GDS_ClearWindow( struct GDS_Device* Device, int x1, int y1, int x2, int y2, int Color );
|
||||||
|
|||||||
@@ -133,45 +133,118 @@ void GDS_GetJPEGSize(uint8_t *Source, int *Width, int *Height) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* Simply draw a RGB565 image
|
* Simply draw a RGB 16bits image
|
||||||
* monoschrome (0.2125 * color.r) + (0.7154 * color.g) + (0.0721 * color.b)
|
* monochrome (0.2125 * color.r) + (0.7154 * color.g) + (0.0721 * color.b)
|
||||||
* grayscale (0.3 * R) + (0.59 * G) + (0.11 * B) )
|
* grayscale (0.3 * R) + (0.59 * G) + (0.11 * B) )
|
||||||
*/
|
*/
|
||||||
void GDS_DrawRGB16( struct GDS_Device* Device, uint16_t *Image, int x, int y, int Width, int Height, int RGB_Mode ) {
|
void GDS_DrawRGB16( struct GDS_Device* Device, uint16_t *Image, int x, int y, int Width, int Height, int RGB_Mode ) {
|
||||||
if (Device->DrawRGB16) {
|
if (Device->DrawRGB16) {
|
||||||
Device->DrawRGB16( Device, x, y, Width, Height, RGB_Mode, Image );
|
Device->DrawRGB16( Device, Image, x, y, Width, Height, RGB_Mode );
|
||||||
} else {
|
} else {
|
||||||
int Scale = Device->Depth < 5 ? 5 - Device->Depth : 0;
|
|
||||||
switch(RGB_Mode) {
|
switch(RGB_Mode) {
|
||||||
case GDS_RGB565:
|
case GDS_RGB565:
|
||||||
for (int c = 0; c < Width; c++) {
|
// 6 bits pixels to be placed. Use a linearized structure for a bit of optimization
|
||||||
|
if (Device->Depth < 6) {
|
||||||
|
int Scale = 6 - Device->Depth;
|
||||||
for (int r = 0; r < Height; r++) {
|
for (int r = 0; r < Height; r++) {
|
||||||
int pixel = Image[Width*r + c];
|
for (int c = 0; c < Width; c++) {
|
||||||
pixel = ((pixel & 0x1f) * 11 + ((((pixel >> 5) & 0x3f) * 59) >> 1) + (pixel >> 11) * 30) / 100;
|
int pixel = *Image++;
|
||||||
GDS_DrawPixel( Device, c + x, r + y, pixel >> Scale);
|
pixel = ((((pixel & 0x1f) * 11) << 1) + ((pixel >> 5) & 0x3f) * 59 + (((pixel >> 11) * 30) << 1) + 1) / 100;
|
||||||
|
GDS_DrawPixel( Device, c + x, r + y, pixel >> Scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int Scale = Device->Depth - 6;
|
||||||
|
for (int r = 0; r < Height; r++) {
|
||||||
|
for (int c = 0; c < Width; c++) {
|
||||||
|
int pixel = *Image++;
|
||||||
|
pixel = ((((pixel & 0x1f) * 11) << 1) + ((pixel >> 5) & 0x3f) * 59 + (((pixel >> 11) * 30) << 1) + 1) / 100;
|
||||||
|
GDS_DrawPixel( Device, c + x, r + y, pixel << Scale);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GDS_RGB555:
|
case GDS_RGB555:
|
||||||
for (int c = 0; c < Width; c++) {
|
// 5 bits pixels to be placed Use a linearized structure for a bit of optimization
|
||||||
|
if (Device->Depth < 5) {
|
||||||
|
int Scale = 5 - Device->Depth;
|
||||||
for (int r = 0; r < Height; r++) {
|
for (int r = 0; r < Height; r++) {
|
||||||
int pixel = Image[Width*r + c];
|
for (int c = 0; c < Width; c++) {
|
||||||
pixel = ((pixel & 0x1f) * 11 + ((pixel >> 5) & 0x1f) * 59 + (pixel >> 10) * 30) / 100;
|
int pixel = *Image++;
|
||||||
GDS_DrawPixel( Device, c + x, r + y, pixel >> Scale);
|
pixel = ((pixel & 0x1f) * 11 + ((pixel >> 5) & 0x1f) * 59 + (pixel >> 10) * 30) / 100;
|
||||||
|
GDS_DrawPixel( Device, c + x, r + y, pixel >> Scale);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
int Scale = Device->Depth - 5;
|
||||||
|
for (int r = 0; r < Height; r++) {
|
||||||
|
for (int c = 0; c < Width; c++) {
|
||||||
|
int pixel = *Image++;
|
||||||
|
pixel = ((pixel & 0x1f) * 11 + ((pixel >> 5) & 0x1f) * 59 + (pixel >> 10) * 30) / 100;
|
||||||
|
GDS_DrawPixel( Device, c + x, r + y, pixel << Scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GDS_RGB444:
|
case GDS_RGB444:
|
||||||
for (int c = 0; c < Width; c++) {
|
// 4 bits pixels to be placed
|
||||||
|
if (Device->Depth < 4) {
|
||||||
|
int Scale = 4 - Device->Depth;
|
||||||
for (int r = 0; r < Height; r++) {
|
for (int r = 0; r < Height; r++) {
|
||||||
int pixel = Image[Width*r + c];
|
for (int c = 0; c < Width; c++) {
|
||||||
pixel = (pixel & 0x0f) * 11 + ((pixel >> 4) & 0x0f) * 59 + (pixel >> 8) * 30;
|
int pixel = *Image++;
|
||||||
GDS_DrawPixel( Device, c + x, r + y, pixel >> (Scale - 1));
|
pixel = (pixel & 0x0f) * 11 + ((pixel >> 4) & 0x0f) * 59 + (pixel >> 8) * 30;
|
||||||
|
GDS_DrawPixel( Device, c + x, r + y, pixel >> Scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int Scale = Device->Depth - 4;
|
||||||
|
for (int r = 0; r < Height; r++) {
|
||||||
|
for (int c = 0; c < Width; c++) {
|
||||||
|
int pixel = *Image++;
|
||||||
|
pixel = (pixel & 0x0f) * 11 + ((pixel >> 4) & 0x0f) * 59 + (pixel >> 8) * 30;
|
||||||
|
GDS_DrawPixel( Device, c + x, r + y, pixel << Scale);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Device->Dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************
|
||||||
|
* Simply draw a RGB 8 bits image (R:3,G:3,B:2)
|
||||||
|
* monochrome (0.2125 * color.r) + (0.7154 * color.g) + (0.0721 * color.b)
|
||||||
|
* grayscale (0.3 * R) + (0.59 * G) + (0.11 * B) )
|
||||||
|
*/
|
||||||
|
void GDS_DrawRGB8( struct GDS_Device* Device, uint8_t *Image, int x, int y, int Width, int Height ) {
|
||||||
|
if (Device->DrawRGB8) {
|
||||||
|
Device->DrawRGB8( Device, Image, x, y, Width, Height );
|
||||||
|
} else if (Device->Depth < 3) {
|
||||||
|
// 3 bits pixels to be placed
|
||||||
|
int Scale = 3 - Device->Depth;
|
||||||
|
for (int r = 0; r < Height; r++) {
|
||||||
|
for (int c = 0; c < Width; c++) {
|
||||||
|
int pixel = *Image++;
|
||||||
|
pixel = ((((pixel & 0x3) * 11) << 1) + ((pixel >> 2) & 0x7) * 59 + (pixel >> 5) * 30 + 1) / 100;
|
||||||
|
GDS_DrawPixel( Device, c + x, r + y, pixel >> Scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 3 bits pixels to be placed
|
||||||
|
int Scale = Device->Depth - 3;
|
||||||
|
for (int r = 0; r < Height; r++) {
|
||||||
|
for (int c = 0; c < Width; c++) {
|
||||||
|
int pixel = *Image++;
|
||||||
|
pixel = ((((pixel & 0x3) * 11) << 1) + ((pixel >> 2) & 0x7) * 59 + (pixel >> 5) * 30 + 1) / 100;
|
||||||
|
GDS_DrawPixel( Device, c + x, r + y, pixel << Scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Device->Dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Decode the embedded image into pixel lines that can be used with the rest of the logic.
|
//Decode the embedded image into pixel lines that can be used with the rest of the logic.
|
||||||
@@ -228,6 +301,7 @@ bool GDS_DrawJPEG( struct GDS_Device* Device, uint8_t *Source, int x, int y, int
|
|||||||
// do decompress & draw
|
// do decompress & draw
|
||||||
Res = jd_decomp(&Decoder, OutHandlerDirect, N);
|
Res = jd_decomp(&Decoder, OutHandlerDirect, N);
|
||||||
if (Res == JDR_OK) {
|
if (Res == JDR_OK) {
|
||||||
|
Device->Dirty = true;
|
||||||
Ret = true;
|
Ret = true;
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(TAG, "Image decoder: jd_decode failed (%d)", Res);
|
ESP_LOGE(TAG, "Image decoder: jd_decode failed (%d)", Res);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ struct GDS_Device;
|
|||||||
|
|
||||||
enum { GDS_RGB565, GDS_RGB555, GDS_RGB444 };
|
enum { GDS_RGB565, GDS_RGB555, GDS_RGB444 };
|
||||||
|
|
||||||
|
// Fit options for GDS_DrawJPEG
|
||||||
#define GDS_IMAGE_LEFT 0x00
|
#define GDS_IMAGE_LEFT 0x00
|
||||||
#define GDS_IMAGE_CENTER_X 0x01
|
#define GDS_IMAGE_CENTER_X 0x01
|
||||||
#define GDS_IMAGE_RIGHT 0x04
|
#define GDS_IMAGE_RIGHT 0x04
|
||||||
@@ -16,11 +17,11 @@ enum { GDS_RGB565, GDS_RGB555, GDS_RGB444 };
|
|||||||
#define GDS_IMAGE_BOTTOM 0x08
|
#define GDS_IMAGE_BOTTOM 0x08
|
||||||
#define GDS_IMAGE_CENTER_Y 0x02
|
#define GDS_IMAGE_CENTER_Y 0x02
|
||||||
#define GDS_IMAGE_CENTER (GDS_IMAGE_CENTER_X | GDS_IMAGE_CENTER_Y)
|
#define GDS_IMAGE_CENTER (GDS_IMAGE_CENTER_X | GDS_IMAGE_CENTER_Y)
|
||||||
#define GDS_IMAGE_FIT 0x10
|
#define GDS_IMAGE_FIT 0x10 // re-scale by a factor of 2^N (up to 3)
|
||||||
|
|
||||||
// Width and Height can be NULL if you already know them (actual scaling is closest ^2)
|
// Width and Height can be NULL if you already know them (actual scaling is closest ^2)
|
||||||
uint16_t* GDS_DecodeJPEG(uint8_t *Source, int *Width, int *Height, float Scale);
|
uint16_t* GDS_DecodeJPEG(uint8_t *Source, int *Width, int *Height, float Scale);
|
||||||
void GDS_GetJPEGSize(uint8_t *Source, int *Width, int *Height);
|
void GDS_GetJPEGSize(uint8_t *Source, int *Width, int *Height);
|
||||||
|
bool GDS_DrawJPEG( struct GDS_Device* Device, uint8_t *Source, int x, int y, int Fit);
|
||||||
void GDS_DrawRGB16( struct GDS_Device* Device, uint16_t *Image, int x, int y, int Width, int Height, int RGB_Mode );
|
void GDS_DrawRGB16( struct GDS_Device* Device, uint16_t *Image, int x, int y, int Width, int Height, int RGB_Mode );
|
||||||
// set DisplayWidth and DisplayHeight to non-zero if you want autoscale to closest factor ^2 from 0..3
|
void GDS_DrawRGB8( struct GDS_Device* Device, uint8_t *Image, int x, int y, int Width, int Height );
|
||||||
bool GDS_DrawJPEG( struct GDS_Device* Device, uint8_t *Source, int x, int y, int Fit);
|
|
||||||
@@ -111,7 +111,8 @@ struct GDS_Device {
|
|||||||
void (*DrawPixelFast)( struct GDS_Device* Device, int X, int Y, int Color );
|
void (*DrawPixelFast)( struct GDS_Device* Device, int X, int Y, int Color );
|
||||||
void (*DrawBitmapCBR)(struct GDS_Device* Device, uint8_t *Data, int Width, int Height, int Color );
|
void (*DrawBitmapCBR)(struct GDS_Device* Device, uint8_t *Data, int Width, int Height, int Color );
|
||||||
// may provide for optimization
|
// may provide for optimization
|
||||||
void (*DrawRGB16)( struct GDS_Device* Device, int x, int y, int Width, int Height, int RGB_Mode, uint16_t *Image );
|
void (*DrawRGB16)( struct GDS_Device* Device, uint16_t *Image,int x, int y, int Width, int Height, int RGB_Mode );
|
||||||
|
void (*DrawRGB8)( struct GDS_Device* Device, uint8_t *Image, int x, int y, int Width, int Height );
|
||||||
void (*ClearWindow)( struct GDS_Device* Device, int x1, int y1, int x2, int y2, int Color );
|
void (*ClearWindow)( struct GDS_Device* Device, int x1, int y1, int x2, int y2, int Color );
|
||||||
|
|
||||||
// interface-specific methods
|
// interface-specific methods
|
||||||
|
|||||||
@@ -21,4 +21,5 @@ CFLAGS += -O3 -DLINKALL -DLOOPBACK -DNO_FAAD -DRESAMPLE16 -DEMBEDDED -DTREMOR_ON
|
|||||||
|
|
||||||
COMPONENT_SRCDIRS := . tas57xx a1s external
|
COMPONENT_SRCDIRS := . tas57xx a1s external
|
||||||
COMPONENT_ADD_INCLUDEDIRS := . ./tas57xx ./a1s
|
COMPONENT_ADD_INCLUDEDIRS := . ./tas57xx ./a1s
|
||||||
|
COMPONENT_EMBED_FILES := vu.data
|
||||||
|
|
||||||
|
|||||||
@@ -73,9 +73,12 @@ struct visu_packet {
|
|||||||
u8_t which;
|
u8_t which;
|
||||||
u8_t count;
|
u8_t count;
|
||||||
union {
|
union {
|
||||||
struct {
|
union {
|
||||||
u32_t bars;
|
struct {
|
||||||
u32_t spectrum_scale;
|
u32_t bars;
|
||||||
|
u32_t spectrum_scale;
|
||||||
|
};
|
||||||
|
u32_t style;
|
||||||
} full;
|
} full;
|
||||||
struct {
|
struct {
|
||||||
u32_t width;
|
u32_t width;
|
||||||
@@ -137,6 +140,10 @@ static struct {
|
|||||||
#define RMS_LEN_BIT 6
|
#define RMS_LEN_BIT 6
|
||||||
#define RMS_LEN (1 << RMS_LEN_BIT)
|
#define RMS_LEN (1 << RMS_LEN_BIT)
|
||||||
|
|
||||||
|
#define VU_WIDTH 160
|
||||||
|
#define VU_HEIGHT SB_HEIGHT
|
||||||
|
#define VU_COUNT 48
|
||||||
|
|
||||||
#define DISPLAY_BW 20000
|
#define DISPLAY_BW 20000
|
||||||
|
|
||||||
static struct scroller_s {
|
static struct scroller_s {
|
||||||
@@ -178,7 +185,7 @@ static EXT_RAM_ATTR struct {
|
|||||||
int limit;
|
int limit;
|
||||||
} bars[MAX_BARS];
|
} bars[MAX_BARS];
|
||||||
float spectrum_scale;
|
float spectrum_scale;
|
||||||
int n, col, row, height, width, border;
|
int n, col, row, height, width, border, style, max;
|
||||||
enum { VISU_BLANK, VISU_VUMETER, VISU_SPECTRUM, VISU_WAVEFORM } mode;
|
enum { VISU_BLANK, VISU_VUMETER, VISU_SPECTRUM, VISU_WAVEFORM } mode;
|
||||||
int speed, wake;
|
int speed, wake;
|
||||||
float fft[FFT_LEN*2], samples[FFT_LEN*2], hanning[FFT_LEN];
|
float fft[FFT_LEN*2], samples[FFT_LEN*2], hanning[FFT_LEN];
|
||||||
@@ -189,6 +196,8 @@ static EXT_RAM_ATTR struct {
|
|||||||
} back;
|
} back;
|
||||||
} visu;
|
} visu;
|
||||||
|
|
||||||
|
extern const uint8_t vu_bitmap[] asm("_binary_vu_data_start");
|
||||||
|
|
||||||
#define ANIM_NONE 0x00
|
#define ANIM_NONE 0x00
|
||||||
#define ANIM_TRANSITION 0x01 // A transition animation has finished
|
#define ANIM_TRANSITION 0x01 // A transition animation has finished
|
||||||
#define ANIM_SCROLL_ONCE 0x02
|
#define ANIM_SCROLL_ONCE 0x02
|
||||||
@@ -565,6 +574,49 @@ static void vfdc_handler( u8_t *_data, int bytes_read) {
|
|||||||
show_display_buffer(ddram);
|
show_display_buffer(ddram);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************
|
||||||
|
* Display VU-Meter (lots of hard-coding)
|
||||||
|
*/
|
||||||
|
void draw_VU(struct GDS_Device * display, const uint8_t *data, int level, int x, int y, int width) {
|
||||||
|
// VU data is by columns and vertical flip to allow block offset
|
||||||
|
data += level * VU_WIDTH * VU_HEIGHT;
|
||||||
|
|
||||||
|
// adjust to current display window
|
||||||
|
if (width > VU_WIDTH) {
|
||||||
|
width = VU_WIDTH;
|
||||||
|
x += (width - VU_WIDTH) / 2;
|
||||||
|
} else {
|
||||||
|
data += (VU_WIDTH - width) / 2 * VU_HEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is RGB332, so pixel will be 3 bits deep
|
||||||
|
int depth = GDS_GetDepth(display);
|
||||||
|
|
||||||
|
// use "fast" version as we are not beyond screen boundaries
|
||||||
|
if (depth < 3) {
|
||||||
|
int scale = 3 - depth;
|
||||||
|
for (int r = 0; r < width; r++) {
|
||||||
|
for (int c = 0; c < VU_HEIGHT; c++) {
|
||||||
|
int pixel = *data++;
|
||||||
|
pixel = ((((pixel & 0x3) * 11) << 1) + ((pixel >> 2) & 0x7) * 59 + (pixel >> 5) * 30 + 1) / 100;
|
||||||
|
GDS_DrawPixelFast(display, r + x, c + y, pixel >> scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int scale = depth - 3;
|
||||||
|
for (int r = 0; r < width; r++) {
|
||||||
|
for (int c = 0; c < VU_HEIGHT; c++) {
|
||||||
|
int pixel = *data++;
|
||||||
|
pixel = ((((pixel & 0x3) * 11) << 1) + ((pixel >> 2) & 0x7) * 59 + (pixel >> 5) * 30 + 1) / 100;
|
||||||
|
GDS_DrawPixelFast(display, r + x, c + y, pixel << scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// need to manually set dirty flag as DrawPixel does not do it
|
||||||
|
GDS_SetDirty(display);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* Process graphic display data
|
* Process graphic display data
|
||||||
*/
|
*/
|
||||||
@@ -733,7 +785,8 @@ static void grfa_handler(u8_t *data, int len) {
|
|||||||
int size = len - sizeof(struct grfa_packet);
|
int size = len - sizeof(struct grfa_packet);
|
||||||
int offset = htonl(pkt->offset);
|
int offset = htonl(pkt->offset);
|
||||||
int length = htonl(pkt->length);
|
int length = htonl(pkt->length);
|
||||||
|
|
||||||
|
// when using full screen visualizer on small screen there is a brief overlay
|
||||||
artwork.enable = (length != 0);
|
artwork.enable = (length != 0);
|
||||||
|
|
||||||
// just a config or an actual artwork
|
// just a config or an actual artwork
|
||||||
@@ -810,7 +863,7 @@ static void visu_update(void) {
|
|||||||
// convert to dB (1 bit remaining for getting X²/N, 60dB dynamic starting from 0dBFS = 3 bits back-off)
|
// convert to dB (1 bit remaining for getting X²/N, 60dB dynamic starting from 0dBFS = 3 bits back-off)
|
||||||
for (int i = visu.n; --i >= 0;) {
|
for (int i = visu.n; --i >= 0;) {
|
||||||
visu.bars[i].current = SB_HEIGHT * (0.01667f*10*log10f(0.0000001f + (visu.bars[i].current >> 1)) - 0.2543f);
|
visu.bars[i].current = SB_HEIGHT * (0.01667f*10*log10f(0.0000001f + (visu.bars[i].current >> 1)) - 0.2543f);
|
||||||
if (visu.bars[i].current > 31) visu.bars[i].current = 31;
|
if (visu.bars[i].current > visu.max) visu.bars[i].current = visu.max;
|
||||||
else if (visu.bars[i].current < 0) visu.bars[i].current = 0;
|
else if (visu.bars[i].current < 0) visu.bars[i].current = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -852,7 +905,7 @@ static void visu_update(void) {
|
|||||||
|
|
||||||
// convert to dB and bars, same back-off
|
// convert to dB and bars, same back-off
|
||||||
if (power) visu.bars[i].current = SB_HEIGHT * (0.01667f*10*(log10f(power) - log10f(FFT_LEN/2*2)) - 0.2543f);
|
if (power) visu.bars[i].current = SB_HEIGHT * (0.01667f*10*(log10f(power) - log10f(FFT_LEN/2*2)) - 0.2543f);
|
||||||
if (visu.bars[i].current > 31) visu.bars[i].current = 31;
|
if (visu.bars[i].current > visu.max) visu.bars[i].current = visu.max;
|
||||||
else if (visu.bars[i].current < 0) visu.bars[i].current = 0;
|
else if (visu.bars[i].current < 0) visu.bars[i].current = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -872,23 +925,31 @@ static void visu_update(void) {
|
|||||||
GDS_DrawBitmapCBR(display, visu.back.frame, visu.back.width, displayer.height, GDS_COLOR_WHITE);
|
GDS_DrawBitmapCBR(display, visu.back.frame, visu.back.width, displayer.height, GDS_COLOR_WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// there is much more optimization to be done here, like not redrawing bars unless needed
|
if (mode != VISU_VUMETER || !visu.style) {
|
||||||
for (int i = visu.n; --i >= 0;) {
|
// there is much more optimization to be done here, like not redrawing bars unless needed
|
||||||
int x1 = visu.col + visu.border + visu.bar_border + i*(visu.bar_width + visu.bar_gap);
|
for (int i = visu.n; --i >= 0;) {
|
||||||
int y1 = visu.row + visu.height - 1;
|
int x1 = visu.col + visu.border + visu.bar_border + i*(visu.bar_width + visu.bar_gap);
|
||||||
|
int y1 = visu.row + visu.height - 1;
|
||||||
|
|
||||||
if (visu.bars[i].current > visu.bars[i].max) visu.bars[i].max = visu.bars[i].current;
|
if (visu.bars[i].current > visu.bars[i].max) visu.bars[i].max = visu.bars[i].current;
|
||||||
else if (visu.bars[i].max) visu.bars[i].max--;
|
else if (visu.bars[i].max) visu.bars[i].max--;
|
||||||
else if (!clear) continue;
|
else if (!clear) continue;
|
||||||
|
|
||||||
for (int j = 0; j <= visu.bars[i].current; j += 2)
|
for (int j = 0; j <= visu.bars[i].current; j += 2)
|
||||||
GDS_DrawLine(display, x1, y1 - j, x1 + visu.bar_width - 1, y1 - j, GDS_COLOR_WHITE);
|
GDS_DrawLine(display, x1, y1 - j, x1 + visu.bar_width - 1, y1 - j, GDS_COLOR_WHITE);
|
||||||
|
|
||||||
if (visu.bars[i].max > 2) {
|
if (visu.bars[i].max > 2) {
|
||||||
GDS_DrawLine(display, x1, y1 - visu.bars[i].max, x1 + visu.bar_width - 1, y1 - visu.bars[i].max, GDS_COLOR_WHITE);
|
GDS_DrawLine(display, x1, y1 - visu.bars[i].max, x1 + visu.bar_width - 1, y1 - visu.bars[i].max, GDS_COLOR_WHITE);
|
||||||
GDS_DrawLine(display, x1, y1 - visu.bars[i].max + 1, x1 + visu.bar_width - 1, y1 - visu.bars[i].max + 1, GDS_COLOR_WHITE);
|
GDS_DrawLine(display, x1, y1 - visu.bars[i].max + 1, x1 + visu.bar_width - 1, y1 - visu.bars[i].max + 1, GDS_COLOR_WHITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (displayer.width / 2 > 3 * VU_WIDTH / 4) {
|
||||||
|
draw_VU(display, vu_bitmap, visu.bars[0].current, 0, visu.row, displayer.width / 2);
|
||||||
|
draw_VU(display, vu_bitmap, visu.bars[1].current, displayer.width / 2, visu.row, displayer.width / 2);
|
||||||
|
} else {
|
||||||
|
int level = (visu.bars[0].current + visu.bars[1].current) / 2;
|
||||||
|
draw_VU(display, vu_bitmap, level, 0, visu.row, displayer.width);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -950,27 +1011,36 @@ static void visu_handler( u8_t *data, int len) {
|
|||||||
} else {
|
} else {
|
||||||
// full screen visu, try to use bottom screen if available
|
// full screen visu, try to use bottom screen if available
|
||||||
visu.height = GDS_GetHeight(display) > SB_HEIGHT ? GDS_GetHeight(display) - SB_HEIGHT : GDS_GetHeight(display);
|
visu.height = GDS_GetHeight(display) > SB_HEIGHT ? GDS_GetHeight(display) - SB_HEIGHT : GDS_GetHeight(display);
|
||||||
bars = htonl(pkt->full.bars);
|
|
||||||
visu.spectrum_scale = htonl(pkt->full.spectrum_scale) / 100.;
|
|
||||||
visu.row = GDS_GetHeight(display) - visu.height;
|
visu.row = GDS_GetHeight(display) - visu.height;
|
||||||
|
|
||||||
|
// is this spectrum or analogue/digital
|
||||||
|
if ((visu.mode & ~VISU_ESP32) == VISU_SPECTRUM) {
|
||||||
|
bars = htonl(pkt->full.bars);
|
||||||
|
visu.spectrum_scale = htonl(pkt->full.spectrum_scale) / 100.;
|
||||||
|
} else {
|
||||||
|
// select analogue/digital
|
||||||
|
visu.style = htonl(pkt->full.style);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// classical (screensaver) mode, don't try to optimize screen usage & force some params
|
// classical (screensaver) mode, don't try to optimize screen usage & force some params
|
||||||
visu.row = 0;
|
visu.row = 0;
|
||||||
visu.height = SB_HEIGHT;
|
visu.height = SB_HEIGHT;
|
||||||
visu.spectrum_scale = 0.25;
|
visu.spectrum_scale = 0.25;
|
||||||
if (artwork.enable && artwork.y < SB_HEIGHT) visu.width = artwork.x - 1;
|
|
||||||
if (visu.mode == VISU_SPECTRUM) bars = visu.width / (htonl(pkt->channels[0].bar_width) + htonl(pkt->channels[0].bar_space));
|
if (visu.mode == VISU_SPECTRUM) bars = visu.width / (htonl(pkt->channels[0].bar_width) + htonl(pkt->channels[0].bar_space));
|
||||||
|
else visu.style = htonl(pkt->classical_vu.style);
|
||||||
if (bars > MAX_BARS) bars = MAX_BARS;
|
if (bars > MAX_BARS) bars = MAX_BARS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to adapt to what we have
|
// try to adapt to what we have
|
||||||
if ((visu.mode & ~VISU_ESP32) == VISU_SPECTRUM) {
|
if ((visu.mode & ~VISU_ESP32) == VISU_SPECTRUM) {
|
||||||
visu.n = bars ? bars : MAX_BARS;
|
visu.n = bars ? bars : MAX_BARS;
|
||||||
|
visu.max = displayer.height - 1;
|
||||||
if (visu.spectrum_scale <= 0 || visu.spectrum_scale > 0.5) visu.spectrum_scale = 0.5;
|
if (visu.spectrum_scale <= 0 || visu.spectrum_scale > 0.5) visu.spectrum_scale = 0.5;
|
||||||
spectrum_limits(0, visu.n, 0);
|
spectrum_limits(0, visu.n, 0);
|
||||||
} else {
|
} else {
|
||||||
visu.n = 2;
|
visu.n = 2;
|
||||||
|
visu.max = visu.style ? (VU_COUNT - 1) : (displayer.height - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|||||||
BIN
components/squeezelite/vu.data
Normal file
BIN
components/squeezelite/vu.data
Normal file
Binary file not shown.
Binary file not shown.
@@ -168,31 +168,48 @@ sub build_modes {
|
|||||||
# mode 9
|
# mode 9
|
||||||
{ desc => ['VISUALIZER_VUMETER'],
|
{ desc => ['VISUALIZER_VUMETER'],
|
||||||
bar => 0, secs => 0, width => $width,
|
bar => 0, secs => 0, width => $width,
|
||||||
params => [$VISUALIZER_VUMETER_ESP32] },
|
params => [$VISUALIZER_VUMETER_ESP32, 0] },
|
||||||
# mode 10
|
# mode 10
|
||||||
|
{ desc => ['VISUALIZER_ANALOG_VUMETER'],
|
||||||
|
bar => 0, secs => 0, width => $width,
|
||||||
|
params => [$VISUALIZER_VUMETER_ESP32, 1] },
|
||||||
|
# mode 11
|
||||||
{ desc => ['VISUALIZER_SPECTRUM_ANALYZER'],
|
{ desc => ['VISUALIZER_SPECTRUM_ANALYZER'],
|
||||||
bar => 0, secs => 0, width => $width,
|
bar => 0, secs => 0, width => $width,
|
||||||
# extra parameters (bars)
|
# extra parameters (bars)
|
||||||
params => [$VISUALIZER_SPECTRUM_ANALYZER_ESP32, int ($width/$spectrum->{full}->{band}), $spectrum->{scale}] },
|
params => [$VISUALIZER_SPECTRUM_ANALYZER_ESP32, int ($width/$spectrum->{full}->{band}), $spectrum->{scale}] },
|
||||||
# mode 11
|
);
|
||||||
|
|
||||||
|
my @extra = (
|
||||||
|
# mode E1
|
||||||
{ desc => ['VISUALIZER_VUMETER', 'AND', 'ELAPSED'],
|
{ desc => ['VISUALIZER_VUMETER', 'AND', 'ELAPSED'],
|
||||||
bar => 0, secs => 1, width => $width,
|
bar => 0, secs => 1, width => $width,
|
||||||
params => [$VISUALIZER_VUMETER_ESP32] },
|
params => [$VISUALIZER_VUMETER_ESP32, 0] },
|
||||||
# mode 12
|
# mode E2
|
||||||
|
{ desc => ['VISUALIZER_ANALOG_VUMETER', 'AND', 'ELAPSED'],
|
||||||
|
bar => 0, secs => 1, width => $width,
|
||||||
|
params => [$VISUALIZER_VUMETER_ESP32, 1] },
|
||||||
|
# mode E3
|
||||||
{ desc => ['VISUALIZER_SPECTRUM_ANALYZER', 'AND', 'ELAPSED'],
|
{ desc => ['VISUALIZER_SPECTRUM_ANALYZER', 'AND', 'ELAPSED'],
|
||||||
bar => 0, secs => 1, width => $width,
|
bar => 0, secs => 1, width => $width,
|
||||||
# extra parameters (bars)
|
# extra parameters (bars)
|
||||||
params => [$VISUALIZER_SPECTRUM_ANALYZER_ESP32, int ($width/$spectrum->{full}->{band}), $spectrum->{scale}] },
|
params => [$VISUALIZER_SPECTRUM_ANALYZER_ESP32, int ($width/$spectrum->{full}->{band}), $spectrum->{scale}] },
|
||||||
# mode 13
|
# mode E4
|
||||||
{ desc => ['VISUALIZER_VUMETER', 'AND', 'REMAINING'],
|
{ desc => ['VISUALIZER_VUMETER', 'AND', 'REMAINING'],
|
||||||
bar => 0, secs => -1, width => $width,
|
bar => 0, secs => -1, width => $width,
|
||||||
params => [$VISUALIZER_VUMETER_ESP32] },
|
params => [$VISUALIZER_VUMETER_ESP32, 0] },
|
||||||
# mode 14
|
# mode E5
|
||||||
|
{ desc => ['VISUALIZER_ANALOG_VUMETER', 'AND', 'REMAINING'],
|
||||||
|
bar => 0, secs => -1, width => $width,
|
||||||
|
params => [$VISUALIZER_VUMETER_ESP32, 1] },
|
||||||
|
# mode E6
|
||||||
{ desc => ['VISUALIZER_SPECTRUM_ANALYZER', 'AND', 'REMAINING'],
|
{ desc => ['VISUALIZER_SPECTRUM_ANALYZER', 'AND', 'REMAINING'],
|
||||||
bar => 0, secs => -1, width => $width,
|
bar => 0, secs => -1, width => $width,
|
||||||
# extra parameters (bars)
|
# extra parameters (bars)
|
||||||
params => [$VISUALIZER_SPECTRUM_ANALYZER_ESP32, int ($width/$spectrum->{full}->{band}), $spectrum->{scale}] },
|
params => [$VISUALIZER_SPECTRUM_ANALYZER_ESP32, int ($width/$spectrum->{full}->{band}), $spectrum->{scale}] },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@modes = (@modes, @extra) if $cprefs->get('height') > 32;
|
||||||
|
|
||||||
return \@modes;
|
return \@modes;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,6 @@
|
|||||||
<name>PLUGIN_SQUEEZEESP32</name>
|
<name>PLUGIN_SQUEEZEESP32</name>
|
||||||
<description>PLUGIN_SQUEEZEESP32_DESC</description>
|
<description>PLUGIN_SQUEEZEESP32_DESC</description>
|
||||||
<module>Plugins::SqueezeESP32::Plugin</module>
|
<module>Plugins::SqueezeESP32::Plugin</module>
|
||||||
<version>0.51</version>
|
<version>0.60</version>
|
||||||
<creator>Philippe</creator>
|
<creator>Philippe</creator>
|
||||||
</extensions>
|
</extensions>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<?xml version='1.0' standalone='yes'?>
|
<?xml version='1.0' standalone='yes'?>
|
||||||
<extensions>
|
<extensions>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin version="0.51" name="SqueezeESP32" minTarget="7.5" maxTarget="*">
|
<plugin version="0.60" name="SqueezeESP32" minTarget="7.5" maxTarget="*">
|
||||||
<link>https://github.com/sle118/squeezelite-esp32</link>
|
<link>https://github.com/sle118/squeezelite-esp32</link>
|
||||||
<creator>Philippe</creator>
|
<creator>Philippe</creator>
|
||||||
<sha>22551488cdbe02c7a357b2b520f8d377af9cb7d3</sha>
|
<sha>fe158890790ead9a5f27a47a7c7a55b5719087fe</sha>
|
||||||
<email>philippe_44@outlook.com</email>
|
<email>philippe_44@outlook.com</email>
|
||||||
<desc lang="EN">SqueezeESP32 additional player id (100)</desc>
|
<desc lang="EN">SqueezeESP32 additional player id (100)</desc>
|
||||||
<url>http://github.com/sle118/squeezelite-esp32/raw/master/plugin/SqueezeESP32.zip</url>
|
<url>http://github.com/sle118/squeezelite-esp32/raw/master/plugin/SqueezeESP32.zip</url>
|
||||||
|
|||||||
Reference in New Issue
Block a user