Compare commits

...

14 Commits

Author SHA1 Message Date
Philippe G
369a9cb9bc add mono channel option - release 2021-02-06 18:02:33 -08:00
philippe44
b9deead084 Update README.md 2021-01-31 15:13:39 -08:00
philippe44
723e7442af Update README.md 2021-01-31 15:07:09 -08:00
Christian Herzog
8189a59d59 typo 2021-01-25 08:24:09 +01:00
philippe44
cc209be4f9 Update README.md 2021-01-24 00:31:08 -08:00
philippe44
1d9e8e863c Update README.md 2021-01-24 00:29:50 -08:00
philippe44
c37fd57b2c Update README.md 2021-01-24 00:29:19 -08:00
philippe44
54420387ab Update README.md 2021-01-24 00:28:56 -08:00
philippe44
173b2d13da Update README.md 2021-01-24 00:18:16 -08:00
philippe44
d60506c63f Update README.md 2021-01-23 23:52:37 -08:00
philippe44
2d80c44181 Update README.md 2021-01-23 23:51:18 -08:00
Philippe G
eb5df86733 Merge branch 'master-cmake' of https://github.com/sle118/squeezelite-esp32 into master-cmake 2021-01-18 22:55:30 -08:00
Philippe G
096e1d636d SSD1322 enhancement - release
at the expense of power but needed for 5.5' displays
2021-01-18 22:49:27 -08:00
philippe44
434836782c Update README.md 2021-01-16 12:02:03 -08:00
10 changed files with 66 additions and 39 deletions

View File

@@ -24,7 +24,7 @@ Other features include
- Firmware over-the-air update
## Supported Hardware
Any esp32-based hardware with at least 4MB of flash and 4MB of PSRAM will be capable of running squeezelite-esp32 and there are various boards that include such chip. A few are mentionned below, but any should work.
Any esp32-based hardware with at least 4MB of flash and 4MB of PSRAM will be capable of running squeezelite-esp32 and there are various boards that include such chip. A few are mentionned below, but any should work. You can find various help & instructions [here](https://forums.slimdevices.com/showthread.php?112697-ANNOUNCE-Squeezelite-ESP32-(dedicated-thread))
### Raw WROVER module
Per above description, a [WROVER module](https://www.espressif.com/en/products/modules/esp32) is enough to run Squeezelite-esp32, but that requires a bit of tinkering to extend it to have analogue audio or hardware buttons (e.g.)
@@ -45,13 +45,18 @@ NB: You can use the pre-build binaries SqueezeAMP4MBFlash which has all the hard
### ESP32-A1S
Works with [ESP32-A1S](https://docs.ai-thinker.com/esp32-a1s) module that includes audio codec and headset output. You still need to use a demo board like [this](https://www.aliexpress.com/item/4000765857347.html?spm=2114.12010615.8148356.11.5d963cd0j669ns) or an external amplifier if you want direct speaker connection.
The board showed above has the following IO set
The board shown above has the following IO set
- amplifier: GPIO21
- key2: GPIO13, key3: GPIO19, key4: GPIO23, key5: GPIO18, key6: GPIO5 (to be confirmed with dip switches)
- key1: not sure, something with GPIO36
- key1: not sure, using GPIO36 in a matrix
- jack insertion: GPIO39 (inserted low)
- LED: GPIO22 (active low)
(note that GPIO need pullups)
- D4 -> GPIO22 used for green LED (active low)
- D5 -> GPIO19 (muxed with key3)
- The IO connector also brings GPIO5, GPIO18, GPIO19, GPIO21, GPIO22 and GPIO23 (don't forget it's muxed with keys!)
- The JTAG connector uses GPIO 12, 13, 14 and 15 (see dip switch) but these are also used for SD-card (and GPIO13 is key2 as well)
- It's always possible to re-use GPIOO (download at boot) and GPIO1/GPIO3 which are RX/TX of UART0 but you'll lose trace
(note that some GPIO need pullups)
So a possible config would be
- set_GPIO: 21=amp,22=green:0,39=jack:0
@@ -207,16 +212,18 @@ There is also the possibility to use 'knobonly' option (exclusive with 'volume'
- double press is 'Back' (Left in LMS's terminology).
- a quick left-right movement on the encoder is 'Pause'
The speed of double click (or left-right) can be set using the optional parameter of 'knobonly'. This is not a perfect solution, and other ideas are welcome. Be aware that the longer you set double click speed, the less responsive the interface will be. The reason is that I need to wait for that delay before deciding if it's a single or double click. It can also make menu navigation "hesitations" being easoly interpreted as 'Pause'
The speed of double click (or left-right) can be set using the optional parameter of 'knobonly'. This is not a perfect solution, and other ideas are welcome. Be aware that the longer you set double click speed, the less responsive the interface will be. The reason is that I need to wait for that delay before deciding if it's a single or double click. It can also make menu navigation "hesitations" being easily interpreted as 'Pause'
Use parameter rotary_config with the following syntax:
```
A=<gpio>,B=<gpio>[,SW=gpio>[[,knobonly[=<ms>]|[,volume][,longpress]]
A=<gpio>,B=<gpio>[,SW=gpio>[[,knobonly[=<ms>]]|[[,volume][,longpress]]]]
```
HW note: all gpio used for rotary have internal pull-up so normally there is no need to provide Vcc to the encoder. Nevertheless if the encoder board you're using also has its own pull-up that are stronger than ESP32's ones (which is likely the case), then there will be crosstalk between gpio, so you must bring Vcc. Look at your board schematic and you'll understand that these board pull-up create a "winning" pull-down when any other pin is grounded.
The SW gpio is optional, you can re-affect it to a pure button if you prefer but the volume, longpress and knobonly options make little sense as the missing switch plays an important role in these modes. You could still have the "volume" mode, but you won't be able to use it for *anything* expect volume up and down. So be aware that the use of syntax [] is a bit misleading hereabove.
See also the "IMPORTANT NOTE" on the "Buttons" section and remember that when 'lms_ctrls_raw' (see below) is activated, none of these knobonly,volume,longpress options apply, raw button codes (not actions) are simply sent to LMS
### Buttons

View File

@@ -147,23 +147,28 @@ static bool Init( struct GDS_Device* Device ) {
Private->ReMap = 0;
Device->SetLayout( Device, false, false, false);
// set Display Enhancement
Device->WriteCommand( Device, 0xB4 );
WriteDataByte( Device, 0xA0 );
WriteDataByte( Device, 0xB5 );
// set Clocks
Device->WriteCommand( Device, 0xB3 );
WriteDataByte( Device, 0x91 );
WriteDataByte( Device, 0xB2 ); // 0x91 seems to be common but is too slow for 5.5'
// set MUX
Device->WriteCommand( Device, 0xCA );
WriteDataByte( Device, Device->Height - 1 );
// phase 1 & 2 period (needed?)
// phase 1 & 2 period
Device->WriteCommand( Device, 0xB1 );
WriteDataByte( Device, 0xE2 );
WriteDataByte( Device, 0xE3 ); // 0xE2 was recommended
// set pre-charge V (needed?°)
// set pre-charge V
Device->WriteCommand( Device, 0xBB );
WriteDataByte( Device, 0x1F );
WriteDataByte( Device, 0x0F); // 0x1F causes column interferences
// set COM deselect voltage (needed?)
// set COM deselect voltage
Device->WriteCommand( Device, 0xBE );
WriteDataByte( Device, 0x07 );

View File

@@ -21,7 +21,7 @@
#include "squeezelite.h"
#include <alac_wrapper.h>
#include "alac_wrapper.h"
#if BYTES_PER_FRAME == 4
#define ALIGN8(n) (n << 8)

View File

@@ -253,6 +253,9 @@ frames_t _output_frames(frames_t avail) {
}
out_frames = !silence ? min(size, cont_frames) : size;
if (output.channels & 0x01) gainR = MONO_MUTED;
else if (output.channels & 0x02) gainL = MONO_MUTED;
wrote = output.write_cb(out_frames, silence, gainL, gainR, cross_gain_in, cross_gain_out, &cross_ptr);

View File

@@ -90,9 +90,7 @@ static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t g
_apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out, cross_ptr);
}
if (gainL != FIXED_ONE || gainR!= FIXED_ONE) {
_apply_gain(outputbuf, out_frames, gainL, gainR);
}
_apply_gain(outputbuf, out_frames, gainL, gainR);
#if BYTES_PER_FRAME == 4
memcpy(btout + oframes * BYTES_PER_FRAME, outputbuf->readp, out_frames * BYTES_PER_FRAME);

View File

@@ -410,10 +410,7 @@ static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32
}
#if BYTES_PER_FRAME == 4
if (gainL != FIXED_ONE || gainR!= FIXED_ONE) {
_apply_gain(outputbuf, out_frames, gainL, gainR);
}
_apply_gain(outputbuf, out_frames, gainL, gainR);
memcpy(obuf + oframes * BYTES_PER_FRAME, outputbuf->readp, out_frames * BYTES_PER_FRAME);
#else
optr = (s32_t*) outputbuf->readp;

View File

@@ -356,17 +356,34 @@ void _apply_cross(struct buffer *outputbuf, frames_t out_frames, s32_t cross_gai
}
}
#if !WIN
inline
#endif
void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR) {
ISAMPLE_T *ptrL = (ISAMPLE_T *)(void *)outputbuf->readp;
ISAMPLE_T *ptrR = (ISAMPLE_T *)(void *)outputbuf->readp + 1;
while (count--) {
*ptrL = gain(gainL, *ptrL);
*ptrR = gain(gainR, *ptrR);
ptrL += 2;
ptrR += 2;
}
if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
return;
} else if (gainL == MONO_MUTED) {
ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp + 1;
while (count--) {
*(ptr - 1) = *ptr = gain(gainR, *ptr);
ptr += 2;
}
} else if (gainR == MONO_MUTED) {
ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp;
while (count--) {
*(ptr + 1) = *ptr = gain(gainL, *ptr);
ptr += 2;
}
} else {
ISAMPLE_T *ptrL = (ISAMPLE_T *)(void *)outputbuf->readp;
ISAMPLE_T *ptrR = (ISAMPLE_T *)(void *)outputbuf->readp + 1;
while (count--) {
*ptrL = gain(gainL, *ptrL);
*ptrR = gain(gainR, *ptrR);
ptrL += 2; ptrR += 2;
}
}
}

View File

@@ -397,8 +397,9 @@ static void process_strm(u8_t *pkt, int len) {
output.next_replay_gain = unpackN(&strm->replay_gain);
output.fade_mode = strm->transition_type - '0';
output.fade_secs = strm->transition_period;
output.invert = (strm->flags & 0x03) == 0x03;
LOG_DEBUG("set fade mode: %u", output.fade_mode);
output.invert = (strm->flags & 0x03) == 0x03;
output.channels = (strm->flags & 0x0c) >> 2;
LOG_DEBUG("set fade: %u, channels: %u, invert: %u", output.fade_mode, output.channels, output.invert);
UNLOCK_O;
}
break;

View File

@@ -471,7 +471,8 @@ void _wake_create(event_event*);
#define MAX_SILENCE_FRAMES 2048
#define FIXED_ONE 0x10000
#define FIXED_ONE 0x10000
#define MONO_MUTED (FIXED_ONE + 1)
#ifndef BYTES_PER_FRAME
#define BYTES_PER_FRAME 8
@@ -660,6 +661,7 @@ typedef enum { FADE_NONE = 0, FADE_CROSSFADE, FADE_IN, FADE_OUT, FADE_INOUT } fa
struct outputstate {
output_state state;
output_format format;
u8_t channels;
const char *device;
int external;
u32_t init_size;

View File

@@ -521,19 +521,16 @@ void stream_sock(u32_t ip, u16_t port, const char *header, size_t header_len, un
#if USE_SSL
if (ntohs(port) == 443) {
char *server = strcasestr(header, "Host:");
char server[256], *p;
ssl = SSL_new(SSLctx);
SSL_set_fd(ssl, sock);
// add SNI
sscanf(header, "Host:%255s", server);
if (server) {
char *p, *servername = malloc(1024);
sscanf(server, "Host:%255[^:]s", servername);
for (p = servername; *p == ' '; p++);
SSL_set_tlsext_host_name(ssl, p);
free(servername);
if ((p = strchr(server, ':')) != NULL) *p = '\0';
SSL_set_tlsext_host_name(ssl, server);
}
while (1) {