mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2026-01-05 08:09:02 +03:00
Compare commits
28 Commits
Muse.16.12
...
I2S-4MFlas
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d37c270e2 | ||
|
|
6054affb81 | ||
|
|
196a1d179a | ||
|
|
7574054e22 | ||
|
|
cd088d2500 | ||
|
|
d16ce964d6 | ||
|
|
84d22cce07 | ||
|
|
0495b7ea7a | ||
|
|
b98ddd76cb | ||
|
|
7ac628a29d | ||
|
|
d2b8edce60 | ||
|
|
b4af1e7bef | ||
|
|
f91392e044 | ||
|
|
1e0fce53c7 | ||
|
|
3372aaea69 | ||
|
|
8d1888a198 | ||
|
|
18b830eaa3 | ||
|
|
cbc1ab38fb | ||
|
|
27a0d2a4d3 | ||
|
|
02fc039bbe | ||
|
|
6fad1f8251 | ||
|
|
42621561df | ||
|
|
5ecb371fb0 | ||
|
|
cad286c8d7 | ||
|
|
a9a9018794 | ||
|
|
236cfef05d | ||
|
|
02b61e0ab6 | ||
|
|
226c483b0b |
5
.github/workflows/Platform_build.yml
vendored
5
.github/workflows/Platform_build.yml
vendored
@@ -13,7 +13,6 @@ on:
|
||||
description: 'Force a Release build. When not forced, the system will check for release word in the last commit message to trigger a release'
|
||||
required: true
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
bootstrap:
|
||||
name: Global setup
|
||||
@@ -228,5 +227,7 @@ jobs:
|
||||
update_web_installer:
|
||||
name: Update Web Installer After Release
|
||||
needs: [ bootstrap, build ]
|
||||
if: ${{( always() && !cancelled() ) && needs.bootstrap.outputs.release_flag == 1 && needs.bootstrap.outputs.mock == 0 }}
|
||||
if: ${{ always() && !cancelled() && needs.bootstrap.outputs.release_flag == 1 && needs.bootstrap.outputs.mock == 0 }}
|
||||
uses: ./.github/workflows/web_deploy.yml
|
||||
secrets:
|
||||
WEB_INSTALLER: ${{ secrets.WEB_INSTALLER }}
|
||||
3
.github/workflows/web_deploy.yml
vendored
3
.github/workflows/web_deploy.yml
vendored
@@ -1,6 +1,9 @@
|
||||
name: Update Web Installer
|
||||
on:
|
||||
workflow_call:
|
||||
secrets:
|
||||
WEB_INSTALLER:
|
||||
required: true
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
update_web_installer:
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
Squeezelite-esp32 is an audio software suite made to run on espressif's ESP32 wifi (b/g/n) and bluetooth chipset. It offers the following capabilities
|
||||
|
||||
- Stream your local music and connect to all major on-line music providers (Spotify, Deezer, Tidal, Qobuz) using [Logitech Media Server - a.k.a LMS](https://forums.slimdevices.com/) and enjoy multi-room audio synchronization. LMS can be extended by numerous plugins and can be controlled using a Web browser or dedicated applications (iPhone, Android). It can also send audio to UPnP, Sonos, ChromeCast and AirPlay speakers/devices.
|
||||
- Stream from a Bluetooth device (iPhone, Android)
|
||||
- Stream from an AirPlay controller (iPhone, iTunes ...) and enjoy synchronization multiroom as well (although it's AirPlay 1 only)
|
||||
- Stream directly from a Bluetooth device (iPhone, Android)
|
||||
- Stream directly from an AirPlay controller (iPhone, iTunes ...) and enjoy synchronization multiroom as well (although it's AirPlay 1 only)
|
||||
- Stream direcly from Spotify using SpotifyConnect (thanks to [cspot](https://github.com/feelfreelinux/cspot)
|
||||
|
||||
Depending on the hardware connected to the ESP32, you can send audio to a local DAC, to SPDIF or to a Bluetooth speaker. The bare minimum required hardware is a WROVER module with 4MB of Flash and 4MB of PSRAM (https://www.espressif.com/en/products/modules/esp32). With that module standalone, just apply power and you can stream to a Bluetooth speaker. You can also send audio to most I2S DAC as well as to SPDIF receivers using just a cable or an optical transducer.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
idf_component_register(
|
||||
INCLUDE_DIRS . ./inc inc/alac inc/helix-aac inc/mad inc/resample16 inc/soxr inc/vorbis inc/opus inc/opusfile
|
||||
INCLUDE_DIRS . ./inc inc/alac inc/helix-aac inc/mad inc/resample16 inc/soxr inc/vorbis inc/opus
|
||||
)
|
||||
|
||||
if (DEFINED AAC_DISABLE_SBR)
|
||||
@@ -14,7 +14,6 @@ add_prebuilt_library(libvorbisidec lib/libvorbisidec.a )
|
||||
add_prebuilt_library(libogg lib/libogg.a )
|
||||
add_prebuilt_library(libalac lib/libalac.a )
|
||||
add_prebuilt_library(libresample16 lib/libresample16.a )
|
||||
add_prebuilt_library(libopusfile lib/libopusfile.a )
|
||||
add_prebuilt_library(libopus lib/libopus.a )
|
||||
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE libmad)
|
||||
@@ -24,5 +23,4 @@ target_link_libraries(${COMPONENT_LIB} INTERFACE libvorbisidec)
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE libogg)
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE libalac)
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE libresample16)
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE libopusfile)
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE libopus)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __CONFIG_TYPES_H__
|
||||
#define __CONFIG_TYPES_H__
|
||||
|
||||
/* these are filled in by configure */
|
||||
/* these are filled in by configure or cmake*/
|
||||
#define INCLUDE_INTTYPES_H 1
|
||||
#define INCLUDE_STDINT_H 1
|
||||
#define INCLUDE_SYS_TYPES_H 1
|
||||
@@ -21,5 +21,6 @@ typedef uint16_t ogg_uint16_t;
|
||||
typedef int32_t ogg_int32_t;
|
||||
typedef uint32_t ogg_uint32_t;
|
||||
typedef int64_t ogg_int64_t;
|
||||
typedef uint64_t ogg_uint64_t;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
********************************************************************
|
||||
|
||||
function: toplevel libogg include
|
||||
last mod: $Id$
|
||||
|
||||
********************************************************************/
|
||||
#ifndef _OGG_H
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: #ifdef jail to whip a few platforms into the UNIX ideal.
|
||||
last mod: $Id$
|
||||
function: Define a consistent set of types on each platform.
|
||||
|
||||
********************************************************************/
|
||||
#ifndef _OS_TYPES_H
|
||||
@@ -44,6 +43,7 @@
|
||||
typedef unsigned long long ogg_uint64_t;
|
||||
# elif defined(__MWERKS__)
|
||||
typedef long long ogg_int64_t;
|
||||
typedef unsigned long long ogg_uint64_t;
|
||||
typedef int ogg_int32_t;
|
||||
typedef unsigned int ogg_uint32_t;
|
||||
typedef short ogg_int16_t;
|
||||
@@ -62,6 +62,7 @@
|
||||
typedef __int64 ogg_int64_t;
|
||||
typedef __int32 ogg_int32_t;
|
||||
typedef unsigned __int32 ogg_uint32_t;
|
||||
typedef unsigned __int64 ogg_uint64_t;
|
||||
typedef __int16 ogg_int16_t;
|
||||
typedef unsigned __int16 ogg_uint16_t;
|
||||
# endif
|
||||
@@ -69,12 +70,13 @@
|
||||
|
||||
#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */
|
||||
|
||||
# include <inttypes.h>
|
||||
# include <sys/types.h>
|
||||
typedef int16_t ogg_int16_t;
|
||||
typedef uint16_t ogg_uint16_t;
|
||||
typedef u_int16_t ogg_uint16_t;
|
||||
typedef int32_t ogg_int32_t;
|
||||
typedef uint32_t ogg_uint32_t;
|
||||
typedef u_int32_t ogg_uint32_t;
|
||||
typedef int64_t ogg_int64_t;
|
||||
typedef u_int64_t ogg_uint64_t;
|
||||
|
||||
#elif defined(__HAIKU__)
|
||||
|
||||
@@ -85,6 +87,7 @@
|
||||
typedef int ogg_int32_t;
|
||||
typedef unsigned int ogg_uint32_t;
|
||||
typedef long long ogg_int64_t;
|
||||
typedef unsigned long long ogg_uint64_t;
|
||||
|
||||
#elif defined(__BEOS__)
|
||||
|
||||
@@ -95,6 +98,7 @@
|
||||
typedef int32_t ogg_int32_t;
|
||||
typedef uint32_t ogg_uint32_t;
|
||||
typedef int64_t ogg_int64_t;
|
||||
typedef uint64_t ogg_uint64_t;
|
||||
|
||||
#elif defined (__EMX__)
|
||||
|
||||
@@ -104,6 +108,8 @@
|
||||
typedef int ogg_int32_t;
|
||||
typedef unsigned int ogg_uint32_t;
|
||||
typedef long long ogg_int64_t;
|
||||
typedef unsigned long long ogg_uint64_t;
|
||||
|
||||
|
||||
#elif defined (DJGPP)
|
||||
|
||||
@@ -112,11 +118,13 @@
|
||||
typedef int ogg_int32_t;
|
||||
typedef unsigned int ogg_uint32_t;
|
||||
typedef long long ogg_int64_t;
|
||||
typedef unsigned long long ogg_uint64_t;
|
||||
|
||||
#elif defined(R5900)
|
||||
|
||||
/* PS2 EE */
|
||||
typedef long ogg_int64_t;
|
||||
typedef unsigned long ogg_uint64_t;
|
||||
typedef int ogg_int32_t;
|
||||
typedef unsigned ogg_uint32_t;
|
||||
typedef short ogg_int16_t;
|
||||
@@ -129,6 +137,7 @@
|
||||
typedef signed int ogg_int32_t;
|
||||
typedef unsigned int ogg_uint32_t;
|
||||
typedef long long int ogg_int64_t;
|
||||
typedef unsigned long long int ogg_uint64_t;
|
||||
|
||||
#elif defined(__TMS320C6X__)
|
||||
|
||||
@@ -138,6 +147,7 @@
|
||||
typedef signed int ogg_int32_t;
|
||||
typedef unsigned int ogg_uint32_t;
|
||||
typedef long long int ogg_int64_t;
|
||||
typedef unsigned long long int ogg_uint64_t;
|
||||
|
||||
#else
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 1994-2012 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation and contributors https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
reference
|
||||
<tt><a href="https://www.xiph.org/ogg/doc/libogg/reference.html">libogg</a></tt>
|
||||
and
|
||||
<tt><a href="https://mf4.xiph.org/jenkins/view/opus/job/opus/ws/doc/html/index.html">libopus</a></tt>
|
||||
<tt><a href="https://opus-codec.org/docs/opus_api-1.3.1/">libopus</a></tt>
|
||||
libraries.
|
||||
|
||||
<tt>libopusfile</tt> provides several sets of built-in routines for
|
||||
@@ -58,7 +58,7 @@
|
||||
it is stored in the header to allow you to resample to it after decoding
|
||||
(the <tt>libopusfile</tt> API does not currently provide a resampler,
|
||||
but the
|
||||
<a href="http://www.speex.org/docs/manual/speex-manual/node7.html#SECTION00760000000000000000">the
|
||||
<a href="https://www.speex.org/docs/manual/speex-manual/node7.html#SECTION00760000000000000000">the
|
||||
Speex resampler</a> is a good choice if you need one).
|
||||
In general, if you are playing back the audio, you should leave it at
|
||||
48 kHz, provided your audio hardware supports it.
|
||||
@@ -68,7 +68,7 @@
|
||||
|
||||
Opus files can contain anywhere from 1 to 255 channels of audio.
|
||||
The channel mappings for up to 8 channels are the same as the
|
||||
<a href="http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9">Vorbis
|
||||
<a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-810004.3.9">Vorbis
|
||||
mappings</a>.
|
||||
A special stereo API can convert everything to 2 channels, making it simple
|
||||
to support multichannel files in an application which only has stereo
|
||||
@@ -147,18 +147,18 @@ typedef struct OggOpusFile OggOpusFile;
|
||||
/**@endcond*/
|
||||
|
||||
/**\defgroup error_codes Error Codes*/
|
||||
/*@{*/
|
||||
/**@{*/
|
||||
/**\name List of possible error codes
|
||||
Many of the functions in this library return a negative error code when a
|
||||
function fails.
|
||||
This list provides a brief explanation of the common errors.
|
||||
See each individual function for more details on what a specific error code
|
||||
means in that context.*/
|
||||
/*@{*/
|
||||
/**@{*/
|
||||
|
||||
/**A request did not succeed.*/
|
||||
#define OP_FALSE (-1)
|
||||
/*Currently not used externally.*/
|
||||
/**Currently not used externally.**/
|
||||
#define OP_EOF (-2)
|
||||
/**There was a hole in the page sequence numbers (e.g., a page was corrupt or
|
||||
missing).*/
|
||||
@@ -185,7 +185,7 @@ typedef struct OggOpusFile OggOpusFile;
|
||||
#define OP_EBADHEADER (-133)
|
||||
/**The ID header contained an unrecognized version number.*/
|
||||
#define OP_EVERSION (-134)
|
||||
/*Currently not used at all.*/
|
||||
/**Currently not used at all.**/
|
||||
#define OP_ENOTAUDIO (-135)
|
||||
/**An audio packet failed to decode properly.
|
||||
This is usually caused by a multistream Ogg packet where the durations of
|
||||
@@ -200,11 +200,11 @@ typedef struct OggOpusFile OggOpusFile;
|
||||
/**The first or last granule position of a link failed basic validity checks.*/
|
||||
#define OP_EBADTIMESTAMP (-139)
|
||||
|
||||
/*@}*/
|
||||
/*@}*/
|
||||
/**@}*/
|
||||
/**@}*/
|
||||
|
||||
/**\defgroup header_info Header Information*/
|
||||
/*@{*/
|
||||
/**@{*/
|
||||
|
||||
/**The maximum number of channels in an Ogg Opus stream.*/
|
||||
#define OPUS_CHANNEL_COUNT_MAX (255)
|
||||
@@ -284,7 +284,7 @@ struct OpusHead{
|
||||
A particular tag may occur more than once, and order is significant.
|
||||
The character set encoding for the strings is always UTF-8, but the tag
|
||||
names are limited to ASCII, and treated as case-insensitive.
|
||||
See <a href="http://www.xiph.org/vorbis/doc/v-comment.html">the Vorbis
|
||||
See <a href="https://www.xiph.org/vorbis/doc/v-comment.html">the Vorbis
|
||||
comment header specification</a> for details.
|
||||
|
||||
In filling in this structure, <tt>libopusfile</tt> will null-terminate the
|
||||
@@ -311,7 +311,7 @@ struct OpusTags{
|
||||
};
|
||||
|
||||
/**\name Picture tag image formats*/
|
||||
/*@{*/
|
||||
/**@{*/
|
||||
|
||||
/**The MIME type was not recognized, or the image data did not match the
|
||||
declared MIME type.*/
|
||||
@@ -325,7 +325,7 @@ struct OpusTags{
|
||||
/**The image is a GIF.*/
|
||||
#define OP_PIC_FORMAT_GIF (3)
|
||||
|
||||
/*@}*/
|
||||
/**@}*/
|
||||
|
||||
/**The contents of a METADATA_BLOCK_PICTURE tag.*/
|
||||
struct OpusPictureTag{
|
||||
@@ -398,7 +398,7 @@ struct OpusPictureTag{
|
||||
These can be used to query the headers returned by <tt>libopusfile</tt>, or
|
||||
to parse Opus headers from sources other than an Ogg Opus stream, provided
|
||||
they use the same format.*/
|
||||
/*@{*/
|
||||
/**@{*/
|
||||
|
||||
/**Parses the contents of the ID header packet of an Ogg Opus stream.
|
||||
\param[out] _head Returns the contents of the parsed packet.
|
||||
@@ -671,12 +671,12 @@ void opus_picture_tag_init(OpusPictureTag *_pic) OP_ARG_NONNULL(1);
|
||||
\param _pic The #OpusPictureTag structure to clear.*/
|
||||
void opus_picture_tag_clear(OpusPictureTag *_pic) OP_ARG_NONNULL(1);
|
||||
|
||||
/*@}*/
|
||||
/**@}*/
|
||||
|
||||
/*@}*/
|
||||
/**@}*/
|
||||
|
||||
/**\defgroup url_options URL Reading Options*/
|
||||
/*@{*/
|
||||
/**@{*/
|
||||
/**\name URL reading options
|
||||
Options for op_url_stream_create() and associated functions.
|
||||
These allow you to provide proxy configuration parameters, skip SSL
|
||||
@@ -685,7 +685,7 @@ void opus_picture_tag_clear(OpusPictureTag *_pic) OP_ARG_NONNULL(1);
|
||||
times, only the value specified by the last occurrence has an effect
|
||||
(unless otherwise specified).
|
||||
They may be expanded in the future.*/
|
||||
/*@{*/
|
||||
/**@{*/
|
||||
|
||||
/**@cond PRIVATE*/
|
||||
|
||||
@@ -698,7 +698,7 @@ void opus_picture_tag_clear(OpusPictureTag *_pic) OP_ARG_NONNULL(1);
|
||||
#define OP_HTTP_PROXY_PASS_REQUEST (6720)
|
||||
#define OP_GET_SERVER_INFO_REQUEST (6784)
|
||||
|
||||
#define OP_URL_OPT(_request) ((_request)+(char *)0)
|
||||
#define OP_URL_OPT(_request) ((char *)(_request))
|
||||
|
||||
/*These macros trigger compilation errors or warnings if the wrong types are
|
||||
provided to one of the URL options.*/
|
||||
@@ -843,11 +843,11 @@ void opus_server_info_clear(OpusServerInfo *_info) OP_ARG_NONNULL(1);
|
||||
#define OP_GET_SERVER_INFO(_info) \
|
||||
OP_URL_OPT(OP_GET_SERVER_INFO_REQUEST),OP_CHECK_SERVER_INFO_PTR(_info)
|
||||
|
||||
/*@}*/
|
||||
/*@}*/
|
||||
/**@}*/
|
||||
/**@}*/
|
||||
|
||||
/**\defgroup stream_callbacks Abstract Stream Reading Interface*/
|
||||
/*@{*/
|
||||
/**@{*/
|
||||
/**\name Functions for reading from streams
|
||||
These functions define the interface used to read from and seek in a stream
|
||||
of data.
|
||||
@@ -856,7 +856,7 @@ void opus_server_info_clear(OpusServerInfo *_info) OP_ARG_NONNULL(1);
|
||||
These functions also include some convenience routines for working with
|
||||
standard <code>FILE</code> pointers, complete streams stored in a single
|
||||
block of memory, or URLs.*/
|
||||
/*@{*/
|
||||
/**@{*/
|
||||
|
||||
/**Reads up to \a _nbytes bytes of data from \a _stream.
|
||||
\param _stream The stream to read from.
|
||||
@@ -1034,18 +1034,18 @@ OP_WARN_UNUSED_RESULT void *op_url_stream_vcreate(OpusFileCallbacks *_cb,
|
||||
OP_WARN_UNUSED_RESULT void *op_url_stream_create(OpusFileCallbacks *_cb,
|
||||
const char *_url,...) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2);
|
||||
|
||||
/*@}*/
|
||||
/*@}*/
|
||||
/**@}*/
|
||||
/**@}*/
|
||||
|
||||
/**\defgroup stream_open_close Opening and Closing*/
|
||||
/*@{*/
|
||||
/**@{*/
|
||||
/**\name Functions for opening and closing streams
|
||||
|
||||
These functions allow you to test a stream to see if it is Opus, open it,
|
||||
and close it.
|
||||
Several flavors are provided for each of the built-in stream types, plus a
|
||||
more general version which takes a set of application-provided callbacks.*/
|
||||
/*@{*/
|
||||
/**@{*/
|
||||
|
||||
/**Test to see if this is an Opus stream.
|
||||
For good results, you will need at least 57 bytes (for a pure Opus-only
|
||||
@@ -1159,20 +1159,16 @@ OP_WARN_UNUSED_RESULT OggOpusFile *op_open_url(const char *_url,
|
||||
This value will be passed verbatim as the first
|
||||
argument to all of the callbacks.
|
||||
\param _cb The callbacks with which to access the stream.
|
||||
<code><a href="#op_read_func">read()</a></code> must
|
||||
be implemented.
|
||||
<code><a href="#op_seek_func">seek()</a></code> and
|
||||
<code><a href="#op_tell_func">tell()</a></code> may
|
||||
be <code>NULL</code>, or may always return -1 to
|
||||
indicate a stream is unseekable, but if
|
||||
<code><a href="#op_seek_func">seek()</a></code> is
|
||||
implemented and succeeds on a particular stream, then
|
||||
<code><a href="#op_tell_func">tell()</a></code> must
|
||||
also.
|
||||
<code><a href="#op_close_func">close()</a></code> may
|
||||
be <code>NULL</code>, but if it is not, it will be
|
||||
called when the \c OggOpusFile is destroyed by
|
||||
op_free().
|
||||
\ref op_read_func "read()" must be implemented.
|
||||
\ref op_seek_func "seek()" and \ref op_tell_func
|
||||
"tell()" may be <code>NULL</code>, or may always
|
||||
return -1 to indicate a stream is unseekable, but if
|
||||
\ref op_seek_func "seek()" is implemented and
|
||||
succeeds on a particular stream, then \ref
|
||||
op_tell_func "tell()" must also.
|
||||
\ref op_close_func "close()" may be <code>NULL</code>,
|
||||
but if it is not, it will be called when the \c
|
||||
OggOpusFile is destroyed by op_free().
|
||||
It will not be called if op_open_callbacks() fails
|
||||
with an error.
|
||||
\param _initial_data An initial buffer of data from the start of the
|
||||
@@ -1183,10 +1179,8 @@ OP_WARN_UNUSED_RESULT OggOpusFile *op_open_url(const char *_url,
|
||||
stream to be opened, even if it is unseekable.
|
||||
\param _initial_bytes The number of bytes in \a _initial_data.
|
||||
If the stream is seekable, its current position (as
|
||||
reported by
|
||||
<code><a href="#opus_tell_func">tell()</a></code>
|
||||
at the start of this function) must be equal to
|
||||
\a _initial_bytes.
|
||||
reported by \ref op_tell_func "tell()" at the start
|
||||
of this function) must be equal to \a _initial_bytes.
|
||||
Otherwise, seeking to absolute positions will
|
||||
generate inconsistent results.
|
||||
\param[out] _error Returns 0 on success, or a failure code on error.
|
||||
@@ -1206,11 +1200,10 @@ OP_WARN_UNUSED_RESULT OggOpusFile *op_open_url(const char *_url,
|
||||
implemented, such as an unsupported channel
|
||||
family.</dd>
|
||||
<dt>#OP_EINVAL</dt>
|
||||
<dd><code><a href="#op_seek_func">seek()</a></code>
|
||||
was implemented and succeeded on this source, but
|
||||
<code><a href="#op_tell_func">tell()</a></code>
|
||||
did not, or the starting position indicator was
|
||||
not equal to \a _initial_bytes.</dd>
|
||||
<dd>\ref op_seek_func "seek()" was implemented and
|
||||
succeeded on this source, but \ref op_tell_func
|
||||
"tell()" did not, or the starting position
|
||||
indicator was not equal to \a _initial_bytes.</dd>
|
||||
<dt>#OP_ENOTFORMAT</dt>
|
||||
<dd>The stream contained a link that did not have
|
||||
any logical Opus streams in it.</dd>
|
||||
@@ -1341,20 +1334,16 @@ OP_WARN_UNUSED_RESULT OggOpusFile *op_test_url(const char *_url,
|
||||
This value will be passed verbatim as the first
|
||||
argument to all of the callbacks.
|
||||
\param _cb The callbacks with which to access the stream.
|
||||
<code><a href="#op_read_func">read()</a></code> must
|
||||
be implemented.
|
||||
<code><a href="#op_seek_func">seek()</a></code> and
|
||||
<code><a href="#op_tell_func">tell()</a></code> may
|
||||
be <code>NULL</code>, or may always return -1 to
|
||||
indicate a stream is unseekable, but if
|
||||
<code><a href="#op_seek_func">seek()</a></code> is
|
||||
implemented and succeeds on a particular stream, then
|
||||
<code><a href="#op_tell_func">tell()</a></code> must
|
||||
also.
|
||||
<code><a href="#op_close_func">close()</a></code> may
|
||||
be <code>NULL</code>, but if it is not, it will be
|
||||
called when the \c OggOpusFile is destroyed by
|
||||
op_free().
|
||||
\ref op_read_func "read()" must be implemented.
|
||||
\ref op_seek_func "seek()" and \ref op_tell_func
|
||||
"tell()" may be <code>NULL</code>, or may always
|
||||
return -1 to indicate a stream is unseekable, but if
|
||||
\ref op_seek_func "seek()" is implemented and
|
||||
succeeds on a particular stream, then \ref
|
||||
op_tell_func "tell()" must also.
|
||||
\ref op_close_func "close()" may be <code>NULL</code>,
|
||||
but if it is not, it will be called when the \c
|
||||
OggOpusFile is destroyed by op_free().
|
||||
It will not be called if op_open_callbacks() fails
|
||||
with an error.
|
||||
\param _initial_data An initial buffer of data from the start of the
|
||||
@@ -1367,9 +1356,8 @@ OP_WARN_UNUSED_RESULT OggOpusFile *op_test_url(const char *_url,
|
||||
\param _initial_bytes The number of bytes in \a _initial_data.
|
||||
If the stream is seekable, its current position (as
|
||||
reported by
|
||||
<code><a href="#opus_tell_func">tell()</a></code>
|
||||
at the start of this function) must be equal to
|
||||
\a _initial_bytes.
|
||||
\ref op_tell_func "tell()" at the start of this
|
||||
function) must be equal to \a _initial_bytes.
|
||||
Otherwise, seeking to absolute positions will
|
||||
generate inconsistent results.
|
||||
\param[out] _error Returns 0 on success, or a failure code on error.
|
||||
@@ -1418,11 +1406,11 @@ int op_test_open(OggOpusFile *_of) OP_ARG_NONNULL(1);
|
||||
\param _of The \c OggOpusFile to free.*/
|
||||
void op_free(OggOpusFile *_of);
|
||||
|
||||
/*@}*/
|
||||
/*@}*/
|
||||
/**@}*/
|
||||
/**@}*/
|
||||
|
||||
/**\defgroup stream_info Stream Information*/
|
||||
/*@{*/
|
||||
/**@{*/
|
||||
/**\name Functions for obtaining information about streams
|
||||
|
||||
These functions allow you to get basic information about a stream, including
|
||||
@@ -1437,18 +1425,17 @@ void op_free(OggOpusFile *_of);
|
||||
streams returned by op_test_callbacks() or one of the associated
|
||||
convenience functions.
|
||||
Their documention will indicate so explicitly.*/
|
||||
/*@{*/
|
||||
/**@{*/
|
||||
|
||||
/**Returns whether or not the stream being read is seekable.
|
||||
This is true if
|
||||
<ol>
|
||||
<li>The <code><a href="#op_seek_func">seek()</a></code> and
|
||||
<code><a href="#op_tell_func">tell()</a></code> callbacks are both
|
||||
non-<code>NULL</code>,</li>
|
||||
<li>The <code><a href="#op_seek_func">seek()</a></code> callback was
|
||||
successfully executed at least once, and</li>
|
||||
<li>The <code><a href="#op_tell_func">tell()</a></code> callback was
|
||||
successfully able to report the position indicator afterwards.</li>
|
||||
<li>The \ref op_seek_func "seek()" and \ref op_tell_func "tell()"
|
||||
callbacks are both non-<code>NULL</code>,</li>
|
||||
<li>The \ref op_seek_func "seek()" callback was successfully executed at
|
||||
least once, and</li>
|
||||
<li>The \ref op_tell_func "tell()" callback was successfully able to report
|
||||
the position indicator afterwards.</li>
|
||||
</ol>
|
||||
This function may be called on partially-opened streams.
|
||||
\param _of The \c OggOpusFile whose seekable status is to be returned.
|
||||
@@ -1638,11 +1625,11 @@ opus_int64 op_raw_tell(const OggOpusFile *_of) OP_ARG_NONNULL(1);
|
||||
\retval #OP_EINVAL The stream was only partially open.*/
|
||||
ogg_int64_t op_pcm_tell(const OggOpusFile *_of) OP_ARG_NONNULL(1);
|
||||
|
||||
/*@}*/
|
||||
/*@}*/
|
||||
/**@}*/
|
||||
/**@}*/
|
||||
|
||||
/**\defgroup stream_seeking Seeking*/
|
||||
/*@{*/
|
||||
/**@{*/
|
||||
/**\name Functions for seeking in Opus streams
|
||||
|
||||
These functions let you seek in Opus streams, if the underlying stream
|
||||
@@ -1667,7 +1654,7 @@ ogg_int64_t op_pcm_tell(const OggOpusFile *_of) OP_ARG_NONNULL(1);
|
||||
values as would be obtained by decoding the stream straight through.
|
||||
However, such differences are expected to be smaller than the loss
|
||||
introduced by Opus's lossy compression.*/
|
||||
/*@{*/
|
||||
/**@{*/
|
||||
|
||||
/**Seek to a byte offset relative to the <b>compressed</b> data.
|
||||
This also scans packets to update the PCM cursor.
|
||||
@@ -1702,11 +1689,11 @@ int op_raw_seek(OggOpusFile *_of,opus_int64 _byte_offset) OP_ARG_NONNULL(1);
|
||||
seeking to the target destination was impossible.*/
|
||||
int op_pcm_seek(OggOpusFile *_of,ogg_int64_t _pcm_offset) OP_ARG_NONNULL(1);
|
||||
|
||||
/*@}*/
|
||||
/*@}*/
|
||||
/**@}*/
|
||||
/**@}*/
|
||||
|
||||
/**\defgroup stream_decoding Decoding*/
|
||||
/*@{*/
|
||||
/**@{*/
|
||||
/**\name Functions for decoding audio data
|
||||
|
||||
These functions retrieve actual decoded audio data from the stream.
|
||||
@@ -1744,7 +1731,7 @@ int op_pcm_seek(OggOpusFile *_of,ogg_int64_t _pcm_offset) OP_ARG_NONNULL(1);
|
||||
If you are reading from an <https:> URL (particularly if seeking is not
|
||||
supported), you should make sure to check for this error and warn the user
|
||||
appropriately.*/
|
||||
/*@{*/
|
||||
/**@{*/
|
||||
|
||||
/**Indicates that the decoding callback should produce signed 16-bit
|
||||
native-endian output samples.*/
|
||||
@@ -1890,7 +1877,7 @@ void op_set_dither_enabled(OggOpusFile *_of,int _enabled) OP_ARG_NONNULL(1);
|
||||
signed native-endian 16-bit values at 48 kHz
|
||||
with a nominal range of <code>[-32768,32767)</code>.
|
||||
Multiple channels are interleaved using the
|
||||
<a href="http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9">Vorbis
|
||||
<a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-810004.3.9">Vorbis
|
||||
channel ordering</a>.
|
||||
This must have room for at least \a _buf_size values.
|
||||
\param _buf_size The number of values that can be stored in \a _pcm.
|
||||
@@ -1972,7 +1959,7 @@ OP_WARN_UNUSED_RESULT int op_read(OggOpusFile *_of,
|
||||
signed floats at 48 kHz with a nominal range of
|
||||
<code>[-1.0,1.0]</code>.
|
||||
Multiple channels are interleaved using the
|
||||
<a href="http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9">Vorbis
|
||||
<a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-810004.3.9">Vorbis
|
||||
channel ordering</a>.
|
||||
This must have room for at least \a _buf_size floats.
|
||||
\param _buf_size The number of floats that can be stored in \a _pcm.
|
||||
@@ -2150,8 +2137,8 @@ OP_WARN_UNUSED_RESULT int op_read_stereo(OggOpusFile *_of,
|
||||
OP_WARN_UNUSED_RESULT int op_read_float_stereo(OggOpusFile *_of,
|
||||
float *_pcm,int _buf_size) OP_ARG_NONNULL(1);
|
||||
|
||||
/*@}*/
|
||||
/*@}*/
|
||||
/**@}*/
|
||||
/**@}*/
|
||||
|
||||
# if OP_GNUC_PREREQ(4,0)
|
||||
# pragma GCC visibility pop
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -136,7 +136,7 @@ const static actrls_t controls = {
|
||||
NULL, NULL, // rew, fwd
|
||||
bt_prev, bt_next, // prev, next
|
||||
NULL, NULL, NULL, NULL, // left, right, up, down
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, // pre1-6
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // pre1-10
|
||||
bt_volume_down, bt_volume_up, bt_toggle// knob left, knob_right, knob push
|
||||
};
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ void config_start_timer(){
|
||||
nvs_type_t config_get_item_type(cJSON * entry){
|
||||
if(entry==NULL){
|
||||
ESP_LOGE(TAG,"null pointer received!");
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
cJSON * item_type = cJSON_GetObjectItemCaseSensitive(entry, "type");
|
||||
if(item_type ==NULL ) {
|
||||
@@ -142,7 +142,7 @@ cJSON * config_set_value_safe(nvs_type_t nvs_type, const char *key, const void
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cJSON * existing = cJSON_GetObjectItemCaseSensitive(nvs_json, key);
|
||||
cJSON * existing = cJSON_GetObjectItemCaseSensitive(nvs_json, key);
|
||||
if(existing !=NULL && nvs_type == NVS_TYPE_STR && config_get_item_type(existing) != NVS_TYPE_STR ) {
|
||||
ESP_LOGW(TAG, "Storing numeric value from string");
|
||||
numvalue = atof((char *)value);
|
||||
|
||||
@@ -40,7 +40,8 @@ const __attribute__((section(".rodata_desc"))) esp_app_desc_t esp_app_desc = {
|
||||
#endif
|
||||
};
|
||||
|
||||
extern int main(int argc, char **argv);
|
||||
extern int squeezelite_main(int argc, char **argv);
|
||||
|
||||
static int launchsqueezelite(int argc, char **argv);
|
||||
|
||||
/** Arguments used by 'squeezelite' function */
|
||||
@@ -54,39 +55,32 @@ static struct {
|
||||
} thread_parms ;
|
||||
|
||||
#define ADDITIONAL_SQUEEZELITE_ARGS 5
|
||||
static void squeezelite_thread(void *arg){
|
||||
static void squeezelite_thread(void *arg){
|
||||
ESP_LOGV(TAG ,"Number of args received: %u",thread_parms.argc );
|
||||
ESP_LOGV(TAG ,"Values:");
|
||||
for(int i = 0;i<thread_parms.argc; i++){
|
||||
ESP_LOGV(TAG ," %s",thread_parms.argv[i]);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG ,"Calling squeezelite");
|
||||
int ret = main(thread_parms.argc,thread_parms.argv);
|
||||
ESP_LOGV(TAG ,"Exited from squeezelite's main(). Freeing argv structure.");
|
||||
|
||||
for(int i=0;i<thread_parms.argc;i++){
|
||||
ESP_LOGV(TAG ,"Freeing char buffer for parameter %u", i+1);
|
||||
free(thread_parms.argv[i]);
|
||||
}
|
||||
ESP_LOGV(TAG ,"Freeing argv pointer");
|
||||
free(thread_parms.argv);
|
||||
|
||||
if(!wait_for_commit()){
|
||||
ESP_LOGW(TAG,"Unable to commit configuration. ");
|
||||
}
|
||||
|
||||
messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "squeezelite exited with error code %d", ret);
|
||||
ESP_LOGI(TAG ,"Calling squeezelite");
|
||||
int ret = squeezelite_main(thread_parms.argc, thread_parms.argv);
|
||||
|
||||
cmd_send_messaging("cfg-audio-tmpl",ret > 1 ? MESSAGING_ERROR : MESSAGING_WARNING,"squeezelite exited with error code %d\n", ret);
|
||||
|
||||
if (ret == 1) {
|
||||
int wait = 60;
|
||||
messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "Rebooting in %d sec", wait);
|
||||
wait_for_commit();
|
||||
cmd_send_messaging("cfg-audio-tmpl",MESSAGING_ERROR,"Rebooting in %d sec\n", wait);
|
||||
vTaskDelay( pdMS_TO_TICKS(wait * 1000));
|
||||
esp_restart();
|
||||
} else {
|
||||
messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "Correct command line and reboot");
|
||||
cmd_send_messaging("cfg-audio-tmpl",MESSAGING_ERROR,"Correct command line and reboot\n");
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "Exited from squeezelite's main(). Freeing argv structure.");
|
||||
|
||||
for(int i=0;i<thread_parms.argc;i++) free(thread_parms.argv[i]);
|
||||
free(thread_parms.argv);
|
||||
}
|
||||
|
||||
static int launchsqueezelite(int argc, char **argv) {
|
||||
|
||||
@@ -50,6 +50,7 @@ static const dmap_field dmap_fields[] = {
|
||||
{ "abar", DMAP_DICT, DMAP_STR, "daap.browseartistlisting" },
|
||||
{ "abcp", DMAP_DICT, DMAP_STR, "daap.browsecomposerlisting" },
|
||||
{ "abgn", DMAP_DICT, DMAP_STR, "daap.browsegenrelisting" },
|
||||
#ifdef DMAP_FULL
|
||||
{ "abpl", DMAP_UINT, 0, "daap.baseplaylist" },
|
||||
{ "abro", DMAP_DICT, 0, "daap.databasebrowse" },
|
||||
{ "adbs", DMAP_DICT, 0, "daap.databasesongs" },
|
||||
@@ -256,10 +257,12 @@ static const dmap_field dmap_fields[] = {
|
||||
{ "meia", DMAP_UINT, 0, "dmap.itemdateadded" },
|
||||
{ "meip", DMAP_UINT, 0, "dmap.itemdateplayed" },
|
||||
{ "mext", DMAP_UINT, 0, "dmap.objectextradata" },
|
||||
#endif
|
||||
{ "miid", DMAP_UINT, 0, "dmap.itemid" },
|
||||
{ "mikd", DMAP_UINT, 0, "dmap.itemkind" },
|
||||
{ "mimc", DMAP_UINT, 0, "dmap.itemcount" },
|
||||
{ "minm", DMAP_STR, 0, "dmap.itemname" },
|
||||
#ifdef DMAP_FULL
|
||||
{ "mlcl", DMAP_DICT, DMAP_DICT, "dmap.listing" },
|
||||
{ "mlid", DMAP_UINT, 0, "dmap.sessionid" },
|
||||
{ "mlit", DMAP_ITEM, 0, "dmap.listingitem" },
|
||||
@@ -314,6 +317,7 @@ static const dmap_field dmap_fields[] = {
|
||||
{ "prat", DMAP_UINT, 0, "dpap.imagerating" },
|
||||
{ "pret", DMAP_DICT, 0, "dpap.retryids" },
|
||||
{ "pwth", DMAP_UINT, 0, "dpap.imagepixelwidth" }
|
||||
#endif
|
||||
};
|
||||
static const size_t dmap_field_count = sizeof(dmap_fields) / sizeof(dmap_field);
|
||||
|
||||
|
||||
@@ -959,7 +959,7 @@ static int base64_decode(const char *str, void *data)
|
||||
*q++ = (val >> 8) & 0xff;
|
||||
if (marker < 1)
|
||||
*q++ = val & 0xff;
|
||||
}
|
||||
}
|
||||
return q - (unsigned char *) data;
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ const static actrls_t controls = {
|
||||
NULL, NULL, // rew, fwd
|
||||
raop_prev, raop_next, // prev, next
|
||||
NULL, NULL, NULL, NULL, // left, right, up, down
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, // pre1-6
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // pre1-10
|
||||
raop_volume_down, raop_volume_up, raop_toggle// knob left, knob_right, knob push
|
||||
};
|
||||
|
||||
|
||||
@@ -71,7 +71,8 @@ static log_level *loglevel = &raop_loglevel;
|
||||
//#define __RTP_STORE
|
||||
|
||||
// default buffer size
|
||||
#define BUFFER_FRAMES ( (150 * RAOP_SAMPLE_RATE * 2) / (352 * 100) )
|
||||
#define BUFFER_FRAMES_MAX ((RAOP_SAMPLE_RATE * 10) / 352 )
|
||||
#define BUFFER_FRAMES_MIN ( (150 * RAOP_SAMPLE_RATE * 2) / (352 * 100) )
|
||||
#define MAX_PACKET 1408
|
||||
#define MIN_LATENCY 11025
|
||||
#define MAX_LATENCY ( (120 * RAOP_SAMPLE_RATE * 2) / 100 )
|
||||
@@ -86,14 +87,15 @@ static log_level *loglevel = &raop_loglevel;
|
||||
enum { DATA = 0, CONTROL, TIMING };
|
||||
|
||||
static const u8_t silence_frame[MAX_PACKET] = { 0 };
|
||||
uint32_t buffer_frames = ((150 * RAOP_SAMPLE_RATE * 2) / (352 * 100));
|
||||
|
||||
typedef u16_t seq_t;
|
||||
typedef struct audio_buffer_entry { // decoded audio packets
|
||||
int ready;
|
||||
typedef struct __attribute__((__packed__)) audio_buffer_entry { // decoded audio packets
|
||||
u32_t rtptime, last_resend;
|
||||
s16_t *data;
|
||||
int len;
|
||||
bool allocated;
|
||||
u16_t len;
|
||||
u8_t ready;
|
||||
u8_t allocated;
|
||||
} abuf_t;
|
||||
|
||||
typedef struct rtp_s {
|
||||
@@ -133,7 +135,7 @@ typedef struct rtp_s {
|
||||
u32_t resent_req, resent_rec; // total resent + recovered frames
|
||||
u32_t silent_frames; // total silence frames
|
||||
u32_t discarded;
|
||||
abuf_t audio_buffer[BUFFER_FRAMES];
|
||||
abuf_t audio_buffer[BUFFER_FRAMES_MAX];
|
||||
seq_t ab_read, ab_write;
|
||||
pthread_mutex_t ab_mutex;
|
||||
#ifdef WIN32
|
||||
@@ -152,7 +154,7 @@ typedef struct rtp_s {
|
||||
} rtp_t;
|
||||
|
||||
|
||||
#define BUFIDX(seqno) ((seq_t)(seqno) % BUFFER_FRAMES)
|
||||
#define BUFIDX(seqno) ((seq_t)(seqno) % buffer_frames)
|
||||
static void buffer_alloc(abuf_t *audio_buffer, int size, uint8_t *buf, size_t buf_size);
|
||||
static void buffer_release(abuf_t *audio_buffer);
|
||||
static void buffer_reset(abuf_t *audio_buffer);
|
||||
@@ -373,25 +375,27 @@ void rtp_record(rtp_t *ctx, unsigned short seqno, unsigned rtptime) {
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void buffer_alloc(abuf_t *audio_buffer, int size, uint8_t *buf, size_t buf_size) {
|
||||
int i;
|
||||
for (i = 0; i < BUFFER_FRAMES; i++) {
|
||||
if (buf && buf_size >= size) {
|
||||
audio_buffer[i].data = (s16_t*) buf;
|
||||
audio_buffer[i].allocated = false;
|
||||
buf += size;
|
||||
buf_size -= size;
|
||||
} else {
|
||||
audio_buffer[i].allocated = true;
|
||||
audio_buffer[i].data = malloc(size);
|
||||
}
|
||||
audio_buffer[i].ready = 0;
|
||||
for (buffer_frames = 0; buf && buf_size >= size && buffer_frames < BUFFER_FRAMES_MAX; buffer_frames++) {
|
||||
audio_buffer[buffer_frames].data = (s16_t*) buf;
|
||||
audio_buffer[buffer_frames].allocated = 0;
|
||||
audio_buffer[buffer_frames].ready = 0;
|
||||
buf += size;
|
||||
buf_size -= size;
|
||||
}
|
||||
|
||||
LOG_INFO("allocated %d buffers (min=%d) from buffer of %zu bytes", buffer_frames, BUFFER_FRAMES_MIN, buf_size + buffer_frames * size);
|
||||
|
||||
for(; buffer_frames < BUFFER_FRAMES_MIN; buffer_frames++) {
|
||||
audio_buffer[buffer_frames].data = malloc(size);
|
||||
audio_buffer[buffer_frames].allocated = 1;
|
||||
audio_buffer[buffer_frames].ready = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void buffer_release(abuf_t *audio_buffer) {
|
||||
int i;
|
||||
for (i = 0; i < BUFFER_FRAMES; i++) {
|
||||
for (i = 0; i < buffer_frames; i++) {
|
||||
if (audio_buffer[i].allocated) free(audio_buffer[i].data);
|
||||
}
|
||||
}
|
||||
@@ -399,7 +403,7 @@ static void buffer_release(abuf_t *audio_buffer) {
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void buffer_reset(abuf_t *audio_buffer) {
|
||||
int i;
|
||||
for (i = 0; i < BUFFER_FRAMES; i++) audio_buffer[i].ready = 0;
|
||||
for (i = 0; i < buffer_frames; i++) audio_buffer[i].ready = 0;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@@ -411,7 +415,7 @@ static int seq_order(seq_t a, seq_t b) {
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void alac_decode(rtp_t *ctx, s16_t *dest, char *buf, int len, int *outsize) {
|
||||
static void alac_decode(rtp_t *ctx, s16_t *dest, char *buf, int len, u16_t *outsize) {
|
||||
unsigned char iv[16];
|
||||
int aeslen;
|
||||
assert(len<=MAX_PACKET);
|
||||
@@ -803,7 +807,7 @@ static bool rtp_request_resend(rtp_t *ctx, seq_t first, seq_t last) {
|
||||
static bool rtp_request_resend(rtp_t *ctx, seq_t first, seq_t last) {
|
||||
unsigned char req[8]; // *not* a standard RTCP NACK
|
||||
|
||||
// do not request silly ranges (happens in case of network large blackouts)
|
||||
// do not request silly ranges (happens in case of network large blackouts)
|
||||
if (seq_order(last, first) || last - first > buffer_frames / 2) return false;
|
||||
|
||||
ctx->resent_req += (seq_t) (last - first) + 1;
|
||||
|
||||
@@ -60,7 +60,7 @@ static const actrls_config_map_t actrls_config_map[] =
|
||||
static const char * actrls_action_s[ ] = { EP(ACTRLS_POWER),EP(ACTRLS_VOLUP),EP(ACTRLS_VOLDOWN),EP(ACTRLS_TOGGLE),EP(ACTRLS_PLAY),
|
||||
EP(ACTRLS_PAUSE),EP(ACTRLS_STOP),EP(ACTRLS_REW),EP(ACTRLS_FWD),EP(ACTRLS_PREV),EP(ACTRLS_NEXT),
|
||||
EP(BCTRLS_UP),EP(BCTRLS_DOWN),EP(BCTRLS_LEFT),EP(BCTRLS_RIGHT),
|
||||
EP(BCTRLS_PS1),EP(BCTRLS_PS2),EP(BCTRLS_PS3),EP(BCTRLS_PS4),EP(BCTRLS_PS5),EP(BCTRLS_PS6),
|
||||
EP(BCTRLS_PS0),EP(BCTRLS_PS1),EP(BCTRLS_PS2),EP(BCTRLS_PS3),EP(BCTRLS_PS4),EP(BCTRLS_PS5),EP(BCTRLS_PS6),EP(BCTRLS_PS7),EP(BCTRLS_PS8),EP(BCTRLS_PS9),
|
||||
EP(KNOB_LEFT),EP(KNOB_RIGHT),EP(KNOB_PUSH),
|
||||
""} ;
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
typedef enum { ACTRLS_NONE = -1, ACTRLS_POWER,ACTRLS_VOLUP, ACTRLS_VOLDOWN, ACTRLS_TOGGLE, ACTRLS_PLAY,
|
||||
ACTRLS_PAUSE, ACTRLS_STOP, ACTRLS_REW, ACTRLS_FWD, ACTRLS_PREV, ACTRLS_NEXT,
|
||||
BCTRLS_UP, BCTRLS_DOWN, BCTRLS_LEFT, BCTRLS_RIGHT,
|
||||
BCTRLS_PS1,BCTRLS_PS2,BCTRLS_PS3,BCTRLS_PS4,BCTRLS_PS5,BCTRLS_PS6,
|
||||
BCTRLS_PS0,BCTRLS_PS1,BCTRLS_PS2,BCTRLS_PS3,BCTRLS_PS4,BCTRLS_PS5,BCTRLS_PS6,BCTRLS_PS7,BCTRLS_PS8,BCTRLS_PS9,
|
||||
KNOB_LEFT, KNOB_RIGHT, KNOB_PUSH,
|
||||
ACTRLS_REMAP, ACTRLS_MAX
|
||||
} actrls_action_e;
|
||||
|
||||
@@ -219,18 +219,23 @@ esp_err_t messaging_post_to_queue(messaging_handle_t subscriber_handle, single_m
|
||||
}
|
||||
return ESP_LOG_DEBUG;
|
||||
}
|
||||
|
||||
void messaging_post_message(messaging_types type,messaging_classes msg_class, const char *fmt, ...){
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
vmessaging_post_message(type, msg_class, fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void vmessaging_post_message(messaging_types type,messaging_classes msg_class, const char *fmt, va_list va){
|
||||
single_message_t * message=NULL;
|
||||
size_t msg_size=0;
|
||||
size_t ln =0;
|
||||
messaging_list_t * cur=⊤
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
ln = vsnprintf(NULL, 0, fmt, va)+1;
|
||||
msg_size = sizeof(single_message_t)+ln;
|
||||
message = (single_message_t *)malloc_init_external(msg_size);
|
||||
vsprintf(message->message, fmt, va);
|
||||
va_end(va);
|
||||
message->msg_size = msg_size;
|
||||
message->type = type;
|
||||
message->msg_class = msg_class;
|
||||
|
||||
@@ -34,6 +34,7 @@ cJSON * messaging_retrieve_messages(RingbufHandle_t buf_handle);
|
||||
messaging_handle_t messaging_register_subscriber(uint8_t max_count, char * name);
|
||||
esp_err_t messaging_post_to_queue(messaging_handle_t subscriber_handle, single_message_t * message, size_t message_size);
|
||||
void messaging_post_message(messaging_types type,messaging_classes msg_class, const char * fmt, ...);
|
||||
void vmessaging_post_message(messaging_types type,messaging_classes msg_class, const char *fmt, va_list va);
|
||||
cJSON * messaging_retrieve_messages(RingbufHandle_t buf_handle);
|
||||
single_message_t * messaging_retrieve_message(RingbufHandle_t buf_handle);
|
||||
void log_send_messaging(messaging_types msgtype,const char *fmt, ...);
|
||||
|
||||
@@ -443,11 +443,11 @@ void cspotPlayer::runTask() {
|
||||
CSPOT_LOG(info, "disconnecting player %s", name.c_str());
|
||||
}
|
||||
|
||||
// we want to release memory ASAP and fore sure
|
||||
// we want to release memory ASAP and for sure
|
||||
centralAudioBuffer.reset();
|
||||
ctx.reset();
|
||||
token.clear();
|
||||
|
||||
|
||||
// update volume when we disconnect
|
||||
cJSON *config = config_alloc_get_cjson("cspot_config");
|
||||
cJSON_DeleteItemFromObject(config, "volume");
|
||||
|
||||
@@ -120,9 +120,9 @@ void MercurySession::handlePacket() {
|
||||
switch (static_cast<RequestType>(packet.command)) {
|
||||
case RequestType::COUNTRY_CODE_RESPONSE: {
|
||||
this->countryCode = std::string();
|
||||
this->countryCode.reserve(2);
|
||||
this->countryCode.resize(2);
|
||||
memcpy(this->countryCode.data(), packet.data.data(), 2);
|
||||
CSPOT_LOG(debug, "Received country code");
|
||||
CSPOT_LOG(debug, "Received country code %s", this->countryCode.c_str());
|
||||
break;
|
||||
}
|
||||
case RequestType::AUDIO_KEY_FAILURE_RESPONSE:
|
||||
|
||||
@@ -77,12 +77,11 @@ void TrackProvider::onMetadataResponse(MercurySession::Response& res) {
|
||||
|
||||
std::vector<uint8_t> trackId;
|
||||
std::vector<uint8_t> fileId;
|
||||
AudioFormat format = AudioFormat_OGG_VORBIS_160;
|
||||
|
||||
|
||||
if (altIndex < 0) {
|
||||
trackId = pbArrayToVector(trackInfo.gid);
|
||||
for (int x = 0; x < trackInfo.file_count; x++) {
|
||||
if (trackInfo.file[x].format == format) {
|
||||
if (trackInfo.file[x].format == ctx->config.audioFormat) {
|
||||
fileId = pbArrayToVector(trackInfo.file[x].file_id);
|
||||
break; // If file found stop searching
|
||||
}
|
||||
@@ -90,7 +89,7 @@ void TrackProvider::onMetadataResponse(MercurySession::Response& res) {
|
||||
} else {
|
||||
trackId = pbArrayToVector(trackInfo.alternative[altIndex].gid);
|
||||
for (int x = 0; x < trackInfo.alternative[altIndex].file_count; x++) {
|
||||
if (trackInfo.alternative[altIndex].file[x].format == format) {
|
||||
if (trackInfo.alternative[altIndex].file[x].format == ctx->config.audioFormat) {
|
||||
fileId =
|
||||
pbArrayToVector(trackInfo.alternative[altIndex].file[x].file_id);
|
||||
break; // If file found stop searching
|
||||
|
||||
@@ -85,7 +85,7 @@ const static actrls_t controls = {
|
||||
NULL, NULL, // rew, fwd
|
||||
cspot_prev, cspot_next, // prev, next
|
||||
NULL, NULL, NULL, NULL, // left, right, up, down
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, // pre1-6
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // pre1-10
|
||||
cspot_volume_down, cspot_volume_up, cspot_toggle// knob left, knob_right, knob push
|
||||
};
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ idf_component_register( SRC_DIRS . external ac101 tas57xx wm8978
|
||||
display
|
||||
tools
|
||||
audio
|
||||
_override
|
||||
EMBED_FILES vu_s.data arrow.data
|
||||
)
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@ static log_level loglevel = lINFO;
|
||||
enum { BUTN_POWER_FRONT = 0X0A, BUTN_ARROW_UP, BUTN_ARROW_DOWN, BUTN_ARROW_LEFT, BUTN_KNOB_PUSH, BUTN_SEARCH,
|
||||
BUTN_REW, BUTN_FWD, BUTN_PLAY, BUTN_ADD, BUTN_BRIGHTNESS, BUTN_NOW_PLAYING,
|
||||
BUTN_PAUSE = 0X17, BUTN_BROWSE, BUTN_VOLUP_FRONT, BUTN_VOLDOWN_FRONT, BUTN_SIZE, BUTN_VISUAL, BUTN_VOLUMEMODE,
|
||||
BUTN_PRESET_1 = 0X23, BUTN_PRESET_2, BUTN_PRESET_3, BUTN_PRESET_4, BUTN_PRESET_5, BUTN_PRESET_6, BUTN_SNOOZE,
|
||||
BUTN_PRESET_0 = 0x22, BUTN_PRESET_1, BUTN_PRESET_2, BUTN_PRESET_3, BUTN_PRESET_4, BUTN_PRESET_5, BUTN_PRESET_6, BUTN_PRESET_7, BUTN_PRESET_8, BUTN_PRESET_9,
|
||||
BUTN_SNOOZE,
|
||||
BUTN_KNOB_LEFT = 0X5A, BUTN_KNOB_RIGHT };
|
||||
|
||||
#define BUTN_ARROW_RIGHT BUTN_KNOB_PUSH
|
||||
@@ -142,12 +143,16 @@ LMS_CALLBACK(down, ARROW_DOWN, arrow_down)
|
||||
LMS_CALLBACK(left, ARROW_LEFT, arrow_left)
|
||||
LMS_CALLBACK(right, ARROW_RIGHT, arrow_right)
|
||||
|
||||
LMS_CALLBACK(pre0, PRESET_0, preset_0.single)
|
||||
LMS_CALLBACK(pre1, PRESET_1, preset_1.single)
|
||||
LMS_CALLBACK(pre2, PRESET_2, preset_2.single)
|
||||
LMS_CALLBACK(pre3, PRESET_3, preset_3.single)
|
||||
LMS_CALLBACK(pre4, PRESET_4, preset_4.single)
|
||||
LMS_CALLBACK(pre5, PRESET_5, preset_5.single)
|
||||
LMS_CALLBACK(pre6, PRESET_6, preset_6.single)
|
||||
LMS_CALLBACK(pre7, PRESET_7, preset_7.single)
|
||||
LMS_CALLBACK(pre8, PRESET_8, preset_8.single)
|
||||
LMS_CALLBACK(pre9, PRESET_9, preset_9.single)
|
||||
|
||||
LMS_CALLBACK(knob_left, KNOB_LEFT, knob_left)
|
||||
LMS_CALLBACK(knob_right, KNOB_RIGHT, knob_right)
|
||||
@@ -162,7 +167,7 @@ const actrls_t LMS_controls = {
|
||||
lms_prev, lms_next, // prev, next
|
||||
lms_up, lms_down,
|
||||
lms_left, lms_right,
|
||||
lms_pre1, lms_pre2, lms_pre3, lms_pre4, lms_pre5, lms_pre6,
|
||||
lms_pre0, lms_pre1, lms_pre2, lms_pre3, lms_pre4, lms_pre5, lms_pre6, lms_pre7, lms_pre8, lms_pre9,
|
||||
lms_knob_left, lms_knob_right, lms_knob_push,
|
||||
};
|
||||
|
||||
|
||||
561
components/squeezelite/cs4265/cs4265.c
Normal file
561
components/squeezelite/cs4265/cs4265.c
Normal file
@@ -0,0 +1,561 @@
|
||||
/*
|
||||
* Squeezelite for esp32
|
||||
*
|
||||
* (c) Sebastien 2019
|
||||
* Philippe G. 2019, philippe_44@outlook.com
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
//#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/i2s.h"
|
||||
#include "driver/i2c.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "adac.h"
|
||||
#include "stdio.h"
|
||||
#include "math.h"
|
||||
#define CS4265_PULL_UP (0x4F )
|
||||
#define CS4265_PULL_DOWN (0x4E )
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
static const char TAG[] = "CS4265";
|
||||
|
||||
static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config);
|
||||
static void speaker(bool active);
|
||||
static void headset(bool active);
|
||||
static bool volume(unsigned left, unsigned right);
|
||||
static void power(adac_power_e mode);
|
||||
static esp_err_t cs4265_update_bit(uint8_t reg_no,uint8_t mask,uint8_t val );
|
||||
static esp_err_t set_clock();
|
||||
const struct adac_s dac_cs4265 = { "CS4265", init, adac_deinit, power, speaker, headset, volume };
|
||||
|
||||
struct cs4265_cmd_s {
|
||||
uint8_t reg;
|
||||
uint8_t value;
|
||||
};
|
||||
struct cs4265_private {
|
||||
uint8_t format;
|
||||
uint32_t sysclk;
|
||||
i2s_config_t *i2s_config;
|
||||
int i2c_port;
|
||||
};
|
||||
struct cs4265_private cs4265;
|
||||
|
||||
#define CS4265_CHIP_ID 0x1
|
||||
#define CS4265_CHIP_ID_VAL 0xD0
|
||||
#define CS4265_CHIP_ID_MASK 0xF0
|
||||
#define CS4265_REV_ID_MASK 0x0F
|
||||
|
||||
#define CS4265_PWRCTL 0x02
|
||||
#define CS4265_PWRCTL_PDN (1 << 0)
|
||||
#define CS4265_PWRCTL_PDN_DAC (1 << 1)
|
||||
#define CS4265_PWRCTL_PDN_ADC (1 << 2)
|
||||
#define CS4265_PWRCTL_PDN_MIC (1 << 3)
|
||||
#define CS4265_PWRCTL_FREEZE (1 << 7)
|
||||
#define CS4265_PWRCTL_PDN_ALL CS4265_PWRCTL_PDN | CS4265_PWRCTL_PDN_ADC | CS4265_PWRCTL_PDN_DAC | CS4265_PWRCTL_PDN_MIC
|
||||
|
||||
|
||||
|
||||
#define CS4265_DAC_CTL 0x3
|
||||
// De-Emphasis Control (Bit 1)
|
||||
// The standard 50/15 i2s digital de-emphasis filter response may be implemented for a sample
|
||||
// rate of 44.1 kHz when the DeEmph bit is set. NOTE: De-emphasis is available only in Single-Speed Mode.
|
||||
#define CS4265_DAC_CTL_DEEMPH (1 << 1)
|
||||
// MUTE DAC
|
||||
// The DAC outputs will mute and the MUTEC pin will become active when this bit is set. Though this bit is
|
||||
// active high, it should be noted that the MUTEC pin is active low. The common mode voltage on the outputs
|
||||
// will be retained when this bit is set. The muting function is effected, similar to attenuation changes, by the
|
||||
// DACSoft and DACZero bits in the DAC Control 2 register.
|
||||
#define CS4265_DAC_CTL_MUTE (1 << 2)
|
||||
// The required relationship between LRCK, SCLK and SDIN for the DAC is defined by the DAC Digital Interface
|
||||
// DAC_DIF1 DAC_DIF0 Description Format Figure
|
||||
// 0 0 Left Justified, up to 24-bit data (default) 0 5
|
||||
// 0 1 I²S, up to 24-bit data 1 6
|
||||
// 1 0 Right-Justified, 16-bit Data 2 7
|
||||
// 1 1 Right-Justified, 24-bit Data 3 7
|
||||
#define CS4265_DAC_CTL_DIF0 (1 << 4)
|
||||
// The required relationship between LRCK, SCLK and SDIN for the DAC is defined by the DAC Digital Interface
|
||||
// DAC_DIF1 DAC_DIF0 Description Format Figure
|
||||
// 0 0 Left Justified, up to 24-bit data (default) 0 5
|
||||
// 0 1 I²S, up to 24-bit data 1 6
|
||||
// 1 0 Right-Justified, 16-bit Data 2 7
|
||||
// 1 1 Right-Justified, 24-bit Data 3 7
|
||||
#define CS4265_DAC_CTL_DIF1 (1 << 5)
|
||||
|
||||
|
||||
|
||||
#define CS4265_ADC_CTL 0x4
|
||||
#define CS4265_ADC_MASTER 1
|
||||
|
||||
#define CS4265_ADC_CTL_MUTE (1 << 2)
|
||||
#define CS4265_ADC_DIF (1 << 4)
|
||||
#define CS4265_ADC_FM (3 << 6)
|
||||
|
||||
//Master Clock Dividers (Bits 6:4)
|
||||
//Sets the frequency of the supplied MCLK signal.
|
||||
//
|
||||
//MCLK Divider MCLK Freq2 MCLK Freq1 MCLK Freq0
|
||||
// ÷ 1 0 0 0
|
||||
// ÷ 1.5 0 0 1
|
||||
// ÷ 2 0 1 0
|
||||
// ÷ 3 0 1 1
|
||||
// ÷ 4 1 0 0
|
||||
// NA 1 0 1
|
||||
// NA 1 1 x
|
||||
#define CS4265_MCLK_FREQ 0x5
|
||||
#define CS4265_MCLK_FREQ_1_0X (0b000<<4 )
|
||||
#define CS4265_MCLK_FREQ_1_5X (0b001<<4 )
|
||||
#define CS4265_MCLK_FREQ_2_0X (0b010<<4 )
|
||||
#define CS4265_MCLK_FREQ_3_0X (0b011<<4 )
|
||||
#define CS4265_MCLK_FREQ_4_0X (0b100<<4 )
|
||||
|
||||
|
||||
#define CS4265_MCLK_FREQ_MASK (7 << 4)
|
||||
|
||||
#define CS4265_SIG_SEL 0x6
|
||||
#define CS4265_SIG_SEL_LOOP (1 << 1)
|
||||
#define CS4265_SIG_SEL_SDIN2 (1 << 7)
|
||||
#define CS4265_SIG_SEL_SDIN1 (0 << 7)
|
||||
|
||||
// Sets the gain or attenuation for the ADC input PGA stage. The gain may be adjusted from -12 dB to
|
||||
// +12 dB in 0.5 dB steps. The gain bits are in two’s complement with the Gain0 bit set for a 0.5 dB step.
|
||||
// Register settings outside of the ±12 dB range are reserved and must not be used. See Table 13 for example settings
|
||||
#define CS4265_CHB_PGA_CTL 0x7
|
||||
// Sets the gain or attenuation for the ADC input PGA stage. The gain may be adjusted from -12 dB to
|
||||
// +12 dB in 0.5 dB steps. The gain bits are in two’s complement with the Gain0 bit set for a 0.5 dB step.
|
||||
// Register settings outside of the ±12 dB range are reserved and must not be used. See Table 13 for example settings
|
||||
#define CS4265_CHA_PGA_CTL 0x8
|
||||
// Gain[5:0] Setting
|
||||
// 101000 -12 dB
|
||||
// 000000 0 dB
|
||||
// 011000 +12 dB
|
||||
|
||||
|
||||
#define CS4265_ADC_CTL2 0x9
|
||||
|
||||
// The digital volume control allows the user to attenuate the signal in 0.5 dB increments from 0 to -127 dB.
|
||||
// The Vol0 bit activates a 0.5 dB attenuation when set, and no attenuation when cleared. The Vol[7:1] bits
|
||||
// activate attenuation equal to their decimal equivalent (in dB).
|
||||
//Binary Code Volume Setting
|
||||
//00000000 0 dB
|
||||
//00000001 -0.5 dB
|
||||
//00101000 -20 dB
|
||||
//00101001 -20.5 dB
|
||||
//11111110 -127 dB
|
||||
//11111111 -127.5 dB
|
||||
#define CS4265_DAC_CHA_VOL 0xA
|
||||
// The digital volume control allows the user to attenuate the signal in 0.5 dB increments from 0 to -127 dB.
|
||||
// The Vol0 bit activates a 0.5 dB attenuation when set, and no attenuation when cleared. The Vol[7:1] bits
|
||||
// activate attenuation equal to their decimal equivalent (in dB).
|
||||
//Binary Code Volume Setting
|
||||
//00000000 0 dB
|
||||
//00000001 -0.5 dB
|
||||
//00101000 -20 dB
|
||||
//00101001 -20.5 dB
|
||||
//11111110 -127 dB
|
||||
//11111111 -127.5 dB
|
||||
#define CS4265_DAC_CHB_VOL 0xB
|
||||
#define CS4265_DAC_VOL_ATT_000_0 0b00000000
|
||||
#define CS4265_DAC_VOL_ATT_000_5 0b00000001
|
||||
#define CS4265_DAC_VOL_ATT_020_0 0b00101000
|
||||
#define CS4265_DAC_VOL_ATT_020_5 0b00101001
|
||||
#define CS4265_DAC_VOL_ATT_127_0 0b11111110
|
||||
#define CS4265_DAC_VOL_ATT_127_5 0b11111111
|
||||
|
||||
// DAC Soft Ramp or Zero Cross Enable (Bits 7:6)
|
||||
//
|
||||
// Soft Ramp Enable
|
||||
// Soft Ramp allows level changes, both muting and attenuation, to be implemented by incrementally ramping, in 1/8 dB steps, from the current level to the new level at a rate of 1 dB per 8 left/right clock periods.
|
||||
// See Table 17.
|
||||
// Zero Cross Enable
|
||||
// Zero Cross Enable dictates that signal-level changes, either by attenuation changes or muting, will occur
|
||||
// on a signal zero crossing to minimize audible artifacts. The requested level change will occur after a timeout period between 512 and 1024 sample periods (10.7 ms to 21.3 ms at 48 kHz sample rate) if the signal
|
||||
// does not encounter a zero crossing. The zero cross function is independently monitored and implemented
|
||||
// for each channel. See Table 17.
|
||||
// Soft Ramp and Zero Cross Enable
|
||||
// Soft Ramp and Zero Cross Enable dictate that signal-level changes, either by attenuation changes or muting, will occur in 1/8 dB steps and be implemented on a signal zero crossing. The 1/8 dB level change will
|
||||
// occur after a time-out period between 512 and 1024 sample periods (10.7 ms to 21.3 ms at 48 kHz sample rate) if the signal does not encounter a zero crossing. The zero cross function is independently monitored and implemented for each channel
|
||||
// DACSoft DACZeroCross Mode
|
||||
// 0 0 Changes to affect immediately
|
||||
// 0 1 Zero Cross enabled
|
||||
// 1 0 Soft Ramp enabled
|
||||
// 1 1 Soft Ramp and Zero Cross enabled (default)
|
||||
#define CS4265_DAC_CTL2 0xC
|
||||
#define CS4265_DAC_CTL2_ZERO_CROSS_EN (uint8_t)(0b01 <<7)
|
||||
#define CS4265_DAC_CTL2_SOFT_RAMP_EN (uint8_t)(0b10 <<7)
|
||||
#define CS4265_DAC_CTL2_SOFT_RAMP_ZERO_CROSS_EN (uint8_t)(0b11 <<7)
|
||||
|
||||
|
||||
#define CS4265_INT_STATUS 0xD
|
||||
#define CS4265_INT_STATUS_ADC_UNDF (1<<0)
|
||||
#define CS4265_INT_STATUS_ADC_OVF (1<<1)
|
||||
#define CS4265_INT_STATUS_CLKERR (1<<3)
|
||||
|
||||
|
||||
#define CS4265_INT_MASK 0xE
|
||||
#define CS4265_STATUS_MODE_MSB 0xF
|
||||
#define CS4265_STATUS_MODE_LSB 0x10
|
||||
|
||||
//Transmitter Control 1 - Address 11h
|
||||
#define CS4265_SPDIF_CTL1 0x11
|
||||
|
||||
|
||||
|
||||
#define CS4265_SPDIF_CTL2 0x12
|
||||
// Transmitter Digital Interface Format (Bits 7:6)
|
||||
// Function:
|
||||
// The required relationship between LRCK, SCLK and SDIN for the transmitter is defined
|
||||
// Tx_DIF1 Tx_DIF0 Description Format Figure
|
||||
// 0 0 Left Justified, up to 24-bit data (default) 0 5
|
||||
// 0 1 I²S, up to 24-bit data 1 6
|
||||
// 1 0 Right-Justified, 16-bit Data 2 7
|
||||
// 1 1 Right-Justified, 24-bit Data 3 7
|
||||
#define CS4265_SPDIF_CTL2_MMTLR (1<<0)
|
||||
#define CS4265_SPDIF_CTL2_MMTCS (1<<1)
|
||||
#define CS4265_SPDIF_CTL2_MMT (1<<2)
|
||||
#define CS4265_SPDIF_CTL2_V (1<<3)
|
||||
#define CS4265_SPDIF_CTL2_TXMUTE (1<<4)
|
||||
#define CS4265_SPDIF_CTL2_TXOFF (1<<5)
|
||||
#define CS4265_SPDIF_CTL2_MUTE (1 << 4)
|
||||
#define CS4265_SPDIF_CTL2_DIF (3 << 6)
|
||||
#define CS4265_SPDIF_CTL2_DIF0 (1 << 6)
|
||||
#define CS4265_SPDIF_CTL2_DIF1 (1 << 7)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define CS4265_C_DATA_BUFF 0x13
|
||||
#define CS4265_MAX_REGISTER 0x2A
|
||||
struct cs4265_clk_para {
|
||||
uint32_t mclk;
|
||||
uint32_t rate;
|
||||
uint8_t fm_mode; /* values 1, 2, or 4 */
|
||||
uint8_t mclkdiv;
|
||||
};
|
||||
static const struct cs4265_clk_para clk_map_table[] = {
|
||||
/*32k*/
|
||||
{8192000, 32000, 0, 0},
|
||||
{12288000, 32000, 0, 1},
|
||||
{16384000, 32000, 0, 2},
|
||||
{24576000, 32000, 0, 3},
|
||||
{32768000, 32000, 0, 4},
|
||||
|
||||
/*44.1k*/
|
||||
{11289600, 44100, 0, 0},
|
||||
{16934400, 44100, 0, 1},
|
||||
{22579200, 44100, 0, 2},
|
||||
{33868000, 44100, 0, 3},
|
||||
{45158400, 44100, 0, 4},
|
||||
|
||||
/*48k*/
|
||||
{12288000, 48000, 0, 0},
|
||||
{18432000, 48000, 0, 1},
|
||||
{24576000, 48000, 0, 2},
|
||||
{36864000, 48000, 0, 3},
|
||||
{49152000, 48000, 0, 4},
|
||||
|
||||
/*64k*/
|
||||
{8192000, 64000, 1, 0},
|
||||
{12288000, 64000, 1, 1},
|
||||
{16934400, 64000, 1, 2},
|
||||
{24576000, 64000, 1, 3},
|
||||
{32768000, 64000, 1, 4},
|
||||
|
||||
/* 88.2k */
|
||||
{11289600, 88200, 1, 0},
|
||||
{16934400, 88200, 1, 1},
|
||||
{22579200, 88200, 1, 2},
|
||||
{33868000, 88200, 1, 3},
|
||||
{45158400, 88200, 1, 4},
|
||||
|
||||
/* 96k */
|
||||
{12288000, 96000, 1, 0},
|
||||
{18432000, 96000, 1, 1},
|
||||
{24576000, 96000, 1, 2},
|
||||
{36864000, 96000, 1, 3},
|
||||
{49152000, 96000, 1, 4},
|
||||
|
||||
/* 128k */
|
||||
{8192000, 128000, 2, 0},
|
||||
{12288000, 128000, 2, 1},
|
||||
{16934400, 128000, 2, 2},
|
||||
{24576000, 128000, 2, 3},
|
||||
{32768000, 128000, 2, 4},
|
||||
|
||||
/* 176.4k */
|
||||
{11289600, 176400, 2, 0},
|
||||
{16934400, 176400, 2, 1},
|
||||
{22579200, 176400, 2, 2},
|
||||
{33868000, 176400, 2, 3},
|
||||
{49152000, 176400, 2, 4},
|
||||
|
||||
/* 192k */
|
||||
{12288000, 192000, 2, 0},
|
||||
{18432000, 192000, 2, 1},
|
||||
{24576000, 192000, 2, 2},
|
||||
{36864000, 192000, 2, 3},
|
||||
{49152000, 192000, 2, 4},
|
||||
};
|
||||
static const struct cs4265_cmd_s cs4265_init_sequence[] = {
|
||||
{CS4265_PWRCTL, CS4265_PWRCTL_PDN_ADC | CS4265_PWRCTL_FREEZE | CS4265_PWRCTL_PDN_DAC | CS4265_PWRCTL_PDN_MIC},
|
||||
{CS4265_DAC_CTL, CS4265_DAC_CTL_DIF0 | CS4265_DAC_CTL_MUTE},
|
||||
{CS4265_SIG_SEL, CS4265_SIG_SEL_SDIN1},/// SDIN1
|
||||
{CS4265_SPDIF_CTL2, CS4265_SPDIF_CTL2_DIF0 },//
|
||||
{CS4265_ADC_CTL, 0x00 },// // Set the serial audio port in slave mode
|
||||
{CS4265_MCLK_FREQ, CS4265_MCLK_FREQ_1_0X },// // no divider
|
||||
{CS4265_CHB_PGA_CTL, 0x00 },// // sets the gain to 0db on channel B
|
||||
{CS4265_CHA_PGA_CTL, 0x00 },// // sets the gain to 0db on channel A
|
||||
{CS4265_ADC_CTL2, 0x19 },//
|
||||
{CS4265_DAC_CHA_VOL,CS4265_DAC_VOL_ATT_000_0 },// Full volume out
|
||||
{CS4265_DAC_CHB_VOL, CS4265_DAC_VOL_ATT_000_0 },// // Full volume out
|
||||
{CS4265_DAC_CTL2, CS4265_DAC_CTL2_SOFT_RAMP_ZERO_CROSS_EN },//
|
||||
{CS4265_SPDIF_CTL1, 0x00 },//
|
||||
{CS4265_INT_MASK, 0x00 },//
|
||||
{CS4265_STATUS_MODE_MSB, 0x00 },//
|
||||
{CS4265_STATUS_MODE_LSB, 0x00 },//
|
||||
{0xff,0xff}
|
||||
};
|
||||
|
||||
|
||||
// matching orders
|
||||
typedef enum { cs4265_ACTIVE = 0, cs4265_STANDBY, cs4265_DOWN, cs4265_ANALOGUE_OFF, cs4265_ANALOGUE_ON, cs4265_VOLUME } dac_cmd_e;
|
||||
|
||||
|
||||
|
||||
static int cs4265_addr;
|
||||
|
||||
static void dac_cmd(dac_cmd_e cmd, ...);
|
||||
static int cs4265_detect(void);
|
||||
static uint32_t calc_rnd_mclk_freq(){
|
||||
float m_scale = (cs4265.i2s_config->sample_rate > 96000 && cs4265.i2s_config->bits_per_sample > 16) ? 4 : 8;
|
||||
float num_channels = cs4265.i2s_config->channel_format < I2S_CHANNEL_FMT_ONLY_RIGHT ? 2 : 1;
|
||||
return (uint32_t) round(cs4265.i2s_config->bits_per_sample*i2s_get_clk(cs4265.i2c_port)* m_scale*num_channels/100)*100;
|
||||
}
|
||||
static int cs4265_get_clk_index(int mclk, int rate)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(clk_map_table); i++) {
|
||||
if (clk_map_table[i].rate == rate &&
|
||||
clk_map_table[i].mclk == mclk)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static esp_err_t set_clock(){
|
||||
esp_err_t err = ESP_OK;
|
||||
uint32_t mclk = calc_rnd_mclk_freq();
|
||||
int index = cs4265_get_clk_index(mclk,cs4265.i2s_config->sample_rate );
|
||||
if (index >= 0) {
|
||||
ESP_LOGD(TAG, "Setting clock for mclk %u, rate %u (fm mode:%u, clk div:%u))", mclk,cs4265.i2s_config->sample_rate,clk_map_table[index].fm_mode,clk_map_table[index].mclkdiv);
|
||||
err=cs4265_update_bit(CS4265_ADC_CTL,CS4265_ADC_FM, clk_map_table[index].fm_mode << 6);
|
||||
err|=cs4265_update_bit( CS4265_MCLK_FREQ,CS4265_MCLK_FREQ_MASK,clk_map_table[index].mclkdiv << 4);
|
||||
} else {
|
||||
ESP_LOGE(TAG,"can't get correct mclk for ");
|
||||
return -1;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static void get_status(){
|
||||
uint8_t sts1= adac_read_byte(cs4265_addr, CS4265_INT_STATUS);
|
||||
ESP_LOGD(TAG,"Status: %s",sts1&CS4265_INT_STATUS_CLKERR?"CLK Error":"CLK OK");
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* init
|
||||
*/
|
||||
static bool init(char *config, int i2c_port, i2s_config_t *i2s_config) {
|
||||
// find which TAS we are using (if any)
|
||||
cs4265_addr = adac_init(config, i2c_port);
|
||||
cs4265.i2s_config = i2s_config;
|
||||
cs4265.i2c_port=i2c_port;
|
||||
if (!cs4265_addr) cs4265_addr = cs4265_detect();
|
||||
if (!cs4265_addr) {
|
||||
ESP_LOGE(TAG, "No cs4265 detected");
|
||||
adac_deinit();
|
||||
return false;
|
||||
}
|
||||
#if BYTES_PER_FRAME == 8
|
||||
ESP_LOGE(TAG,"The CS4265 does not support 32 bits mode. ");
|
||||
adac_deinit();
|
||||
return false;
|
||||
#endif
|
||||
// configure MLK
|
||||
ESP_LOGD(TAG, "Configuring MCLK on GPIO0");
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1);
|
||||
REG_WRITE(PIN_CTRL, 0xFFFFFFF0);
|
||||
i2c_cmd_handle_t i2c_cmd = i2c_cmd_link_create();
|
||||
for (int i = 0; cs4265_init_sequence[i].reg != 0xff; i++) {
|
||||
i2c_master_start(i2c_cmd);
|
||||
i2c_master_write_byte(i2c_cmd, (cs4265_addr << 1) | I2C_MASTER_WRITE, I2C_MASTER_NACK);
|
||||
i2c_master_write_byte(i2c_cmd, cs4265_init_sequence[i].reg, I2C_MASTER_NACK);
|
||||
i2c_master_write_byte(i2c_cmd, cs4265_init_sequence[i].value, I2C_MASTER_NACK);
|
||||
ESP_LOGD(TAG, "i2c write %x at %u", cs4265_init_sequence[i].reg, cs4265_init_sequence[i].value);
|
||||
}
|
||||
|
||||
i2c_master_stop(i2c_cmd);
|
||||
esp_err_t res = i2c_master_cmd_begin(i2c_port, i2c_cmd, 500 / portTICK_RATE_MS);
|
||||
i2c_cmd_link_delete(i2c_cmd);
|
||||
|
||||
if (res != ESP_OK) {
|
||||
ESP_LOGE(TAG, "could not intialize cs4265 %d", res);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
static esp_err_t cs4265_update_bit(uint8_t reg_no,uint8_t mask,uint8_t val ){
|
||||
esp_err_t ret=ESP_OK;
|
||||
uint8_t old= adac_read_byte(cs4265_addr, reg_no);
|
||||
uint8_t newval = (old & ~mask) | (val & mask);
|
||||
bool change = old != newval;
|
||||
if (change){
|
||||
ret = adac_write_byte(cs4265_addr, reg_no, newval);
|
||||
if(ret != ESP_OK){
|
||||
ESP_LOGE(TAG,"Unable to change dac register 0x%02x [0x%02x->0x%02x] from value 0x%02x, mask 0x%02x ",reg_no,old,newval,val,mask);
|
||||
}
|
||||
else {
|
||||
ESP_LOGD(TAG,"Changed dac register 0x%02x [0x%02x->0x%02x] from value 0x%02x, mask 0x%02x ",reg_no,old,newval,val,mask);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* change volume
|
||||
*/
|
||||
static bool volume(unsigned left, unsigned right) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* power
|
||||
*/
|
||||
static void power(adac_power_e mode) {
|
||||
switch(mode) {
|
||||
case ADAC_STANDBY:
|
||||
dac_cmd(cs4265_STANDBY);
|
||||
break;
|
||||
case ADAC_ON:
|
||||
dac_cmd(cs4265_ACTIVE);
|
||||
break;
|
||||
case ADAC_OFF:
|
||||
dac_cmd(cs4265_DOWN);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGW(TAG, "unknown DAC command");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* speaker
|
||||
*/
|
||||
static void speaker(bool active) {
|
||||
if (active) dac_cmd(cs4265_ANALOGUE_ON);
|
||||
else dac_cmd(cs4265_ANALOGUE_OFF);
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* headset
|
||||
*/
|
||||
static void headset(bool active) { }
|
||||
|
||||
/****************************************************************************************
|
||||
* DAC specific commands
|
||||
*/
|
||||
void dac_cmd(dac_cmd_e cmd, ...) {
|
||||
va_list args;
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
va_start(args, cmd);
|
||||
|
||||
switch(cmd) {
|
||||
case cs4265_VOLUME:
|
||||
ESP_LOGE(TAG, "DAC volume not handled yet");
|
||||
break;
|
||||
case cs4265_ACTIVE:
|
||||
ESP_LOGD(TAG, "Activating DAC");
|
||||
adac_write_byte(cs4265_addr, CS4265_PWRCTL,0);
|
||||
cs4265_update_bit(CS4265_SPDIF_CTL2,CS4265_SPDIF_CTL2_TXOFF,0);
|
||||
cs4265_update_bit(CS4265_SPDIF_CTL2,CS4265_SPDIF_CTL2_TXMUTE,0);
|
||||
cs4265_update_bit(CS4265_DAC_CTL,CS4265_DAC_CTL_MUTE,0);
|
||||
break;
|
||||
case cs4265_STANDBY:
|
||||
ESP_LOGD(TAG, "DAC Stand-by");
|
||||
cs4265_update_bit(CS4265_SPDIF_CTL2,CS4265_SPDIF_CTL2_TXOFF,CS4265_SPDIF_CTL2_TXOFF);
|
||||
cs4265_update_bit(CS4265_SPDIF_CTL2,CS4265_SPDIF_CTL2_TXMUTE,CS4265_SPDIF_CTL2_TXMUTE);
|
||||
cs4265_update_bit(CS4265_DAC_CTL,CS4265_DAC_CTL_MUTE,CS4265_DAC_CTL_MUTE);
|
||||
break;
|
||||
case cs4265_DOWN:
|
||||
ESP_LOGD(TAG, "DAC Power Down");
|
||||
adac_write_byte(cs4265_addr, CS4265_PWRCTL,CS4265_PWRCTL_PDN_ALL);
|
||||
break;
|
||||
case cs4265_ANALOGUE_OFF:
|
||||
ESP_LOGD(TAG, "DAC Analog off");
|
||||
cs4265_update_bit(CS4265_SPDIF_CTL2,CS4265_SPDIF_CTL2_TXOFF,CS4265_SPDIF_CTL2_TXOFF);
|
||||
cs4265_update_bit(CS4265_SPDIF_CTL2,CS4265_SPDIF_CTL2_TXMUTE,CS4265_SPDIF_CTL2_TXMUTE);
|
||||
cs4265_update_bit(CS4265_DAC_CTL,CS4265_DAC_CTL_MUTE,CS4265_DAC_CTL_MUTE);
|
||||
break;
|
||||
case cs4265_ANALOGUE_ON:
|
||||
ESP_LOGD(TAG, "DAC Analog on");
|
||||
adac_write_byte(cs4265_addr, CS4265_PWRCTL,0);
|
||||
cs4265_update_bit(CS4265_SPDIF_CTL2,CS4265_SPDIF_CTL2_TXOFF,0);
|
||||
cs4265_update_bit(CS4265_SPDIF_CTL2,CS4265_SPDIF_CTL2_TXMUTE,0);
|
||||
cs4265_update_bit(CS4265_DAC_CTL,CS4265_DAC_CTL_MUTE,0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "could not use cs4265 %d", ret);
|
||||
}
|
||||
get_status();
|
||||
// now set the clock
|
||||
ret=set_clock(cs4265.i2s_config,cs4265.i2c_port);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "could not set the cs4265's clock %d", ret);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* TAS57 detection
|
||||
*/
|
||||
static int cs4265_detect(void) {
|
||||
uint8_t addr[] = {CS4265_PULL_DOWN,CS4265_PULL_UP};
|
||||
|
||||
for (int i = 0; i < sizeof(addr); i++) {
|
||||
ESP_LOGI(TAG,"Looking for CS4265 @0x%x",addr[i]);
|
||||
uint8_t reg=adac_read_byte(addr[i], CS4265_CHIP_ID);
|
||||
if(reg==255){
|
||||
continue;
|
||||
}
|
||||
// found a device at that address
|
||||
uint8_t devid = reg & CS4265_CHIP_ID_MASK;
|
||||
if (devid != CS4265_CHIP_ID_VAL) {
|
||||
ESP_LOGE(TAG,"CS4265 Device ID (%X). Expected %X",devid, CS4265_CHIP_ID);
|
||||
return 0;
|
||||
}
|
||||
ESP_LOGI(TAG,"Found DAC @0x%x, Version %x",addr[i], reg & CS4265_REV_ID_MASK);
|
||||
return addr[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -247,13 +247,17 @@ void decode_close(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void decode_flush(void) {
|
||||
void decode_flush(bool close) {
|
||||
LOG_INFO("decode flush");
|
||||
LOCK_D;
|
||||
decode.state = DECODE_STOPPED;
|
||||
IF_PROCESS(
|
||||
process_flush();
|
||||
);
|
||||
if (close && codec) {
|
||||
codec->close();
|
||||
codec = NULL;
|
||||
}
|
||||
UNLOCK_D;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ static bool bt_sink_cmd_handler(bt_sink_cmd_t cmd, va_list args)
|
||||
{
|
||||
// don't LOCK_O as there is always a chance that LMS takes control later anyway
|
||||
if (output.external != DECODE_BT && output.state > OUTPUT_STOPPED) {
|
||||
LOG_WARN("Cannot use BT sink while LMS/AirPlay/CSpot are controlling player");
|
||||
LOG_WARN("Cannot use BT sink while LMS/AirPlay/CSpot are controlling player %d", output.external);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ static bool raop_sink_cmd_handler(raop_event_t event, va_list args)
|
||||
{
|
||||
// don't LOCK_O as there is always a chance that LMS takes control later anyway
|
||||
if (output.external != DECODE_RAOP && output.state > OUTPUT_STOPPED) {
|
||||
LOG_WARN("Cannot use Airplay sink while LMS/BT/CSpot are controlling player");
|
||||
LOG_WARN("Cannot use Airplay sink while LMS/BT/CSpot are controlling player %d", output.external);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -338,7 +338,7 @@ static bool cspot_cmd_handler(cspot_event_t cmd, va_list args)
|
||||
{
|
||||
// don't LOCK_O as there is always a chance that LMS takes control later anyway
|
||||
if (output.external != DECODE_CSPOT && output.state > OUTPUT_STOPPED) {
|
||||
LOG_WARN("Cannot use CSpot sink while LMS/BT/Airplay are controlling player");
|
||||
LOG_WARN("Cannot use CSpot sink while LMS/BT/Airplay are controlling player %d", output.external);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -406,9 +406,7 @@ static bool cspot_cmd_handler(cspot_event_t cmd, va_list args)
|
||||
case CSPOT_VOLUME: {
|
||||
u32_t volume = va_arg(args, u32_t);
|
||||
LOG_INFO("CSpot volume %u", volume);
|
||||
//volume = 65536 * powf(volume / 32768.0f, 3);
|
||||
// TODO spotify seems to volume normalize crazy high
|
||||
volume = 4096 * powf(volume / 32768.0f, 3);
|
||||
volume = 65536 * powf(volume / 65536.0f, 2);
|
||||
set_volume(volume, volume);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "esp_wifi.h"
|
||||
#include "monitor.h"
|
||||
#include "platform_config.h"
|
||||
#include "messaging.h"
|
||||
|
||||
mutex_type slimp_mutex;
|
||||
static jmp_buf jumpbuf;
|
||||
@@ -29,6 +30,15 @@ _sig_func_ptr signal(int sig, _sig_func_ptr func) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void em_logprint(const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
vmessaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, fmt, args);
|
||||
va_end(args);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
void *audio_calloc(size_t nmemb, size_t size) {
|
||||
return calloc(nmemb, size);
|
||||
}
|
||||
@@ -55,6 +65,7 @@ int embedded_init(void) {
|
||||
mutex_create(slimp_mutex);
|
||||
sb_controls_init();
|
||||
custom_player_id = sb_displayer_init() ? 100 : 101;
|
||||
|
||||
return setjmp(jumpbuf);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,10 @@ extern u8_t custom_player_id;
|
||||
// to force some special buffer attribute
|
||||
#define EXT_BSS __attribute__((section(".ext_ram.bss")))
|
||||
|
||||
// otherwise just leave it empty
|
||||
void em_logprint(const char *fmt, ...);
|
||||
#define LOG_ERROR(fmt, ...) em_logprint("%s %s:%d " fmt "\n", logtime(), __FUNCTION__, __LINE__, ##__VA_ARGS__);
|
||||
|
||||
// all exit() calls are made from main thread (or a function called in main thread)
|
||||
void embedded_exit(int code);
|
||||
#define exit(code) do { embedded_exit(code); } while (0)
|
||||
|
||||
@@ -275,7 +275,11 @@ static void sighandler(int signum) {
|
||||
signal(signum, SIG_DFL);
|
||||
}
|
||||
|
||||
#ifndef EMBEDDED
|
||||
int main(int argc, char **argv) {
|
||||
#else
|
||||
int squeezelite_main(int argc, char **argv) {
|
||||
#endif
|
||||
char *server = NULL;
|
||||
char *output_device = "default";
|
||||
char *include_codecs = NULL;
|
||||
@@ -382,7 +386,7 @@ int main(int argc, char **argv) {
|
||||
optarg = NULL;
|
||||
optind += 1;
|
||||
} else {
|
||||
fprintf(stderr, "\nOption error: -%s\n\n", opt);
|
||||
LOG_ERROR("=> Option error: -%s", opt);
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
@@ -433,7 +437,7 @@ int main(int argc, char **argv) {
|
||||
if (!strcmp(l, "all") || !strcmp(l, "ir")) log_ir = new;
|
||||
#endif
|
||||
} else {
|
||||
fprintf(stderr, "\nDebug settings error: -d %s\n\n", optarg);
|
||||
LOG_ERROR("=> Debug settings error: -d %s", optarg);
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
@@ -447,7 +451,7 @@ int main(int argc, char **argv) {
|
||||
int byte = 0;
|
||||
char *tmp;
|
||||
if (!strncmp(optarg, "00:04:20", 8)) {
|
||||
LOG_ERROR("ignoring mac address from hardware player range 00:04:20:**:**:**");
|
||||
LOG_ERROR("=> ignoring mac address from hardware player range 00:04:20:**:**:**");
|
||||
} else {
|
||||
char *t = strtok(optarg, ":");
|
||||
while (t && byte < 6) {
|
||||
@@ -685,14 +689,14 @@ int main(int argc, char **argv) {
|
||||
exit(0);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Arg error: %s\n", argv[optind]);
|
||||
LOG_ERROR("=> arg error: %s", argv[optind]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// warn if command line includes something which isn't parsed
|
||||
if (optind < argc) {
|
||||
fprintf(stderr, "\nError: command line argument error\n\n");
|
||||
LOG_ERROR("=> command line argument error");
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
@@ -802,7 +806,7 @@ int main(int argc, char **argv) {
|
||||
#endif
|
||||
|
||||
if (name && namefile) {
|
||||
fprintf(stderr, "-n and -N option should not be used at same time\n");
|
||||
LOG_ERROR("=> -n and -N option should not be used at same time");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -845,5 +849,5 @@ int main(int argc, char **argv) {
|
||||
free_ssl_symbols();
|
||||
#endif
|
||||
|
||||
exit(0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -30,9 +30,6 @@
|
||||
* thread has a higher priority. Using an interim buffer where opus decoder writes the output is not great from
|
||||
* an efficiency (one extra memory copy) point of view, but it allows the lock to not be kept for too long
|
||||
*/
|
||||
#if EMBEDDED
|
||||
#define FRAME_BUF 2048
|
||||
#endif
|
||||
|
||||
#if BYTES_PER_FRAME == 4
|
||||
#define ALIGN(n) (n)
|
||||
@@ -40,23 +37,53 @@
|
||||
#define ALIGN(n) (n << 16)
|
||||
#endif
|
||||
|
||||
#include <opusfile.h>
|
||||
#include <ogg/ogg.h>
|
||||
#include <opus.h>
|
||||
|
||||
// opus maximum output frames is 120ms @ 48kHz
|
||||
#define MAX_OPUS_FRAMES 5760
|
||||
|
||||
struct opus {
|
||||
struct OggOpusFile *of;
|
||||
bool end;
|
||||
#if FRAME_BUF
|
||||
u8_t *write_buf;
|
||||
#endif
|
||||
#if !LINKALL
|
||||
// opus symbols to be dynamically loaded
|
||||
void (*op_free)(OggOpusFile *_of);
|
||||
int (*op_read)(OggOpusFile *_of, opus_int16 *_pcm, int _buf_size, int *_li);
|
||||
const OpusHead* (*op_head)(OggOpusFile *_of, int _li);
|
||||
OggOpusFile* (*op_open_callbacks) (void *_source, OpusFileCallbacks *_cb, unsigned char *_initial_data, size_t _initial_bytes, int *_error);
|
||||
#endif
|
||||
enum {OGG_SYNC, OGG_ID_HEADER, OGG_COMMENT_HEADER} status;
|
||||
ogg_stream_state state;
|
||||
ogg_packet packet;
|
||||
ogg_sync_state sync;
|
||||
ogg_page page;
|
||||
OpusDecoder* decoder;
|
||||
int rate, gain, pre_skip;
|
||||
size_t overframes;
|
||||
u8_t *overbuf;
|
||||
int channels;
|
||||
bool eos;
|
||||
};
|
||||
|
||||
#if !LINKALL
|
||||
static struct {
|
||||
void *handle;
|
||||
int (*ogg_stream_init)(ogg_stream_state* os, int serialno);
|
||||
int (*ogg_stream_clear)(ogg_stream_state* os);
|
||||
int (*ogg_stream_reset)(ogg_stream_state* os);
|
||||
int (*ogg_stream_eos)(ogg_stream_state* os);
|
||||
int (*ogg_stream_reset_serialno)(ogg_stream_state* os, int serialno);
|
||||
int (*ogg_sync_clear)(ogg_sync_state* oy);
|
||||
void (*ogg_packet_clear)(ogg_packet* op);
|
||||
char* (*ogg_sync_buffer)(ogg_sync_state* oy, long size);
|
||||
int (*ogg_sync_wrote)(ogg_sync_state* oy, long bytes);
|
||||
long (*ogg_sync_pageseek)(ogg_sync_state* oy, ogg_page* og);
|
||||
int (*ogg_sync_pageout)(ogg_sync_state* oy, ogg_page* og);
|
||||
int (*ogg_stream_pagein)(ogg_stream_state* os, ogg_page* og);
|
||||
int (*ogg_stream_packetout)(ogg_stream_state* os, ogg_packet* op);
|
||||
int (*ogg_page_packets)(const ogg_page* og);
|
||||
} go;
|
||||
|
||||
static struct {
|
||||
void* handle;
|
||||
OpusDecoder* (*opus_decoder_create)(opus_int32 Fs, int channels, int* error);
|
||||
int (*opus_decode)(OpusDecoder* st, const unsigned char* data, opus_int32 len, opus_int16* pcm, int frame_size, int decode_fec);
|
||||
void (*opus_decoder_destroy)(OpusDecoder* st);
|
||||
} gu;
|
||||
#endif
|
||||
|
||||
static struct opus *u;
|
||||
|
||||
extern log_level loglevel;
|
||||
@@ -75,72 +102,136 @@ extern struct processstate process;
|
||||
#if PROCESS
|
||||
#define LOCK_O_direct if (decode.direct) mutex_lock(outputbuf->mutex)
|
||||
#define UNLOCK_O_direct if (decode.direct) mutex_unlock(outputbuf->mutex)
|
||||
#define LOCK_O_not_direct if (!decode.direct) mutex_lock(outputbuf->mutex)
|
||||
#define UNLOCK_O_not_direct if (!decode.direct) mutex_unlock(outputbuf->mutex)
|
||||
#define IF_DIRECT(x) if (decode.direct) { x }
|
||||
#define IF_PROCESS(x) if (!decode.direct) { x }
|
||||
#else
|
||||
#define LOCK_O_direct mutex_lock(outputbuf->mutex)
|
||||
#define UNLOCK_O_direct mutex_unlock(outputbuf->mutex)
|
||||
#define LOCK_O_not_direct
|
||||
#define UNLOCK_O_not_direct
|
||||
#define IF_DIRECT(x) { x }
|
||||
#define IF_PROCESS(x)
|
||||
#endif
|
||||
|
||||
#if LINKALL
|
||||
#define OP(h, fn, ...) (op_ ## fn)(__VA_ARGS__)
|
||||
#define OG(h, fn, ...) (ogg_ ## fn)(__VA_ARGS__)
|
||||
#define OP(h, fn, ...) (opus_ ## fn)(__VA_ARGS__)
|
||||
#else
|
||||
#define OP(h, fn, ...) (h)->op_ ## fn(__VA_ARGS__)
|
||||
#define OG(h, fn, ...) (h)->ogg_ ## fn(__VA_ARGS__)
|
||||
#define OP(h, fn, ...) (h)->opus_ ## fn(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
// called with mutex locked within vorbis_decode to avoid locking O before S
|
||||
static int _read_cb(void *datasource, char *ptr, int size) {
|
||||
size_t bytes;
|
||||
static unsigned parse_uint16(const unsigned char* _data) {
|
||||
return _data[0] | _data[1] << 8;
|
||||
}
|
||||
|
||||
static int parse_int16(const unsigned char* _data) {
|
||||
return ((_data[0] | _data[1] << 8) ^ 0x8000) - 0x8000;
|
||||
}
|
||||
|
||||
static opus_uint32 parse_uint32(const unsigned char* _data) {
|
||||
return _data[0] | (opus_uint32)_data[1] << 8 |
|
||||
(opus_uint32)_data[2] << 16 | (opus_uint32)_data[3] << 24;
|
||||
}
|
||||
|
||||
static int get_opus_packet(void) {
|
||||
int status = 0;
|
||||
|
||||
LOCK_S;
|
||||
size_t bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
|
||||
|
||||
while (!(status = OG(&go, stream_packetout, &u->state, &u->packet)) && bytes) {
|
||||
do {
|
||||
size_t consumed = min(bytes, 4096);
|
||||
char* buffer = OG(&gu, sync_buffer, &u->sync, consumed);
|
||||
memcpy(buffer, streambuf->readp, consumed);
|
||||
OG(&gu, sync_wrote, &u->sync, consumed);
|
||||
|
||||
bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
|
||||
bytes = min(bytes, size);
|
||||
_buf_inc_readp(streambuf, consumed);
|
||||
bytes -= consumed;
|
||||
} while (!(status = OG(&gu, sync_pageseek, &u->sync, &u->page)) && bytes);
|
||||
|
||||
memcpy(ptr, streambuf->readp, bytes);
|
||||
_buf_inc_readp(streambuf, bytes);
|
||||
// if we have a new page, put it in
|
||||
if (status) OG(&go, stream_pagein, &u->state, &u->page);
|
||||
}
|
||||
|
||||
UNLOCK_S;
|
||||
return status;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
static int read_opus_header(void) {
|
||||
int status = 0;
|
||||
bool fetch = true;
|
||||
|
||||
LOCK_S;
|
||||
size_t bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
|
||||
|
||||
while (bytes && !status) {
|
||||
// first fetch a page if we need one
|
||||
if (fetch) {
|
||||
size_t consumed = min(bytes, 4096);
|
||||
char* buffer = OG(&gu, sync_buffer, &u->sync, consumed);
|
||||
memcpy(buffer, streambuf->readp, consumed);
|
||||
OG(&gu, sync_wrote, &u->sync, consumed);
|
||||
|
||||
_buf_inc_readp(streambuf, consumed);
|
||||
bytes -= consumed;
|
||||
|
||||
if (!OG(&gu, sync_pageseek, &u->sync, &u->page)) continue;
|
||||
}
|
||||
|
||||
switch (u->status) {
|
||||
case OGG_SYNC:
|
||||
u->status = OGG_ID_HEADER;
|
||||
OG(&gu, stream_reset_serialno, &u->state, OG(&gu, page_serialno, &u->page));
|
||||
fetch = false;
|
||||
break;
|
||||
case OGG_ID_HEADER:
|
||||
status = OG(&gu, stream_pagein, &u->state, &u->page);
|
||||
if (OG(&gu, stream_packetout, &u->state, &u->packet)) {
|
||||
if (u->packet.bytes < 19 || memcmp(u->packet.packet, "OpusHead", 8)) {
|
||||
LOG_ERROR("wrong opus header packet (size:%u)", u->packet.bytes);
|
||||
status = -100;
|
||||
break;
|
||||
}
|
||||
u->status = OGG_COMMENT_HEADER;
|
||||
u->channels = u->packet.packet[9];
|
||||
u->pre_skip = parse_uint16(u->packet.packet + 10);
|
||||
u->rate = parse_uint32(u->packet.packet + 12);
|
||||
u->gain = parse_int16(u->packet.packet + 16);
|
||||
u->decoder = OP(&gu, decoder_create, 48000, u->channels, &status);
|
||||
if (!u->decoder || status != OPUS_OK) {
|
||||
LOG_ERROR("can't create decoder %d (channels:%u)", status, u->channels);
|
||||
}
|
||||
}
|
||||
fetch = true;
|
||||
break;
|
||||
case OGG_COMMENT_HEADER:
|
||||
// skip pakets to consume VorbisComment. With opus, header packets align on pages
|
||||
status = OG(&gu, page_packets, &u->page);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UNLOCK_S;
|
||||
return status;
|
||||
}
|
||||
|
||||
static decode_state opus_decompress(void) {
|
||||
frames_t frames;
|
||||
int n;
|
||||
static int channels;
|
||||
u8_t *write_buf;
|
||||
|
||||
LOCK_S;
|
||||
if (decode.new_stream) {
|
||||
int status = read_opus_header();
|
||||
|
||||
if (stream.state <= DISCONNECT && u->end) {
|
||||
UNLOCK_S;
|
||||
return DECODE_COMPLETE;
|
||||
}
|
||||
|
||||
UNLOCK_S;
|
||||
|
||||
if (decode.new_stream) {
|
||||
struct OpusFileCallbacks cbs;
|
||||
const struct OpusHead *info;
|
||||
int err;
|
||||
|
||||
cbs.read = (op_read_func) _read_cb;
|
||||
cbs.seek = NULL; cbs.tell = NULL; cbs.close = NULL;
|
||||
|
||||
if ((u->of = OP(u, open_callbacks, streambuf, &cbs, NULL, 0, &err)) == NULL) {
|
||||
LOG_WARN("open_callbacks error: %d", err);
|
||||
return DECODE_COMPLETE;
|
||||
if (status == 0) {
|
||||
return DECODE_RUNNING;
|
||||
} else if (status < 0) {
|
||||
LOG_WARN("can't create codec");
|
||||
return DECODE_ERROR;
|
||||
}
|
||||
|
||||
info = OP(u, head, u->of, -1);
|
||||
|
||||
|
||||
LOCK_O;
|
||||
output.next_sample_rate = decode_newstream(48000, output.supported_rates);
|
||||
IF_DSD( output.next_fmt = PCM; )
|
||||
@@ -148,46 +239,59 @@ static decode_state opus_decompress(void) {
|
||||
if (output.fade_mode) _checkfade(true);
|
||||
decode.new_stream = false;
|
||||
UNLOCK_O;
|
||||
|
||||
channels = info->channel_count;
|
||||
|
||||
|
||||
if (u->channels > 2) {
|
||||
LOG_WARN("too many channels: %d", u->channels);
|
||||
return DECODE_ERROR;
|
||||
}
|
||||
|
||||
LOG_INFO("setting track_start");
|
||||
}
|
||||
|
||||
#if FRAME_BUF
|
||||
IF_DIRECT(
|
||||
frames = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / BYTES_PER_FRAME;
|
||||
frames = min(frames, FRAME_BUF);
|
||||
write_buf = u->write_buf;
|
||||
);
|
||||
#else
|
||||
LOCK_O_direct;
|
||||
IF_DIRECT(
|
||||
frames = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / BYTES_PER_FRAME;
|
||||
write_buf = outputbuf->writep;
|
||||
);
|
||||
#endif
|
||||
IF_PROCESS(
|
||||
frames = process.max_in_frames;
|
||||
write_buf = process.inbuf;
|
||||
);
|
||||
|
||||
u->end = frames == 0;
|
||||
|
||||
// write the decoded frames into outputbuf then unpack them (they are 16 bits)
|
||||
n = OP(u, read, u->of, (opus_int16*) write_buf, frames * channels, NULL);
|
||||
// get some packets and decode them, or use the leftover from previous pass
|
||||
if (u->overframes) {
|
||||
/* use potential leftover from previous encoding. We know that it will fit this time
|
||||
* as min_space is >=MAX_OPUS_FRAMES and we start from the beginning of the buffer */
|
||||
memcpy(write_buf, u->overbuf, u->overframes * BYTES_PER_FRAME);
|
||||
n = u->overframes;
|
||||
u->overframes = 0;
|
||||
} else if (get_opus_packet() > 0) {
|
||||
if (frames < MAX_OPUS_FRAMES) {
|
||||
// don't have enough contiguous space, use the overflow buffer
|
||||
n = OP(&gu, decode, u->decoder, u->packet.packet, u->packet.bytes, (opus_int16*) u->overbuf, MAX_OPUS_FRAMES, 0);
|
||||
if (n > 0) {
|
||||
u->overframes = n - min(n, frames);
|
||||
n = min(n, frames);
|
||||
memcpy(write_buf, u->overbuf, n * BYTES_PER_FRAME);
|
||||
memmove(u->overbuf, u->overbuf + n, u->overframes);
|
||||
}
|
||||
} else {
|
||||
/* we just do one packet at a time, although we could loop on packets but that means locking the
|
||||
* outputbuf and streambuf for maybe a long time while we process it all, so don't do that */
|
||||
n = OP(&gu, decode, u->decoder, u->packet.packet, u->packet.bytes, (opus_int16*) write_buf, frames, 0);
|
||||
}
|
||||
} else if (!OG(&go, page_eos, &u->page)) {
|
||||
UNLOCK_O_direct;
|
||||
return DECODE_RUNNING;
|
||||
} else u->eos = true;
|
||||
|
||||
#if FRAME_BUF
|
||||
LOCK_O_direct;
|
||||
#endif
|
||||
|
||||
if (n > 0) {
|
||||
frames_t count;
|
||||
s16_t *iptr;
|
||||
ISAMPLE_T *optr;
|
||||
|
||||
frames = n;
|
||||
count = frames * channels;
|
||||
count = frames * u->channels;
|
||||
|
||||
// work backward to unpack samples (if needed)
|
||||
iptr = (s16_t *) write_buf + count;
|
||||
@@ -198,20 +302,13 @@ static decode_state opus_decompress(void) {
|
||||
optr = (ISAMPLE_T *) write_buf + frames * 2;
|
||||
)
|
||||
|
||||
if (channels == 2) {
|
||||
#if BYTES_PER_FRAME == 4
|
||||
#if FRAME_BUF
|
||||
// copy needed only when DIRECT and FRAME_BUF
|
||||
IF_DIRECT(
|
||||
memcpy(outputbuf->writep, write_buf, frames * BYTES_PER_FRAME);
|
||||
)
|
||||
#endif
|
||||
#else
|
||||
if (u->channels == 2) {
|
||||
#if BYTES_PER_FRAME == 8
|
||||
while (count--) {
|
||||
*--optr = ALIGN(*--iptr);
|
||||
}
|
||||
#endif
|
||||
} else if (channels == 1) {
|
||||
} else if (u->channels == 1) {
|
||||
while (count--) {
|
||||
*--optr = ALIGN(*--iptr);
|
||||
*--optr = ALIGN(*iptr);
|
||||
@@ -229,69 +326,85 @@ static decode_state opus_decompress(void) {
|
||||
|
||||
} else if (n == 0) {
|
||||
|
||||
if (stream.state <= DISCONNECT) {
|
||||
LOG_INFO("partial decode");
|
||||
if (stream.state <= DISCONNECT && u->eos) {
|
||||
LOG_INFO("end of decode");
|
||||
UNLOCK_O_direct;
|
||||
return DECODE_COMPLETE;
|
||||
} else {
|
||||
LOG_INFO("no frame decoded");
|
||||
}
|
||||
|
||||
} else if (n == OP_HOLE) {
|
||||
|
||||
// recoverable hole in stream, seen when skipping
|
||||
LOG_DEBUG("hole in stream");
|
||||
|
||||
} else {
|
||||
|
||||
LOG_INFO("op_read error: %d", n);
|
||||
LOG_INFO("opus decode error: %d", n);
|
||||
UNLOCK_O_direct;
|
||||
return DECODE_COMPLETE;
|
||||
}
|
||||
|
||||
UNLOCK_O_direct;
|
||||
|
||||
return DECODE_RUNNING;
|
||||
}
|
||||
|
||||
|
||||
static void opus_open(u8_t size, u8_t rate, u8_t chan, u8_t endianness) {
|
||||
if (!u->of) {
|
||||
#if FRAME_BUF
|
||||
if (!u->write_buf) u->write_buf = malloc(FRAME_BUF * BYTES_PER_FRAME);
|
||||
#endif
|
||||
} else {
|
||||
OP(u, free, u->of);
|
||||
u->of = NULL;
|
||||
}
|
||||
u->end = false;
|
||||
static void opus_open(u8_t size, u8_t rate, u8_t chan, u8_t endianness) {
|
||||
if (u->decoder) OP(&gu, decoder_destroy, u->decoder);
|
||||
u->decoder = NULL;
|
||||
|
||||
if (!u->overbuf) u->overbuf = malloc(MAX_OPUS_FRAMES * BYTES_PER_FRAME);
|
||||
|
||||
u->eos = false;
|
||||
u->status = OGG_SYNC;
|
||||
u->overframes = 0;
|
||||
|
||||
OG(&gu, sync_clear, &u->sync);
|
||||
OG(&gu, stream_clear, &u->state);
|
||||
OG(&gu, stream_init, &u->state, -1);
|
||||
}
|
||||
|
||||
static void opus_close(void) {
|
||||
if (u->of) {
|
||||
OP(u, free, u->of);
|
||||
u->of = NULL;
|
||||
}
|
||||
#if FRAME_BUF
|
||||
free(u->write_buf);
|
||||
u->write_buf = NULL;
|
||||
#endif
|
||||
static void opus_close(void) {
|
||||
if (u->decoder) OP(&gu, decoder_destroy, u->decoder);
|
||||
u->decoder = NULL;
|
||||
|
||||
free(u->overbuf);
|
||||
u->overbuf = NULL;
|
||||
|
||||
OG(&gu, stream_clear, &u->state);
|
||||
OG(&gu, sync_clear, &u->sync);
|
||||
}
|
||||
|
||||
static bool load_opus(void) {
|
||||
#if !LINKALL
|
||||
void *handle = dlopen(LIBOPUS, RTLD_NOW);
|
||||
char *err;
|
||||
|
||||
if (!handle) {
|
||||
LOG_INFO("dlerror: %s", dlerror());
|
||||
|
||||
void *u.handle = dlopen(LIBOPUS, RTLD_NOW);
|
||||
if (!u_handle) {
|
||||
LOG_INFO("opus dlerror: %s", dlerror());
|
||||
return false;
|
||||
}
|
||||
|
||||
u->op_free = dlsym(handle, "op_free");
|
||||
u->op_read = dlsym(handle, "op_read");
|
||||
u->op_head = dlsym(handle, "op_head");
|
||||
u->op_open_callbacks = dlsym(handle, "op_open_callbacks");
|
||||
void *g_handle = dlopen(LIBOGG, RTLD_NOW);
|
||||
if (!g_handle) {
|
||||
dlclose(u_handle);
|
||||
LOG_INFO("ogg dlerror: %s", dlerror());
|
||||
return false;
|
||||
}
|
||||
|
||||
g_handle->ogg_stream_clear = dlsym(g_handle->handle, "ogg_stream_clear");
|
||||
g_handle->.ogg_stream_reset = dlsym(g_handle->handle, "ogg_stream_reset");
|
||||
g_handle->ogg_stream_eos = dlsym(g_handle->handle, "ogg_stream_eos");
|
||||
g_handle->ogg_stream_reset_serialno = dlsym(g_handle->handle, "ogg_stream_reset_serialno");
|
||||
g_handle->ogg_sync_clear = dlsym(g_handle->handle, "ogg_sync_clear");
|
||||
g_handle->ogg_packet_clear = dlsym(g_handle->handle, "ogg_packet_clear");
|
||||
g_handle->ogg_sync_buffer = dlsym(g_handle->handle, "ogg_sync_buffer");
|
||||
g_handle->ogg_sync_wrote = dlsym(g_handle->handle, "ogg_sync_wrote");
|
||||
g_handle->ogg_sync_pageseek = dlsym(g_handle->handle, "ogg_sync_pageseek");
|
||||
g_handle->ogg_sync_pageout = dlsym(g_handle->handle, "ogg_sync_pageout");
|
||||
g_handle->ogg_stream_pagein = dlsym(g_handle->handle, "ogg_stream_pagein");
|
||||
g_handle->ogg_stream_packetout = dlsym(g_handle->handle, "ogg_stream_packetout");
|
||||
g_handle->ogg_page_packets = dlsym(g_handle->handle, "ogg_page_packets");
|
||||
|
||||
u_handle->opus_decoder_create = dlsym(u_handle->handle, "opus_decoder_create");
|
||||
u_handle->opus_decoder_destroy = dlsym(u_handle->handle, "opus_decoder_destroy");
|
||||
u_handle->opus_decode = dlsym(u_handle->handle, "opus_decode");
|
||||
|
||||
if ((err = dlerror()) != NULL) {
|
||||
LOG_INFO("dlerror: %s", err);
|
||||
@@ -308,23 +421,17 @@ struct codec *register_opus(void) {
|
||||
static struct codec ret = {
|
||||
'u', // id
|
||||
"ops", // types
|
||||
4*1024, // min read
|
||||
32*1024, // min space
|
||||
8*1024, // min read
|
||||
MAX_OPUS_FRAMES*BYTES_PER_FRAME*2, // min space
|
||||
opus_open, // open
|
||||
opus_close, // close
|
||||
opus_decompress, // decode
|
||||
};
|
||||
|
||||
u = malloc(sizeof(struct opus));
|
||||
if (!u) {
|
||||
if ((u = calloc(1, sizeof(struct opus))) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u->of = NULL;
|
||||
#if FRAME_BUF
|
||||
u->write_buf = NULL;
|
||||
#endif
|
||||
|
||||
if (!load_opus()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -306,7 +306,7 @@ static void process_strm(u8_t *pkt, int len) {
|
||||
break;
|
||||
case 'f':
|
||||
case 'q':
|
||||
decode_flush();
|
||||
decode_flush(strm->command == 'q');
|
||||
if (!output.external) output_flush();
|
||||
status.frames_played = 0;
|
||||
if (stream_disconnect() && strm->command == 'f') sendSTAT("STMf", 0);
|
||||
|
||||
@@ -393,7 +393,6 @@ typedef enum { lERROR = 0, lWARN, lINFO, lDEBUG, lSDEBUG } log_level;
|
||||
const char *logtime(void);
|
||||
void logprint(const char *fmt, ...);
|
||||
|
||||
#define LOG_ERROR(fmt, ...) logprint("%s %s:%d " fmt "\n", logtime(), __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#define LOG_WARN(fmt, ...) if (loglevel >= lWARN) logprint("%s %s:%d " fmt "\n", logtime(), __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#define LOG_INFO(fmt, ...) if (loglevel >= lINFO) logprint("%s %s:%d " fmt "\n", logtime(), __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#define LOG_DEBUG(fmt, ...) if (loglevel >= lDEBUG) logprint("%s %s:%d " fmt "\n", logtime(), __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
@@ -406,6 +405,10 @@ typedef int sockfd;
|
||||
#include "embedded.h"
|
||||
#endif
|
||||
|
||||
#ifndef LOG_ERROR
|
||||
#define LOG_ERROR(fmt, ...) logprint("%s %s:%d " fmt "\n", logtime(), __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if !defined(MSG_NOSIGNAL)
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
@@ -619,7 +622,7 @@ struct codec {
|
||||
|
||||
void decode_init(log_level level, const char *include_codecs, const char *exclude_codecs);
|
||||
void decode_close(void);
|
||||
void decode_flush(void);
|
||||
void decode_flush(bool close);
|
||||
unsigned decode_newstream(unsigned sample_rate, unsigned supported_rates[]);
|
||||
void codec_open(u8_t format, u8_t sample_size, u8_t sample_rate, u8_t channels, u8_t endianness);
|
||||
|
||||
|
||||
@@ -390,7 +390,7 @@ void stream_init(log_level level, unsigned stream_buf_size) {
|
||||
buf_init(streambuf, stream_buf_size);
|
||||
if (streambuf->buf == NULL) {
|
||||
LOG_ERROR("unable to malloc buffer");
|
||||
exit(0);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
#if USE_SSL
|
||||
@@ -401,7 +401,7 @@ void stream_init(log_level level, unsigned stream_buf_size) {
|
||||
SSLctx = SSL_CTX_new(SSLv23_client_method());
|
||||
if (SSLctx == NULL) {
|
||||
LOG_ERROR("unable to allocate SSL context");
|
||||
exit(0);
|
||||
exit(3);
|
||||
}
|
||||
SSL_CTX_set_options(SSLctx, SSL_OP_NO_SSLv2);
|
||||
#if !LINKALL && !NO_SSLSYM
|
||||
|
||||
@@ -69,7 +69,11 @@ const char *logtime(void) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
strftime(buf, sizeof(buf), "[%T.", localtime(&tv.tv_sec));
|
||||
sprintf(buf+strlen(buf), "%06ld]", (long)tv.tv_usec);
|
||||
#ifdef EMBEDDED
|
||||
sprintf(buf+strlen(buf), "%03ld]", (long)tv.tv_usec/1000);
|
||||
#else
|
||||
sprintf(buf+strlen(buf), "%06ld]", (long)tv.tv_usec);
|
||||
#endif
|
||||
#endif
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -21,52 +21,81 @@
|
||||
|
||||
#include "squeezelite.h"
|
||||
|
||||
/*
|
||||
* with some low-end CPU, the decode call takes a fair bit of time and if the outputbuf is locked during that
|
||||
* period, the output_thread (or equivalent) will be locked although there is plenty of samples available.
|
||||
* Normally, with PRIO_INHERIT, that thread should increase decoder priority and get the lock quickly but it
|
||||
* seems that when the streambuf has plenty of data, the decode thread grabs the CPU to much, even it the output
|
||||
* thread has a higher priority. Using an interim buffer where vorbis decoder writes the output is not great from
|
||||
* an efficiency (one extra memory copy) point of view, but it allows the lock to not be kept for too long
|
||||
*/
|
||||
#if EMBEDDED
|
||||
#define FRAME_BUF 2048
|
||||
#endif
|
||||
|
||||
#if BYTES_PER_FRAME == 4
|
||||
#define ALIGN(n) (n)
|
||||
#else
|
||||
#define ALIGN(n) (n << 16)
|
||||
#endif
|
||||
|
||||
// automatically select between floating point (preferred) and fixed point libraries:
|
||||
// NOTE: works with Tremor version here: http://svn.xiph.org/trunk/Tremor, not vorbisidec.1.0.2 currently in ubuntu
|
||||
|
||||
// we take common definations from <vorbis/vorbisfile.h> even though we can use tremor at run time
|
||||
// tremor's OggVorbis_File struct is normally smaller so this is ok, but padding added to malloc in case it is bigger
|
||||
#define OV_EXCLUDE_STATIC_CALLBACKS
|
||||
|
||||
#include <ogg/ogg.h>
|
||||
#ifdef TREMOR_ONLY
|
||||
#include <ivorbisfile.h>
|
||||
#include <vorbis/ivorbiscodec.h>
|
||||
#else
|
||||
#include <vorbis/vorbisfile.h>
|
||||
#include <vorbis/codec.h>
|
||||
static bool tremor = false;
|
||||
#endif
|
||||
|
||||
// this is tremor packing, not mine...
|
||||
static inline int32_t clip15(int32_t x) {
|
||||
int ret = x;
|
||||
ret -= ((x<=32767)-1)&(x-32767);
|
||||
ret -= ((x>=-32768)-1)&(x+32768);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if BYTES_PER_FRAME == 4
|
||||
#define ALIGN(n) clip15((n) >> 9);
|
||||
#define ALIGN_FLOAT(n) ((n)*32768.0f + 0.5f)
|
||||
#else
|
||||
#define ALIGN(n) (clip15((n) >> 9) << 16)
|
||||
#define ALIGN_FLOAT ((n)*32768.0f*65536.0f + 0.5f)
|
||||
#endif
|
||||
|
||||
struct vorbis {
|
||||
OggVorbis_File *vf;
|
||||
bool opened, end;
|
||||
#if FRAME_BUF
|
||||
u8_t *write_buf;
|
||||
#endif
|
||||
bool opened;
|
||||
enum { OGG_SYNC, OGG_ID_HEADER, OGG_COMMENT_HEADER, OGG_SETUP_HEADER } status;
|
||||
struct {
|
||||
ogg_stream_state state;
|
||||
ogg_packet packet;
|
||||
ogg_sync_state sync;
|
||||
ogg_page page;
|
||||
};
|
||||
struct {
|
||||
vorbis_dsp_state decoder;
|
||||
vorbis_info info;
|
||||
vorbis_comment comment;
|
||||
vorbis_block block;
|
||||
};
|
||||
int rate, channels;
|
||||
uint32_t overflow;
|
||||
bool eos;
|
||||
};
|
||||
|
||||
#if !LINKALL
|
||||
static struct vorbis {
|
||||
// vorbis symbols to be dynamically loaded - from either vorbisfile or vorbisidec (tremor) version of library
|
||||
vorbis_info *(* ov_info)(OggVorbis_File *vf, int link);
|
||||
int (* ov_clear)(OggVorbis_File *vf);
|
||||
long (* ov_read)(OggVorbis_File *vf, char *buffer, int length, int bigendianp, int word, int sgned, int *bitstream);
|
||||
long (* ov_read_tremor)(OggVorbis_File *vf, char *buffer, int length, int *bitstream);
|
||||
int (* ov_open_callbacks)(void *datasource, OggVorbis_File *vf, const char *initial, long ibytes, ov_callbacks callbacks);
|
||||
} gv;
|
||||
|
||||
static struct {
|
||||
void *handle;
|
||||
int (*ogg_stream_init)(ogg_stream_state* os, int serialno);
|
||||
int (*ogg_stream_clear)(ogg_stream_state* os);
|
||||
int (*ogg_stream_reset)(ogg_stream_state* os);
|
||||
int (*ogg_stream_eos)(ogg_stream_state* os);
|
||||
int (*ogg_stream_reset_serialno)(ogg_stream_state* os, int serialno);
|
||||
int (*ogg_sync_clear)(ogg_sync_state* oy);
|
||||
void (*ogg_packet_clear)(ogg_packet* op);
|
||||
char* (*ogg_sync_buffer)(ogg_sync_state* oy, long size);
|
||||
int (*ogg_sync_wrote)(ogg_sync_state* oy, long bytes);
|
||||
long (*ogg_sync_pageseek)(ogg_sync_state* oy, ogg_page* og);
|
||||
int (*ogg_sync_pageout)(ogg_sync_state* oy, ogg_page* og);
|
||||
int (*ogg_stream_pagein)(ogg_stream_state* os, ogg_page* og);
|
||||
int (*ogg_stream_packetout)(ogg_stream_state* os, ogg_packet* op);
|
||||
int (*ogg_page_packets)(const ogg_page* og);
|
||||
} go;
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct vorbis *v;
|
||||
|
||||
@@ -86,183 +115,249 @@ extern struct processstate process;
|
||||
#if PROCESS
|
||||
#define LOCK_O_direct if (decode.direct) mutex_lock(outputbuf->mutex)
|
||||
#define UNLOCK_O_direct if (decode.direct) mutex_unlock(outputbuf->mutex)
|
||||
#define LOCK_O_not_direct if (!decode.direct) mutex_lock(outputbuf->mutex)
|
||||
#define UNLOCK_O_not_direct if (!decode.direct) mutex_unlock(outputbuf->mutex)
|
||||
#define IF_DIRECT(x) if (decode.direct) { x }
|
||||
#define IF_PROCESS(x) if (!decode.direct) { x }
|
||||
#else
|
||||
#define LOCK_O_direct mutex_lock(outputbuf->mutex)
|
||||
#define UNLOCK_O_direct mutex_unlock(outputbuf->mutex)
|
||||
#define LOCK_O_not_direct
|
||||
#define UNLOCK_O_not_direct
|
||||
#define IF_DIRECT(x) { x }
|
||||
#define IF_PROCESS(x)
|
||||
#endif
|
||||
|
||||
#if LINKALL
|
||||
#define OV(h, fn, ...) (ov_ ## fn)(__VA_ARGS__)
|
||||
#define TREMOR(h) 0
|
||||
#if !WIN
|
||||
extern int ov_read_tremor(); // needed to enable compilation, not linked
|
||||
#endif
|
||||
#define OV(h, fn, ...) (vorbis_ ## fn)(__VA_ARGS__)
|
||||
#define OG(h, fn, ...) (ogg_ ## fn)(__VA_ARGS__)
|
||||
#else
|
||||
#define OV(h, fn, ...) (h)->ov_##fn(__VA_ARGS__)
|
||||
#define TREMOR(h) (h)->ov_read_tremor
|
||||
#define OG(h, fn, ...) (h)->ogg_ ## fn(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
// called with mutex locked within vorbis_decode to avoid locking O before S
|
||||
static size_t _read_cb(void *ptr, size_t size, size_t nmemb, void *datasource) {
|
||||
size_t bytes;
|
||||
static int get_ogg_packet(void) {
|
||||
int status = 0;
|
||||
|
||||
LOCK_S;
|
||||
size_t bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
|
||||
|
||||
bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
|
||||
bytes = min(bytes, size * nmemb);
|
||||
while (!(status = OG(&go, stream_packetout, &v->state, &v->packet)) && bytes) {
|
||||
do {
|
||||
size_t consumed = min(bytes, 4096);
|
||||
char* buffer = OG(&gv, sync_buffer, &v->sync, consumed);
|
||||
memcpy(buffer, streambuf->readp, consumed);
|
||||
OG(&gv, sync_wrote, &v->sync, consumed);
|
||||
|
||||
memcpy(ptr, streambuf->readp, bytes);
|
||||
_buf_inc_readp(streambuf, bytes);
|
||||
_buf_inc_readp(streambuf, consumed);
|
||||
bytes -= consumed;
|
||||
} while (!(status = OG(&go, sync_pageseek, &v->sync, &v->page)) && bytes);
|
||||
|
||||
// if we have a new page, put it in
|
||||
if (status) OG(&go, stream_pagein, &v->state, &v->page);
|
||||
}
|
||||
|
||||
UNLOCK_S;
|
||||
|
||||
return bytes / size;
|
||||
return status;
|
||||
}
|
||||
|
||||
// these are needed for older versions of tremor, later versions and libvorbis allow NULL to be used
|
||||
static int _seek_cb(void *datasource, ogg_int64_t offset, int whence) { return -1; }
|
||||
static int _close_cb(void *datasource) { return 0; }
|
||||
static long _tell_cb(void *datasource) { return 0; }
|
||||
|
||||
static decode_state vorbis_decode(void) {
|
||||
static int channels;
|
||||
frames_t frames;
|
||||
int bytes, s, n;
|
||||
u8_t *write_buf;
|
||||
static int read_vorbis_header(void) {
|
||||
int status = 0;
|
||||
bool fetch = true;
|
||||
|
||||
LOCK_S;
|
||||
|
||||
if (stream.state <= DISCONNECT && v->end) {
|
||||
UNLOCK_S;
|
||||
return DECODE_COMPLETE;
|
||||
size_t bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
|
||||
|
||||
while (bytes && !status) {
|
||||
// first fetch a page if we need one
|
||||
if (fetch) {
|
||||
size_t consumed = min(bytes, 4096);
|
||||
char* buffer = OG(&go, sync_buffer, &v->sync, consumed);
|
||||
memcpy(buffer, streambuf->readp, consumed);
|
||||
OG(&go, sync_wrote, &v->sync, consumed);
|
||||
|
||||
_buf_inc_readp(streambuf, consumed);
|
||||
bytes -= consumed;
|
||||
|
||||
if (!OG(&go, sync_pageseek, &v->sync, &v->page)) continue;
|
||||
}
|
||||
|
||||
switch (v->status) {
|
||||
case OGG_SYNC:
|
||||
v->status = OGG_ID_HEADER;
|
||||
OG(&go, stream_reset_serialno, &v->state, OG(&go, page_serialno, &v->page));
|
||||
fetch = false;
|
||||
break;
|
||||
case OGG_ID_HEADER:
|
||||
status = OG(&go, stream_pagein, &v->state, &v->page);
|
||||
if (!OG(&go, stream_packetout, &v->state, &v->packet)) break;
|
||||
|
||||
OV(&gv, info_init, &v->info);
|
||||
status = OV(&gv, synthesis_headerin, &v->info, &v->comment, &v->packet);
|
||||
|
||||
if (status) {
|
||||
LOG_ERROR("vorbis id header packet error %d", status);
|
||||
status = -1;
|
||||
} else {
|
||||
v->channels = v->info.channels;
|
||||
v->rate = v->info.rate;
|
||||
v->status = OGG_COMMENT_HEADER;
|
||||
|
||||
// only fetch if no other packet already in (they should not)
|
||||
fetch = OG(&go, page_packets, &v->page) <= 1;
|
||||
if (!fetch) LOG_INFO("id packet should terminate page");
|
||||
LOG_INFO("id acquired");
|
||||
}
|
||||
break;
|
||||
case OGG_SETUP_HEADER:
|
||||
// header packets don't align with pages on Vorbis (contrary to Opus)
|
||||
if (fetch) OG(&go, stream_pagein, &v->state, &v->page);
|
||||
|
||||
// finally build a codec if we have the packet
|
||||
status = OG(&go, stream_packetout, &v->state, &v->packet);
|
||||
if (status && ((status = OV(&gv, synthesis_headerin, &v->info, &v->comment, &v->packet)) ||
|
||||
(status = OV(&gv, synthesis_init, &v->decoder, &v->info)))) {
|
||||
LOG_ERROR("vorbis setup header packet error %d", status);
|
||||
// no need to free comment, it's fake
|
||||
OV(&gv, info_clear, &v->info);
|
||||
status = -1;
|
||||
} else {
|
||||
OV(&gv, block_init, &v->decoder, &v->block);
|
||||
v->opened = true;
|
||||
LOG_INFO("codec up and running (rate: %d, channels:%d)", v->rate, v->channels);
|
||||
status = 1;
|
||||
}
|
||||
//@FIXME: can we have audio on that page as well?
|
||||
break;
|
||||
case OGG_COMMENT_HEADER: {
|
||||
// don't consume VorbisComment, just skip it
|
||||
int packets = OG(&go, page_packets, &v->page);
|
||||
if (packets) {
|
||||
v->status = OGG_SETUP_HEADER;
|
||||
OG(&go, stream_pagein, &v->state, &v->page);
|
||||
OG(&go, stream_packetout, &v->state, &v->packet);
|
||||
|
||||
OV(&gv, comment_init, &v->comment);
|
||||
v->comment.vendor = "N/A";
|
||||
|
||||
// because of lack of page alignment, we might have the setup page already fully in
|
||||
if (packets > 1) fetch = false;
|
||||
LOG_INFO("comment skipped succesfully");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UNLOCK_S;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
inline int pcm_out(vorbis_dsp_state* decoder, void*** pcm) {
|
||||
#ifndef TREMOR_ONLY
|
||||
if (!tremor) return OV(&gv, synthesis_pcmout, decoder, (ogg_float_t***) pcm);
|
||||
#endif
|
||||
return OV(&gv, synthesis_pcmout, decoder, (ogg_int32_t***) pcm);
|
||||
}
|
||||
|
||||
static decode_state vorbis_decode(void) {
|
||||
frames_t frames;
|
||||
int n = 0;
|
||||
u8_t *write_buf;
|
||||
void** pcm = NULL;
|
||||
|
||||
if (decode.new_stream) {
|
||||
ov_callbacks cbs;
|
||||
int err;
|
||||
struct vorbis_info *info;
|
||||
int status = read_vorbis_header();
|
||||
|
||||
cbs.read_func = _read_cb;
|
||||
|
||||
if (TREMOR(v)) {
|
||||
cbs.seek_func = _seek_cb; cbs.close_func = _close_cb; cbs.tell_func = _tell_cb;
|
||||
} else {
|
||||
cbs.seek_func = NULL; cbs.close_func = NULL; cbs.tell_func = NULL;
|
||||
if (status == 0) {
|
||||
return DECODE_RUNNING;
|
||||
} else if (status < 0) {
|
||||
LOG_WARN("can't create codec");
|
||||
return DECODE_ERROR;
|
||||
}
|
||||
|
||||
if ((err = OV(v, open_callbacks, streambuf, v->vf, NULL, 0, cbs)) < 0) {
|
||||
LOG_WARN("open_callbacks error: %d", err);
|
||||
return DECODE_COMPLETE;
|
||||
}
|
||||
|
||||
v->opened = true;
|
||||
info = OV(v, info, v->vf, -1);
|
||||
|
||||
LOG_INFO("setting track_start");
|
||||
LOCK_O;
|
||||
output.next_sample_rate = decode_newstream(info->rate, output.supported_rates);
|
||||
output.next_sample_rate = decode_newstream(v->rate, output.supported_rates);
|
||||
IF_DSD( output.next_fmt = PCM; )
|
||||
output.track_start = outputbuf->writep;
|
||||
if (output.fade_mode) _checkfade(true);
|
||||
decode.new_stream = false;
|
||||
UNLOCK_O;
|
||||
|
||||
channels = info->channels;
|
||||
|
||||
if (channels > 2) {
|
||||
LOG_WARN("too many channels: %d", channels);
|
||||
if (v->channels > 2) {
|
||||
LOG_WARN("too many channels: %d", v->channels);
|
||||
return DECODE_ERROR;
|
||||
}
|
||||
|
||||
LOG_INFO("setting track_start");
|
||||
}
|
||||
|
||||
#if FRAME_BUF
|
||||
IF_DIRECT(
|
||||
frames = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / BYTES_PER_FRAME;
|
||||
frames = min(frames, FRAME_BUF);
|
||||
write_buf = v->write_buf;
|
||||
);
|
||||
#else
|
||||
LOCK_O_direct;
|
||||
IF_DIRECT(
|
||||
frames = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / BYTES_PER_FRAME;
|
||||
write_buf = outputbuf->writep;
|
||||
);
|
||||
#endif
|
||||
IF_PROCESS(
|
||||
frames = process.max_in_frames;
|
||||
write_buf = process.inbuf;
|
||||
);
|
||||
|
||||
bytes = frames * 2 * channels; // samples returned are 16 bits
|
||||
v->end = frames == 0;
|
||||
|
||||
// write the decoded frames into outputbuf even though they are 16 bits per sample, then unpack them
|
||||
#ifdef TREMOR_ONLY
|
||||
n = OV(v, read, v->vf, (char *)write_buf, bytes, &s);
|
||||
#else
|
||||
if (!TREMOR(v)) {
|
||||
#if SL_LITTLE_ENDIAN
|
||||
n = OV(v, read, v->vf, (char *)write_buf, bytes, 0, 2, 1, &s);
|
||||
#else
|
||||
n = OV(v, read, v->vf, (char *)write_buf, bytes, 1, 2, 1, &s);
|
||||
#endif
|
||||
#if !WIN
|
||||
} else {
|
||||
n = OV(v, read_tremor, v->vf, (char *)write_buf, bytes, &s);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if FRAME_BUF
|
||||
LOCK_O_direct;
|
||||
#endif
|
||||
if (v->overflow) {
|
||||
n = pcm_out(&v->decoder, &pcm);
|
||||
v->overflow = n - min(n, frames);
|
||||
} else if (get_ogg_packet() > 0) {
|
||||
n = OV(&gv, synthesis, &v->block, &v->packet);
|
||||
if (n == 0) n = OV(&gv, synthesis_blockin, &v->decoder, &v->block);
|
||||
if (n == 0) n = pcm_out(&v->decoder, &pcm);
|
||||
v->overflow = n - min(n, frames);
|
||||
} else if (!OG(&go, page_eos, &v->page)) {
|
||||
UNLOCK_O_direct;
|
||||
return DECODE_RUNNING;
|
||||
} else v->eos = true;
|
||||
|
||||
if (n > 0) {
|
||||
frames_t count;
|
||||
s16_t *iptr;
|
||||
ISAMPLE_T *optr;
|
||||
ISAMPLE_T *optr = (ISAMPLE_T*) write_buf;
|
||||
frames = min(n, frames);
|
||||
frames_t count = frames;
|
||||
|
||||
#ifndef TREMOR_ONLY
|
||||
if (!tremor) {
|
||||
if (v->channels == 2) {
|
||||
float* iptr_l = (float*) pcm[0];
|
||||
float* iptr_r = (float*) pcm[1];
|
||||
|
||||
frames = n / 2 / channels;
|
||||
count = frames * channels;
|
||||
|
||||
// work backward to unpack samples (if needed)
|
||||
iptr = (s16_t *) write_buf + count;
|
||||
IF_DIRECT(
|
||||
optr = (ISAMPLE_T *) outputbuf->writep + frames * 2;
|
||||
)
|
||||
IF_PROCESS(
|
||||
optr = (ISAMPLE_T *) write_buf + frames * 2;
|
||||
)
|
||||
|
||||
if (channels == 2) {
|
||||
#if BYTES_PER_FRAME == 4
|
||||
#if FRAME_BUF
|
||||
// copy needed only when DIRECT and FRAME_BUF
|
||||
IF_DIRECT(
|
||||
memcpy(outputbuf->writep, write_buf, frames * BYTES_PER_FRAME);
|
||||
)
|
||||
#endif
|
||||
while (count--) {
|
||||
*optr++ = ALIGN_FLOAT(*iptr_l++);
|
||||
*optr++ = ALIGN_FLOAT(*iptr_r++);;
|
||||
}
|
||||
} else if (v->channels == 1) {
|
||||
float* iptr = pcm[0];
|
||||
while (count--) {
|
||||
*optr++ = ALIGN_FLOAT(*iptr);
|
||||
*optr++ = ALIGN_FLOAT(*iptr++);
|
||||
}
|
||||
}
|
||||
} else
|
||||
#else
|
||||
while (count--) {
|
||||
*--optr = ALIGN(*--iptr);
|
||||
}
|
||||
{
|
||||
if (v->channels == 2) {
|
||||
s32_t* iptr_l = (s32_t*) pcm[0];
|
||||
s32_t* iptr_r = (s32_t*) pcm[1];
|
||||
|
||||
while (count--) {
|
||||
*optr++ = ALIGN(*iptr_l++);
|
||||
*optr++ = ALIGN(*iptr_r++);
|
||||
}
|
||||
} else if (v->channels == 1) {
|
||||
s32_t* iptr = (s32_t*) pcm[0];
|
||||
while (count--) {
|
||||
*optr++ = ALIGN(*iptr);
|
||||
*optr++ = ALIGN(*iptr++);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else if (channels == 1) {
|
||||
while (count--) {
|
||||
*--optr = ALIGN(*--iptr);
|
||||
*--optr = ALIGN(*iptr);
|
||||
}
|
||||
}
|
||||
// return samples to vorbis/tremor decoder
|
||||
OV(&gv, synthesis_read, &v->decoder, frames);
|
||||
|
||||
IF_DIRECT(
|
||||
_buf_inc_writep(outputbuf, frames * BYTES_PER_FRAME);
|
||||
@@ -275,19 +370,14 @@ static decode_state vorbis_decode(void) {
|
||||
|
||||
} else if (n == 0) {
|
||||
|
||||
if (stream.state <= DISCONNECT) {
|
||||
LOG_INFO("partial decode");
|
||||
if (stream.state <= DISCONNECT && v->eos) {
|
||||
LOG_INFO("end of decode");
|
||||
UNLOCK_O_direct;
|
||||
return DECODE_COMPLETE;
|
||||
} else {
|
||||
LOG_INFO("no frame decoded");
|
||||
}
|
||||
|
||||
} else if (n == OV_HOLE) {
|
||||
|
||||
// recoverable hole in stream, seen when skipping
|
||||
LOG_DEBUG("hole in stream");
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
LOG_INFO("ov_read error: %d", n);
|
||||
@@ -300,55 +390,81 @@ static decode_state vorbis_decode(void) {
|
||||
}
|
||||
|
||||
static void vorbis_open(u8_t size, u8_t rate, u8_t chan, u8_t endianness) {
|
||||
if (!v->vf) {
|
||||
v->vf = malloc(sizeof(OggVorbis_File) + 128); // add some padding as struct size may be larger
|
||||
memset(v->vf, 0, sizeof(OggVorbis_File) + 128);
|
||||
#if FRAME_BUF
|
||||
v->write_buf = malloc(FRAME_BUF * BYTES_PER_FRAME);
|
||||
#endif
|
||||
} else {
|
||||
if (v->opened) {
|
||||
OV(v, clear, v->vf);
|
||||
v->opened = false;
|
||||
}
|
||||
LOG_INFO("OPENING CODEC");
|
||||
if (v->opened) {
|
||||
OV(&go, block_clear, &v->block);
|
||||
OV(&go, info_clear, &v->info);
|
||||
OV(&go, dsp_clear, &v->decoder);
|
||||
}
|
||||
|
||||
v->eos = false;
|
||||
v->opened = false;
|
||||
v->status = OGG_SYNC;
|
||||
v->overflow = 0;
|
||||
|
||||
OG(&gu, sync_clear, &v->sync);
|
||||
OG(&gu, stream_clear, &v->state);
|
||||
OG(&gu, stream_init, &v->state, -1);
|
||||
}
|
||||
|
||||
static void vorbis_close(void) {
|
||||
static void vorbis_close() {
|
||||
return;
|
||||
LOG_INFO("CLOSING CODEC");
|
||||
if (v->opened) {
|
||||
OV(v, clear, v->vf);
|
||||
v->opened = false;
|
||||
OV(&go, block_clear, &v->block);
|
||||
OV(&go, info_clear, &v->info);
|
||||
OV(&go, dsp_clear, &v->decoder);
|
||||
}
|
||||
free(v->vf);
|
||||
#if FRAME_BUF
|
||||
free(v->write_buf);
|
||||
v->write_buf = NULL;
|
||||
#endif
|
||||
v->vf = NULL;
|
||||
v->end = false;
|
||||
|
||||
v->opened = false;
|
||||
|
||||
OG(&go, stream_clear, &v->state);
|
||||
OG(&go, sync_clear, &v->sync);
|
||||
}
|
||||
|
||||
static bool load_vorbis() {
|
||||
#if !LINKALL
|
||||
void *handle = dlopen(LIBVORBIS, RTLD_NOW);
|
||||
char *err;
|
||||
bool tremor = false;
|
||||
|
||||
if (!handle) {
|
||||
handle = dlopen(LIBTREMOR, RTLD_NOW);
|
||||
if (handle) {
|
||||
char *err;
|
||||
|
||||
void *g_handle = dlopen(LIBOGG, RTLD_NOW);
|
||||
if (!g_handle) {
|
||||
LOG_INFO("ogg dlerror: %s", dlerror());
|
||||
return false
|
||||
}
|
||||
|
||||
void *v_handle = NULL;
|
||||
#ifndef TREMOR_ONLY
|
||||
v_handle = dlopen(LIBVORBIS, RTLD_NOW);
|
||||
#endif
|
||||
if (!v_handle) {
|
||||
v_handle = dlopen(LIBTREMOR, RTLD_NOW);
|
||||
if (v_handle) {
|
||||
tremor = true;
|
||||
} else {
|
||||
LOG_INFO("dlerror: %s", dlerror());
|
||||
dlclose(g_handle);
|
||||
LOG_INFO("vorbis/tremor dlerror: %s", dlerror());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
g_handle->ogg_stream_clear = dlsym(g_handle->handle, "ogg_stream_clear");
|
||||
g_handle->ogg_stream_reset = dlsym(g_handle->handle, "ogg_stream_reset");
|
||||
g_handle->ogg_stream_eos = dlsym(g_handle->handle, "ogg_stream_eos");
|
||||
g_handle->ogg_stream_reset_serialno = dlsym(g_handle->handle, "ogg_stream_reset_serialno");
|
||||
g_handle->ogg_sync_clear = dlsym(g_handle->handle, "ogg_sync_clear");
|
||||
g_handle->ogg_packet_clear = dlsym(g_handle->handle, "ogg_packet_clear");
|
||||
g_handle->ogg_sync_buffer = dlsym(g_handle->handle, "ogg_sync_buffer");
|
||||
g_handle->ogg_sync_wrote = dlsym(g_handle->handle, "ogg_sync_wrote");
|
||||
g_handle->ogg_sync_pageseek = dlsym(g_handle->handle, "ogg_sync_pageseek");
|
||||
g_handle->ogg_sync_pageout = dlsym(g_handle->handle, "ogg_sync_pageout");
|
||||
g_handle->ogg_stream_pagein = dlsym(g_handle->handle, "ogg_stream_pagein");
|
||||
g_handle->ogg_stream_packetout = dlsym(g_handle->handle, "ogg_stream_packetout");
|
||||
g_handle->ogg_page_packets = dlsym(g_handle->handle, "ogg_page_packets");
|
||||
|
||||
v->ov_read = tremor ? NULL : dlsym(handle, "ov_read");
|
||||
v->ov_read_tremor = tremor ? dlsym(handle, "ov_read") : NULL;
|
||||
v->ov_info = dlsym(handle, "ov_info");
|
||||
v->ov_clear = dlsym(handle, "ov_clear");
|
||||
v->ov_open_callbacks = dlsym(handle, "ov_open_callbacks");
|
||||
v_handle.ov_read = dlsym(handle, "ov_read");
|
||||
v_handle.ov_info = dlsym(handle, "ov_info");
|
||||
v_handle.ov_clear = dlsym(handle, "ov_clear");
|
||||
v_handle.ov_open_callbacks = dlsym(handle, "ov_open_callbacks");
|
||||
|
||||
if ((err = dlerror()) != NULL) {
|
||||
LOG_INFO("dlerror: %s", err);
|
||||
@@ -372,12 +488,10 @@ struct codec *register_vorbis(void) {
|
||||
vorbis_decode,// decode
|
||||
};
|
||||
|
||||
v = malloc(sizeof(struct vorbis));
|
||||
if (!v) {
|
||||
if ((v = calloc(1, sizeof(struct vorbis))) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
v->vf = NULL;
|
||||
v->opened = false;
|
||||
|
||||
if (!load_vorbis()) {
|
||||
|
||||
@@ -128,8 +128,8 @@ void init_telnet(){
|
||||
if (bMirrorToUART) uart_fd = open("/dev/uart/0", O_RDWR);
|
||||
|
||||
ESP_ERROR_CHECK(esp_vfs_register("/dev/pkspstdout", &vfs, NULL));
|
||||
freopen("/dev/pkspstdout", "wb", stdout);
|
||||
freopen("/dev/pkspstdout", "wb", stderr);
|
||||
freopen("/dev/pkspstdout", "w", stdout);
|
||||
freopen("/dev/pkspstdout", "w", stderr);
|
||||
|
||||
bIsEnabled=true;
|
||||
}
|
||||
|
||||
@@ -266,6 +266,11 @@ cJSON* network_status_get_basic_info(cJSON** old) {
|
||||
*old = network_status_update_float(old, "avg_conn_time", nm->num_disconnect > 0 ? (nm->total_connected_time / nm->num_disconnect) : 0);
|
||||
*old = network_update_cjson_number(old, "bt_status", bt_app_source_get_a2d_state());
|
||||
*old = network_update_cjson_number(old, "bt_sub_status", bt_app_source_get_media_state());
|
||||
#if DEPTH == 16
|
||||
*old = network_update_cjson_number(old, "depth", 16);
|
||||
#elif DEPTH == 32
|
||||
*old = network_update_cjson_number(old, "depth", 32);
|
||||
#endif
|
||||
#if CONFIG_I2C_LOCKED
|
||||
*old = network_status_update_bool(old, "is_i2c_locked", true);
|
||||
#else
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
7
components/wifi-manager/webapp/dist/css/index.cd56ff129e3113d8cd3a.css
vendored
Normal file
7
components/wifi-manager/webapp/dist/css/index.cd56ff129e3113d8cd3a.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
components/wifi-manager/webapp/dist/css/index.cd56ff129e3113d8cd3a.css.gz
vendored
Normal file
BIN
components/wifi-manager/webapp/dist/css/index.cd56ff129e3113d8cd3a.css.gz
vendored
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
components/wifi-manager/webapp/dist/index.html.gz
vendored
BIN
components/wifi-manager/webapp/dist/index.html.gz
vendored
Binary file not shown.
2
components/wifi-manager/webapp/dist/js/index.0748ab.bundle.js
vendored
Normal file
2
components/wifi-manager/webapp/dist/js/index.0748ab.bundle.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
components/wifi-manager/webapp/dist/js/index.0748ab.bundle.js.gz
vendored
Normal file
BIN
components/wifi-manager/webapp/dist/js/index.0748ab.bundle.js.gz
vendored
Normal file
Binary file not shown.
1
components/wifi-manager/webapp/dist/js/index.0748ab.bundle.js.map
vendored
Normal file
1
components/wifi-manager/webapp/dist/js/index.0748ab.bundle.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
2
components/wifi-manager/webapp/dist/js/node_vendors.0748ab.bundle.js
vendored
Normal file
2
components/wifi-manager/webapp/dist/js/node_vendors.0748ab.bundle.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
components/wifi-manager/webapp/dist/js/node_vendors.0748ab.bundle.js.gz
vendored
Normal file
BIN
components/wifi-manager/webapp/dist/js/node_vendors.0748ab.bundle.js.gz
vendored
Normal file
Binary file not shown.
1
components/wifi-manager/webapp/dist/js/node_vendors.0748ab.bundle.js.map
vendored
Normal file
1
components/wifi-manager/webapp/dist/js/node_vendors.0748ab.bundle.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
39
components/wifi-manager/webapp/dist/report.html
vendored
Normal file
39
components/wifi-manager/webapp/dist/report.html
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -24,6 +24,24 @@ declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getStatus(): {};
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
@@ -50,6 +68,42 @@ declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function getRadioButton(entry: any): string;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
declare function pushStatus(): void;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
declare const PORT: 9100;
|
||||
import HtmlWebPackPlugin = require("html-webpack-plugin");
|
||||
export namespace entry {
|
||||
const test: string;
|
||||
@@ -17,7 +18,7 @@ export namespace devServer {
|
||||
}
|
||||
export const open: boolean;
|
||||
export const compress: boolean;
|
||||
export const port: number;
|
||||
export { PORT as port };
|
||||
export const host: string;
|
||||
export const allowedHosts: string;
|
||||
export const headers: {
|
||||
@@ -33,3 +34,4 @@ export namespace devServer {
|
||||
export function onBeforeSetupMiddleware(devServer: any): void;
|
||||
}
|
||||
export const plugins: HtmlWebPackPlugin[];
|
||||
export {};
|
||||
|
||||
@@ -23,5 +23,6 @@
|
||||
"mock_plugin_has_proxy": "x",
|
||||
"mock_fail_fw_update":"",
|
||||
"mock_fail_recovery":"",
|
||||
"mock_old_recovery":""
|
||||
"mock_old_recovery":"",
|
||||
"depth": 16
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"scripts": {
|
||||
"prod": "webpack serve --open --mode=production",
|
||||
"build": "webpack --mode=production ",
|
||||
"stats": "webpack --env ANALYZE_SIZE=1 --mode=production ",
|
||||
"watch": "webpack --progress --watch --mode=development ",
|
||||
"dev": "webpack serve --open --mode=development"
|
||||
},
|
||||
@@ -51,6 +52,7 @@
|
||||
"lodash-webpack-plugin": "^0.11.6",
|
||||
"mini-css-extract-plugin": "^2.5.2",
|
||||
"node-sass": "^7.0.1",
|
||||
"open": "^9.1.0",
|
||||
"postcss": "^8.4.5",
|
||||
"postcss-loader": "^6.2.1",
|
||||
"purgecss-webpack-plugin": "^4.1.3",
|
||||
@@ -65,7 +67,7 @@
|
||||
"ts-loader": "^9.2.6",
|
||||
"typescript": "^4.5.5",
|
||||
"webpack": "^5.67.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0",
|
||||
"webpack-bundle-analyzer": "^4.8.0",
|
||||
"webpack-cli": "^4.9.2",
|
||||
"webpack-dev-server": "^4.7.3"
|
||||
},
|
||||
@@ -74,7 +76,9 @@
|
||||
"async-mutex": "^0.3.2",
|
||||
"bootstrap": "^5.1.3",
|
||||
"jquery": "^3.6.0",
|
||||
"popper.js": "^1.16.1"
|
||||
"popper.js": "^1.16.1",
|
||||
"webpack-visualizer-plugin": "^0.1.11",
|
||||
"webpack-visualizer-plugin2": "^1.0.0"
|
||||
},
|
||||
"keywords": [
|
||||
"webppack4",
|
||||
|
||||
@@ -44,19 +44,23 @@
|
||||
|
||||
</div>
|
||||
<div class="info navbar-right" style="display: inline-flex;">
|
||||
<span class="recovery_element material-icons " style="color:orange; display: none" aria-label="🛑" >system_update_alt</span>
|
||||
<span id="battery" class="material-icons" style="fill:white; display: none" aria-label="🔋" >battery_full</span>
|
||||
<span class="recovery_element material-icons " style="color:orange; display: none"
|
||||
aria-label="🛑">system_update_alt</span>
|
||||
<span id="battery" class="material-icons" style="fill:white; display: none"
|
||||
aria-label="🔋">battery_full</span>
|
||||
<span id="o_jack" class="material-icons" style="fill:white; display: none" aria-label="🎧">headphones</span>
|
||||
<span id="s_airplay" class="material-icons" style="fill:white; display: none" aria-label="🍎">airplay</span>
|
||||
<em id="s_cspot" class="fab fa-spotify" style="fill:white; display: inline"></em>
|
||||
<span data-bs-toggle="tooltip" id="o_type" data-bs-placement="top" title="">
|
||||
<span id="o_bt" class="material-icons" style="fill:white; display: none" aria-label="">bluetooth</span>
|
||||
<span id="o_spdif" class="material-icons" style="fill:white; display: none" aria-label="">graphic_eq</span>
|
||||
<span id="o_spdif" class="material-icons" style="fill:white; display: none"
|
||||
aria-label="">graphic_eq</span>
|
||||
<span id="o_i2s" class="material-icons" style="fill:white; display: none" aria-label="🔈">speaker</span>
|
||||
</span>
|
||||
<span id="ethernet" class="material-icons if_eth" style="fill:white; display: none" aria-label="ETH">cable</span>
|
||||
<span id="wifiStsIcon" class="material-icons if_wifi"
|
||||
style="fill:white; display: none" aria-label=""></span>
|
||||
<span id="ethernet" class="material-icons if_eth" style="fill:white; display: none"
|
||||
aria-label="ETH">cable</span>
|
||||
<span id="wifiStsIcon" class="material-icons if_wifi" style="fill:white; display: none"
|
||||
aria-label=""></span>
|
||||
|
||||
</div>
|
||||
</header>
|
||||
@@ -215,33 +219,116 @@
|
||||
<div class="card text-white mb-3">
|
||||
<div class="card-header">Usage Templates</div>
|
||||
<div class="card-body">
|
||||
<fieldset>
|
||||
<fieldset class="form-group" id="output-tmpl">
|
||||
<legend>Output</legend>
|
||||
<div class="form-check">
|
||||
<label>Output</label><br>
|
||||
<div class="form-check form-check-inline">
|
||||
<label class="form-check-label">
|
||||
<input type="radio" class="form-check-input" name="output-tmpl" id="i2s">
|
||||
I2S Dac
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<div class="form-check form-check-inline">
|
||||
<label class="form-check-label">
|
||||
<input type="radio" class="form-check-input" name="output-tmpl" id="spdif">
|
||||
SPDIF
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<div class="form-check form-check-inline">
|
||||
<label class="form-check-label">
|
||||
<input type="radio" class="form-check-input" name="output-tmpl" id="bt">
|
||||
Bluetooth
|
||||
</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="form-group"><label for="player">Player Name</label><input type="text"
|
||||
class="form-control " placeholder="Squeezelite" id="player"></div>
|
||||
<div class="form-group"><label for="optional">Optional setting (e.g. for LMS IP
|
||||
address)</label><input type="text" class="form-control" id="optional"></div>
|
||||
<fieldset>
|
||||
<div id="options">
|
||||
<div class="form-group"><label for="cmd_opt_n">Set the player name</label><input
|
||||
type="text" class="form-control sqcmd" placeholder="name" id="cmd_opt_n"></div>
|
||||
<div class="form-group"><label for="cmd_opt_s">Server</label><input type="text"
|
||||
class="form-control sqcmd" placeholder="server[:port]" id="cmd_opt_s"></div>
|
||||
<div class="form-group"><label for="cmd_opt_b">Stream and Output buffer sizes (in
|
||||
Kbytes)</label><input type="text" class="form-control sqcmd"
|
||||
placeholder="stream:output" id="cmd_opt_b"></div>
|
||||
<div class="form-group"><label for="cmd_opt_c">Restrict codecs </label><input
|
||||
type="text" class="form-control sqcmd" placeholder="codec1,codec2"
|
||||
id="cmd_opt_c"><small class="form-text text-muted">Supported: flac,pcm,mp3,ogg
|
||||
(mad,mpg for specific mp3 codec)</small></div>
|
||||
<div class="form-group"><label for="cmd_opt_C">Ouput device close timeout</label><input
|
||||
type="text" class="form-control sqcmd" placeholder="timeout"
|
||||
id="cmd_opt_C"><small class="form-text text-muted">Close output device after
|
||||
timeout seconds, default
|
||||
is to keep it open while player is 'on'</small></div>
|
||||
<div class="form-group"><label for="cmd_opt_d">Set logging level</label><input
|
||||
type="text" class="form-control sqcmd" placeholder="log=level"
|
||||
id="cmd_opt_d"><small class="form-text text-muted">Logs:
|
||||
all|slimproto|stream|decode|output, level:
|
||||
info|debug|sdebug</small></div>
|
||||
<div class="form-group"><label for="cmd_opt_e">Explicitly exclude native support of one
|
||||
or more codecs</label><input type="text" class="form-control sqcmd"
|
||||
placeholder="codec1,codec2" id="cmd_opt_e"><small
|
||||
class="form-text text-muted">Supported: flac,pcm,mp3,ogg (mad,mpg for specific
|
||||
mp3 codec)</small></div>
|
||||
<div class="form-group"><label for="cmd_opt_m">Set mac address</label><input type="text"
|
||||
class="form-control sqcmd" placeholder="mac addr" id="cmd_opt_m"><small
|
||||
class="form-text text-muted">Format: ab:cd:ef:12:34:56</small></div>
|
||||
<div class="form-group"><label for="cmd_opt_r">Sample rates supported, allows output to
|
||||
be off when squeezelite is started</label><input type="text"
|
||||
class="form-control sqcmd" placeholder="rates" id="cmd_opt_r"><small
|
||||
class="form-text text-muted"><maxrate>|<minrate><maxrate><rate1><rate2><rate3></small>
|
||||
</div>
|
||||
|
||||
<div class="form-group hide" id="cmd_opt_R">
|
||||
<label>Resample</label><br>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="resample" id="resample_none"
|
||||
suffix="" checked aint="false">
|
||||
<label class="form-check-label" for="resampleNone">No resampling</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="resample" id="resample"
|
||||
suffix=' -R' aint="false">
|
||||
<label class="form-check-label" for="resampleNone">Default</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="resample" id="resample_b"
|
||||
suffix=' -R -u b' aint="true">
|
||||
<label class="form-check-label" for="resampleBasic">Basic linear
|
||||
interpolation</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="resample" id="resample_l"
|
||||
suffix=' -R -u l' aint="true">
|
||||
<label class="form-check-label" for="resample13Taps">13 taps</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="resample" id="resample_m"
|
||||
suffix=' -R -u m' aint="true">
|
||||
<label class="form-check-label" for="resample21Taps">21 taps</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" name="interpolate"
|
||||
id="resample_i" suffix=":i">
|
||||
<label class="form-check-label" for="interpolate">Interpolate filter
|
||||
coefficients</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group"><label for="cmd_opt_Z">Report rate to server in helo as the
|
||||
maximum sample rate we can support</label><input type="text"
|
||||
class="form-control" placeholder="rate" id="cmd_opt_Z"></div>
|
||||
<div class="form-group">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
<input class="form-check-input" type="checkbox" id="cmd_opt_W" value=""
|
||||
checked="">
|
||||
Read wave and aiff format from header, ignore server parameters
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
<input class="form-check-input" type="checkbox" id="disable-squeezelite"
|
||||
|
||||
@@ -28,71 +28,95 @@ Object.assign(Date.prototype, {
|
||||
return this.toLocaleString(undefined, opt);
|
||||
},
|
||||
});
|
||||
function handleNVSVisible(){
|
||||
function get_control_option_value(obj) {
|
||||
let ctrl,id,val,opt;
|
||||
let radio = false;
|
||||
let checked = false;
|
||||
if (typeof (obj) === 'string') {
|
||||
id = obj;
|
||||
ctrl = $(`#${id}`);
|
||||
} else {
|
||||
id = $(obj).attr('id');
|
||||
ctrl = $(obj);
|
||||
}
|
||||
if(ctrl.attr('type') === 'checkbox'){
|
||||
opt = $(obj).checked?id.replace('cmd_opt_', ''):'';
|
||||
val = true;
|
||||
}
|
||||
else {
|
||||
opt = id.replace('cmd_opt_', '');
|
||||
val = $(obj).val();
|
||||
val = `${val.includes(" ") ? '"' : ''}${val}${val.includes(" ") ? '"' : ''}`;
|
||||
}
|
||||
|
||||
return { opt, val };
|
||||
}
|
||||
function handleNVSVisible() {
|
||||
let nvs_previous_checked = isEnabled(Cookies.get("show-nvs"));
|
||||
$('input#show-nvs')[0].checked = nvs_previous_checked ;
|
||||
$('input#show-nvs')[0].checked = nvs_previous_checked;
|
||||
if ($('input#show-nvs')[0].checked || recovery) {
|
||||
$('*[href*="-nvs"]').show();
|
||||
} else {
|
||||
$('*[href*="-nvs"]').hide();
|
||||
$('*[href*="-nvs"]').show();
|
||||
} else {
|
||||
$('*[href*="-nvs"]').hide();
|
||||
}
|
||||
}
|
||||
function concatenateOptions(options) {
|
||||
let commandLine = ' ';
|
||||
for (const [option, value] of Object.entries(options)) {
|
||||
if (option !== 'n' && option !== 'o') {
|
||||
commandLine += `-${option} `;
|
||||
if (value !== true) {
|
||||
commandLine += `${value} `;
|
||||
}
|
||||
}
|
||||
}
|
||||
return commandLine;
|
||||
}
|
||||
|
||||
|
||||
function isEnabled(val) {
|
||||
return val!=undefined && typeof val === 'string' && val.match("[Yy1]");
|
||||
return val != undefined && typeof val === 'string' && val.match("[Yy1]");
|
||||
}
|
||||
|
||||
const nvsTypes = {
|
||||
NVS_TYPE_U8: 0x01,
|
||||
|
||||
/*! < Type uint8_t */
|
||||
NVS_TYPE_I8: 0x11,
|
||||
|
||||
/*! < Type int8_t */
|
||||
NVS_TYPE_U16: 0x02,
|
||||
|
||||
/*! < Type uint16_t */
|
||||
NVS_TYPE_I16: 0x12,
|
||||
|
||||
/*! < Type int16_t */
|
||||
NVS_TYPE_U32: 0x04,
|
||||
|
||||
/*! < Type uint32_t */
|
||||
NVS_TYPE_I32: 0x14,
|
||||
|
||||
/*! < Type int32_t */
|
||||
NVS_TYPE_U64: 0x08,
|
||||
|
||||
/*! < Type uint64_t */
|
||||
NVS_TYPE_I64: 0x18,
|
||||
|
||||
/*! < Type int64_t */
|
||||
NVS_TYPE_STR: 0x21,
|
||||
|
||||
/*! < Type string */
|
||||
NVS_TYPE_BLOB: 0x42,
|
||||
|
||||
/*! < Type blob */
|
||||
NVS_TYPE_ANY: 0xff /*! < Must be last */,
|
||||
};
|
||||
const btIcons = {
|
||||
bt_playing: {'label':'','icon': 'media_bluetooth_on'},
|
||||
bt_disconnected: {'label':'','icon': 'media_bluetooth_off'},
|
||||
bt_neutral: {'label':'','icon': 'bluetooth'},
|
||||
bt_connecting: {'label':'','icon': 'bluetooth_searching'},
|
||||
bt_connected: {'label':'','icon': 'bluetooth_connected'},
|
||||
bt_disabled: {'label':'','icon': 'bluetooth_disabled'},
|
||||
play_arrow: {'label':'','icon': 'play_circle_filled'},
|
||||
pause: {'label':'','icon': 'pause_circle'},
|
||||
stop: {'label':'','icon': 'stop_circle'},
|
||||
'': {'label':'','icon':''}
|
||||
bt_playing: { 'label': '', 'icon': 'media_bluetooth_on' },
|
||||
bt_disconnected: { 'label': '', 'icon': 'media_bluetooth_off' },
|
||||
bt_neutral: { 'label': '', 'icon': 'bluetooth' },
|
||||
bt_connecting: { 'label': '', 'icon': 'bluetooth_searching' },
|
||||
bt_connected: { 'label': '', 'icon': 'bluetooth_connected' },
|
||||
bt_disabled: { 'label': '', 'icon': 'bluetooth_disabled' },
|
||||
play_arrow: { 'label': '', 'icon': 'play_circle_filled' },
|
||||
pause: { 'label': '', 'icon': 'pause_circle' },
|
||||
stop: { 'label': '', 'icon': 'stop_circle' },
|
||||
'': { 'label': '', 'icon': '' }
|
||||
};
|
||||
const batIcons = [
|
||||
{ icon: "battery_0_bar", label:'▪', ranges: [{ f: 5.8, t: 6.8 }, { f: 8.8, t: 10.2 }] },
|
||||
{ icon: "battery_2_bar", label:'▪▪', ranges: [{ f: 6.8, t: 7.4 }, { f: 10.2, t: 11.1 }] },
|
||||
{ icon: "battery_3_bar", label:'▪▪▪', ranges: [{ f: 7.4, t: 7.5 }, { f: 11.1, t: 11.25 }] },
|
||||
{ icon: "battery_4_bar", label:'▪▪▪▪', ranges: [{ f: 7.5, t: 7.8 }, { f: 11.25, t: 11.7 }] }
|
||||
{ icon: "battery_0_bar", label: '▪', ranges: [{ f: 5.8, t: 6.8 }, { f: 8.8, t: 10.2 }] },
|
||||
{ icon: "battery_2_bar", label: '▪▪', ranges: [{ f: 6.8, t: 7.4 }, { f: 10.2, t: 11.1 }] },
|
||||
{ icon: "battery_3_bar", label: '▪▪▪', ranges: [{ f: 7.4, t: 7.5 }, { f: 11.1, t: 11.25 }] },
|
||||
{ icon: "battery_4_bar", label: '▪▪▪▪', ranges: [{ f: 7.5, t: 7.8 }, { f: 11.25, t: 11.7 }] }
|
||||
];
|
||||
const btStateIcons = [
|
||||
{ desc: 'Idle', sub: ['bt_neutral'] },
|
||||
@@ -162,7 +186,7 @@ let flashState = {
|
||||
$('.flact').prop('disabled', false);
|
||||
$('#flashfilename').value = null;
|
||||
$('#fw-url-input').value = null;
|
||||
if(!this.isStateError()){
|
||||
if (!this.isStateError()) {
|
||||
$('span#flash-status').html('');
|
||||
$('#fwProgressLabel').parent().removeClass('bg-danger');
|
||||
}
|
||||
@@ -357,8 +381,8 @@ let flashState = {
|
||||
const xhttp = new XMLHttpRequest();
|
||||
xhttp.context = this;
|
||||
var boundHandleUploadProgressEvent = this.HandleUploadProgressEvent.bind(this);
|
||||
var boundsetOTAError=this.setOTAError.bind(this);
|
||||
xhttp.upload.addEventListener("progress",boundHandleUploadProgressEvent, false);
|
||||
var boundsetOTAError = this.setOTAError.bind(this);
|
||||
xhttp.upload.addEventListener("progress", boundHandleUploadProgressEvent, false);
|
||||
xhttp.onreadystatechange = function () {
|
||||
if (xhttp.readyState === 4) {
|
||||
if (xhttp.status === 0 || xhttp.status === 404) {
|
||||
@@ -464,11 +488,89 @@ window.handleReboot = function (link) {
|
||||
$('#reboot_nav').removeClass('active'); delayReboot(500, '', link);
|
||||
}
|
||||
}
|
||||
function isConnected(){
|
||||
return ConnectedTo.hasOwnProperty('ip') && ConnectedTo.ip!='0.0.0.0'&& ConnectedTo.ip!='';
|
||||
|
||||
function parseSqueezeliteCommandLine(commandLine) {
|
||||
const options = {};
|
||||
let output, name;
|
||||
let otherValues = '';
|
||||
|
||||
const argRegex = /("[^"]+"|'[^']+'|\S+)/g;
|
||||
const args = commandLine.match(argRegex);
|
||||
|
||||
let i = 0;
|
||||
|
||||
while (i < args.length) {
|
||||
const arg = args[i];
|
||||
|
||||
if (arg.startsWith('-')) {
|
||||
const option = arg.slice(1);
|
||||
|
||||
if (option === '') {
|
||||
otherValues += args.slice(i).join(' ');
|
||||
break;
|
||||
}
|
||||
|
||||
let value = true;
|
||||
|
||||
if (i + 1 < args.length && !args[i + 1].startsWith('-')) {
|
||||
value = args[i + 1].replace(/"/g, '').replace(/'/g, '');
|
||||
i++;
|
||||
}
|
||||
|
||||
options[option] = value;
|
||||
} else {
|
||||
otherValues += arg + ' ';
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
otherValues = otherValues.trim();
|
||||
output = getOutput(options);
|
||||
name = getName(options);
|
||||
let otherOptions={btname:null,n:null};
|
||||
// assign o and n options to otheroptions if present
|
||||
if (options.o && output.toUpperCase() === 'BT') {
|
||||
let temp = parseSqueezeliteCommandLine(options.o);
|
||||
if(temp.name) {
|
||||
otherOptions.btname = temp.name;
|
||||
}
|
||||
delete options.o;
|
||||
}
|
||||
if (options.n) {
|
||||
otherOptions['n'] = options.n;
|
||||
delete options.n;
|
||||
}
|
||||
return { name, output, options, otherValues,otherOptions };
|
||||
}
|
||||
function getIcon(icons){
|
||||
return isConnected()?icons.icon:icons.label;
|
||||
|
||||
function getOutput(options) {
|
||||
let output;
|
||||
if (options.o){
|
||||
output = options.o.replace(/"/g, '').replace(/'/g, '');
|
||||
/* set output as the first alphanumerical word in the command line */
|
||||
if (output.indexOf(' ') > 0) {
|
||||
output = output.substring(0, output.indexOf(' '));
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
function getName(options) {
|
||||
let name;
|
||||
/* if n option present, assign to name variable */
|
||||
if (options.n){
|
||||
name = options.n.replace(/"/g, '').replace(/'/g, '');
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
function isConnected() {
|
||||
return ConnectedTo.hasOwnProperty('ip') && ConnectedTo.ip != '0.0.0.0' && ConnectedTo.ip != '';
|
||||
}
|
||||
function getIcon(icons) {
|
||||
return isConnected() ? icons.icon : icons.label;
|
||||
}
|
||||
function handlebtstate(data) {
|
||||
let icon = '';
|
||||
@@ -476,7 +578,7 @@ function handlebtstate(data) {
|
||||
if (data.bt_status !== undefined && data.bt_sub_status !== undefined) {
|
||||
const iconindex = btStateIcons[data.bt_status].sub[data.bt_sub_status];
|
||||
if (iconindex) {
|
||||
icon = btIcons[iconindex];
|
||||
icon = btIcons[iconindex];
|
||||
tt = btStateIcons[data.bt_status].desc;
|
||||
} else {
|
||||
icon = btIcons.bt_connected;
|
||||
@@ -485,19 +587,28 @@ function handlebtstate(data) {
|
||||
}
|
||||
|
||||
$('#o_type').attr('title', tt);
|
||||
$('#o_bt').html(isConnected()?icon.label:icon.text);
|
||||
$('#o_bt').html(isConnected() ? icon.label : icon.text);
|
||||
}
|
||||
function handleTemplateTypeRadio(outtype) {
|
||||
$('#o_type').children('span').css({ display: 'none' });
|
||||
let changed = false;
|
||||
if (outtype === 'bt') {
|
||||
changed = output !== 'bt' && output !== '';
|
||||
output = 'bt';
|
||||
} else if (outtype === 'spdif') {
|
||||
changed = output !== 'spdif' && output !== '';
|
||||
output = 'spdif';
|
||||
} else {
|
||||
changed = output !== 'i2s' && output !== '';
|
||||
output = 'i2s';
|
||||
}
|
||||
$('#' + output).prop('checked', true);
|
||||
$('#o_' + output).css({ display: 'inline' });
|
||||
if (changed) {
|
||||
Object.keys(commandDefaults[output]).forEach(function (key) {
|
||||
$(`#cmd_opt_${key}`).val(commandDefaults[output][key]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function handleExceptionResponse(xhr, _ajaxOptions, thrownError) {
|
||||
@@ -545,7 +656,17 @@ let releaseURL =
|
||||
|
||||
let recovery = false;
|
||||
let messagesHeld = false;
|
||||
const commandHeader = 'squeezelite -b 500:2000 -d all=info -C 30 -W';
|
||||
let commandBTSinkName = '';
|
||||
const commandHeader = 'squeezelite ';
|
||||
const commandDefaults = {
|
||||
i2s: { b: "500:2000", C: "30", W: "", Z: "96000", o: "I2S" },
|
||||
spdif: { b: "500:2000", C: "30", W: "", Z: "48000", o: "SPDIF" },
|
||||
bt: { b: "500:2000", C: "30", W: "", Z: "44100", o: "BT" },
|
||||
};
|
||||
let validOptions = {
|
||||
codecs: ['flac', 'pcm', 'mp3', 'ogg', 'aac', 'wma', 'alac', 'dsd', 'mad', 'mpg']
|
||||
};
|
||||
|
||||
//let blockFlashButton = false;
|
||||
let apList = null;
|
||||
//let selectedSSID = '';
|
||||
@@ -559,6 +680,7 @@ let hostName = '';
|
||||
let versionName = 'Squeezelite-ESP32';
|
||||
let prevmessage = '';
|
||||
let project_name = versionName;
|
||||
let depth = 16;
|
||||
let board_model = '';
|
||||
let platform_name = versionName;
|
||||
let preset_name = '';
|
||||
@@ -690,11 +812,6 @@ function handleHWPreset(allfields, reboot) {
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -773,23 +890,34 @@ function delayReboot(duration, cmdname, ota = 'reboot') {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
window.saveAutoexec1 = function (apply) {
|
||||
showCmdMessage('cfg-audio-tmpl', 'MESSAGING_INFO', 'Saving.\n', false);
|
||||
let commandLine = commandHeader + ' -n "' + $('#player').val() + '"';
|
||||
let commandLine = `${commandHeader} -o ${output} `;
|
||||
$('.sqcmd').each(function () {
|
||||
let { opt, val } = get_control_option_value($(this));
|
||||
if ((opt && opt.length>0 ) && typeof(val) == 'boolean' || val.length > 0) {
|
||||
const optStr=opt===':'?opt:(` -${opt} `);
|
||||
val = typeof(val) == 'boolean'?'':val;
|
||||
commandLine += `${optStr} ${val}`;
|
||||
}
|
||||
});
|
||||
const resample=$('#cmd_opt_R input[name=resample]:checked');
|
||||
if (resample.length>0 && resample.attr('suffix')!=='') {
|
||||
commandLine += resample.attr('suffix');
|
||||
// now check resample_i option and if checked, add suffix to command line
|
||||
if ($('#resample_i').is(":checked") && resample.attr('aint') =='true') {
|
||||
commandLine += $('#resample_i').attr('suffix');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (output === 'bt') {
|
||||
commandLine += ' -o "BT" -R -Z 192000';
|
||||
showCmdMessage(
|
||||
'cfg-audio-tmpl',
|
||||
'MESSAGING_INFO',
|
||||
'Remember to configure the Bluetooth audio device name.\n',
|
||||
true
|
||||
);
|
||||
} else if (output === 'spdif') {
|
||||
commandLine += ' -o SPDIF -Z 192000';
|
||||
} else {
|
||||
commandLine += ' -o I2S';
|
||||
}
|
||||
if ($('#optional').val() !== '') {
|
||||
commandLine += ' ' + $('#optional').val();
|
||||
}
|
||||
commandLine += concatenateOptions(options);
|
||||
const data = {
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
@@ -880,9 +1008,33 @@ window.handleConnect = function () {
|
||||
// now we can re-set the intervals regardless of result
|
||||
|
||||
}
|
||||
function renderError(opt,error){
|
||||
const fieldname = `cmd_opt_${opt}`;
|
||||
let errorFieldName=`${fieldname}-error`;
|
||||
let errorField=$(`#${errorFieldName}`);
|
||||
let field=$(`#${fieldname}`);
|
||||
|
||||
if (!errorField || errorField.length ==0) {
|
||||
field.after(`<div id="${errorFieldName}" class="invalid-feedback"></div>`);
|
||||
errorField=$(`#${errorFieldName}`);
|
||||
}
|
||||
if(error.length ==0){
|
||||
errorField.hide();
|
||||
field.removeClass('is-invalid');
|
||||
field.addClass('is-valid');
|
||||
errorField.text('');
|
||||
}
|
||||
else {
|
||||
errorField.show();
|
||||
errorField.text(error);
|
||||
field.removeClass('is-valid');
|
||||
field.addClass('is-invalid');
|
||||
}
|
||||
return errorField;
|
||||
}
|
||||
$(document).ready(function () {
|
||||
$('.material-icons').each(function (_index, entry) {
|
||||
entry.attributes['icon']=entry.textContent;
|
||||
entry.attributes['icon'] = entry.textContent;
|
||||
});
|
||||
setIcons(true);
|
||||
handleNVSVisible();
|
||||
@@ -908,6 +1060,43 @@ $(document).ready(function () {
|
||||
|
||||
});
|
||||
setTimeout(refreshAP, 1500);
|
||||
/* add validation for cmd_opt_c, which accepts a comma separated list.
|
||||
getting known codecs from validOptions.codecs array
|
||||
use bootstrap classes to highlight the error with an overlay message */
|
||||
$('#options input').on('input', function () {
|
||||
const { opt, val } = get_control_option_value(this);
|
||||
if (opt === 'c' || opt === 'e') {
|
||||
const fieldname = `cmd_opt_${opt}_codec-error`;
|
||||
|
||||
const values = val.split(',').map(function (item) {
|
||||
return item.trim();
|
||||
});
|
||||
/* get a list of invalid codecs */
|
||||
const invalid = values.filter(function (item) {
|
||||
return !validOptions.codecs.includes(item);
|
||||
});
|
||||
renderError(opt,invalid.length > 0 ? `Invalid codec(s) ${invalid.join(', ')}` : '');
|
||||
}
|
||||
/* add validation for cmd_opt_m, which accepts a mac_address */
|
||||
if (opt === 'm') {
|
||||
const mac_regex = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/;
|
||||
renderError(opt,mac_regex.test(val) ? '' : 'Invalid MAC address');
|
||||
}
|
||||
if (opt === 'r') {
|
||||
const rateRegex = /^(\d+\.?\d*|\.\d+)-(\d+\.?\d*|\.\d+)$|^(\d+\.?\d*)$|^(\d+\.?\d*,)+\d+\.?\d*$/;
|
||||
renderError(opt,rateRegex.test(val)?'':`Invalid rate(s) ${val}. Acceptable format: <maxrate>|<minrate>-<maxrate>|<rate1>,<rate2>,<rate3>`);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$('#WifiConnectDialog')[0].addEventListener('shown.bs.modal', function (event) {
|
||||
$("*[class*='connecting']").hide();
|
||||
@@ -1029,7 +1218,7 @@ $(document).ready(function () {
|
||||
|
||||
$('input#show-nvs').on('click', function () {
|
||||
this.checked = this.checked ? 1 : 0;
|
||||
Cookies.set("show-nvs", this.checked?'Y':'N');
|
||||
Cookies.set("show-nvs", this.checked ? 'Y' : 'N');
|
||||
handleNVSVisible();
|
||||
});
|
||||
$('#btn_reboot_recovery').on('click', function () {
|
||||
@@ -1048,7 +1237,7 @@ $(document).ready(function () {
|
||||
saveAutoexec1(true);
|
||||
});
|
||||
$('#btn_disconnect').on('click', function () {
|
||||
ConnectedTo={};
|
||||
ConnectedTo = {};
|
||||
refreshAPHTML2();
|
||||
$.ajax({
|
||||
url: '/connect.json',
|
||||
@@ -1303,15 +1492,15 @@ window.setURL = function (button) {
|
||||
|
||||
function rssiToIcon(rssi) {
|
||||
if (rssi >= -55) {
|
||||
return {'label':'****','icon':`signal_wifi_statusbar_4_bar`};
|
||||
return { 'label': '****', 'icon': `signal_wifi_statusbar_4_bar` };
|
||||
} else if (rssi >= -60) {
|
||||
return {'label':'***','icon':`network_wifi_3_bar`};
|
||||
return { 'label': '***', 'icon': `network_wifi_3_bar` };
|
||||
} else if (rssi >= -65) {
|
||||
return {'label':'**','icon':`network_wifi_2_bar`};
|
||||
return { 'label': '**', 'icon': `network_wifi_2_bar` };
|
||||
} else if (rssi >= -70) {
|
||||
return {'label':'*','icon':`network_wifi_1_bar`};
|
||||
return { 'label': '*', 'icon': `network_wifi_1_bar` };
|
||||
} else {
|
||||
return {'label':'.','icon':`signal_wifi_statusbar_null`};
|
||||
return { 'label': '.', 'icon': `signal_wifi_statusbar_null` };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1339,9 +1528,9 @@ function refreshAP() {
|
||||
});
|
||||
}
|
||||
function formatAP(ssid, rssi, auth) {
|
||||
const rssi_icon=rssiToIcon(rssi);
|
||||
const auth_icon={label:auth == 0 ? '🔓' : '🔒',icon:auth == 0 ? 'no_encryption' : 'lock'};
|
||||
|
||||
const rssi_icon = rssiToIcon(rssi);
|
||||
const auth_icon = { label: auth == 0 ? '🔓' : '🔒', icon: auth == 0 ? 'no_encryption' : 'lock' };
|
||||
|
||||
return `<tr data-bs-toggle="modal" data-bs-target="#WifiConnectDialog"><td></td><td>${ssid}</td><td>
|
||||
<span class="material-icons" style="fill:white; display: inline" aria-label="${rssi_icon.label}" icon="${rssi_icon.icon}" >${getIcon(rssi_icon)}</span>
|
||||
</td><td>
|
||||
@@ -1512,9 +1701,9 @@ function getMessages() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
setTimeout(getMessages,messageInterval);
|
||||
setTimeout(getMessages, messageInterval);
|
||||
}).fail(function (xhr, ajaxOptions, thrownError) {
|
||||
|
||||
|
||||
if (xhr.status == 404) {
|
||||
$('.orec').hide(); // system commands won't be available either
|
||||
messagesHeld = true;
|
||||
@@ -1522,15 +1711,15 @@ function getMessages() {
|
||||
else {
|
||||
handleExceptionResponse(xhr, ajaxOptions, thrownError);
|
||||
}
|
||||
if(xhr.status == 0 && xhr.readyState ==0){
|
||||
if (xhr.status == 0 && xhr.readyState == 0) {
|
||||
// probably a timeout. Target is rebooting?
|
||||
setTimeout(getMessages,messageInterval*2); // increase duration if a failure happens
|
||||
setTimeout(getMessages, messageInterval * 2); // increase duration if a failure happens
|
||||
}
|
||||
else if(!messagesHeld){
|
||||
else if (!messagesHeld) {
|
||||
// 404 here means we rebooted to an old recovery
|
||||
setTimeout(getMessages,messageInterval); // increase duration if a failure happens
|
||||
setTimeout(getMessages, messageInterval); // increase duration if a failure happens
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1552,18 +1741,18 @@ function handleRecoveryMode(data) {
|
||||
$('#boot-button').html('Reboot');
|
||||
$('#boot-form').attr('action', '/reboot_ota.json');
|
||||
} else {
|
||||
if(!recovery && messagesHeld){
|
||||
messagesHeld=false;
|
||||
setTimeout(getMessages,messageInterval); // increase duration if a failure happens
|
||||
if (!recovery && messagesHeld) {
|
||||
messagesHeld = false;
|
||||
setTimeout(getMessages, messageInterval); // increase duration if a failure happens
|
||||
}
|
||||
recovery = false;
|
||||
|
||||
|
||||
$('.recovery_element').hide();
|
||||
$('.ota_element').show();
|
||||
$('#boot-button').html('Recovery');
|
||||
$('#boot-form').attr('action', '/recovery.json');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function hasConnectionChanged(data) {
|
||||
@@ -1645,9 +1834,9 @@ function handleWifiDialog(data) {
|
||||
|
||||
}
|
||||
}
|
||||
function setIcons(offline){
|
||||
function setIcons(offline) {
|
||||
$('.material-icons').each(function (_index, entry) {
|
||||
entry.textContent = entry.attributes[offline?'aria-label':'icon'].value;
|
||||
entry.textContent = entry.attributes[offline ? 'aria-label' : 'icon'].value;
|
||||
});
|
||||
}
|
||||
function handleNetworkStatus(data) {
|
||||
@@ -1682,13 +1871,13 @@ function batteryToIcon(voltage) {
|
||||
for (const iconEntry of batIcons) {
|
||||
for (const entryRanges of iconEntry.ranges) {
|
||||
if (inRange(voltage, entryRanges.f, entryRanges.t)) {
|
||||
return { label: iconEntry.label, icon:iconEntry.icon};
|
||||
return { label: iconEntry.label, icon: iconEntry.icon };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return {label:'▪▪▪▪',icon:"battery_full"};
|
||||
return { label: '▪▪▪▪', icon: "battery_full" };
|
||||
}
|
||||
function checkStatus() {
|
||||
$.ajaxSetup({
|
||||
@@ -1700,6 +1889,16 @@ function checkStatus() {
|
||||
handleNetworkStatus(data);
|
||||
handlebtstate(data);
|
||||
flashState.EventTargetStatus(data);
|
||||
if(data.depth) {
|
||||
depth = data.depth;
|
||||
if(depth==16){
|
||||
$('#cmd_opt_R').show();
|
||||
}
|
||||
else{
|
||||
$('#cmd_opt_R').hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (data.project_name && data.project_name !== '') {
|
||||
project_name = data.project_name;
|
||||
@@ -1717,10 +1916,10 @@ function checkStatus() {
|
||||
$('span#flash-status').html('');
|
||||
}
|
||||
if (data.Voltage) {
|
||||
const bat_icon=batteryToIcon(data.Voltage);
|
||||
const bat_icon = batteryToIcon(data.Voltage);
|
||||
$('#battery').html(`${getIcon(bat_icon)}`);
|
||||
$('#battery').attr("aria-label",bat_icon.label);
|
||||
$('#battery').attr("icon",bat_icon.icon);
|
||||
$('#battery').attr("aria-label", bat_icon.label);
|
||||
$('#battery').attr("icon", bat_icon.icon);
|
||||
$('#battery').show();
|
||||
} else {
|
||||
$('#battery').hide();
|
||||
@@ -1757,15 +1956,15 @@ function checkStatus() {
|
||||
});
|
||||
}
|
||||
$('#o_jack').css({ display: Number(data.Jack) ? 'inline' : 'none' });
|
||||
setTimeout(checkStatus,statusInterval);
|
||||
setTimeout(checkStatus, statusInterval);
|
||||
}).fail(function (xhr, ajaxOptions, thrownError) {
|
||||
handleExceptionResponse(xhr, ajaxOptions, thrownError);
|
||||
if(xhr.status == 0 && xhr.readyState ==0){
|
||||
if (xhr.status == 0 && xhr.readyState == 0) {
|
||||
// probably a timeout. Target is rebooting?
|
||||
setTimeout(checkStatus,messageInterval*2); // increase duration if a failure happens
|
||||
setTimeout(checkStatus, messageInterval * 2); // increase duration if a failure happens
|
||||
}
|
||||
else {
|
||||
setTimeout(checkStatus,messageInterval); // increase duration if a failure happens
|
||||
setTimeout(checkStatus, messageInterval); // increase duration if a failure happens
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1995,6 +2194,7 @@ function getConfig() {
|
||||
$('#nvsTable tr').remove();
|
||||
const data = (entries.config ? entries.config : entries);
|
||||
SystemConfig = data;
|
||||
commandBTSinkName = '';
|
||||
Object.keys(data)
|
||||
.sort()
|
||||
.forEach(function (key) {
|
||||
@@ -2006,20 +2206,15 @@ function getConfig() {
|
||||
$('#disable-squeezelite')[0].checked = false;
|
||||
}
|
||||
} else if (key === 'autoexec1') {
|
||||
const re = /-o\s?(["][^"]*["]|[^-]+)/g;
|
||||
const m = re.exec(val);
|
||||
if (m[1].toUpperCase().startsWith('I2S')) {
|
||||
handleTemplateTypeRadio('i2s');
|
||||
} else if (m[1].toUpperCase().startsWith('SPDIF')) {
|
||||
handleTemplateTypeRadio('spdif');
|
||||
} else if (m[1].toUpperCase().startsWith('"BT')) {
|
||||
handleTemplateTypeRadio('bt');
|
||||
}
|
||||
/* call new function to parse the squeezelite options */
|
||||
processSqueezeliteCommandLine(val);
|
||||
} else if (key === 'host_name') {
|
||||
val = val.replaceAll('"', '');
|
||||
$('input#dhcp-name1').val(val);
|
||||
$('input#dhcp-name2').val(val);
|
||||
$('#player').val(val);
|
||||
if ($('#cmd_opt_n').length == 0) {
|
||||
$('#cmd_opt_n').val(val);
|
||||
}
|
||||
document.title = val;
|
||||
hostName = val;
|
||||
} else if (key === 'rel_api') {
|
||||
@@ -2054,6 +2249,10 @@ function getConfig() {
|
||||
);
|
||||
$('input#' + key).val(data[key].value);
|
||||
});
|
||||
if(commandBTSinkName.length > 0) {
|
||||
// persist the sink name found in the autoexec1 command line
|
||||
$('#cfg-audio-bt_source-sink_name').val(commandBTSinkName);
|
||||
}
|
||||
$('tbody#nvsTable').append(
|
||||
"<tr><td><input type='text' class='form-control' id='nvs-new-key' placeholder='new key'></td><td><input type='text' class='form-control' id='nvs-new-value' placeholder='new value' nvs_type=33 ></td></tr>"
|
||||
);
|
||||
@@ -2083,6 +2282,40 @@ function getConfig() {
|
||||
handleExceptionResponse(xhr, ajaxOptions, thrownError);
|
||||
});
|
||||
}
|
||||
|
||||
function processSqueezeliteCommandLine(val) {
|
||||
const parsed = parseSqueezeliteCommandLine(val);
|
||||
if (parsed.output.toUpperCase().startsWith('I2S')) {
|
||||
handleTemplateTypeRadio('i2s');
|
||||
} else if (parsed.output.toUpperCase().startsWith('SPDIF')) {
|
||||
handleTemplateTypeRadio('spdif');
|
||||
} else if (parsed.output.toUpperCase().startsWith('BT')) {
|
||||
if(parsed.otherOptions.btname){
|
||||
commandBTSinkName= parsed.otherOptions.btname;
|
||||
}
|
||||
handleTemplateTypeRadio('bt');
|
||||
}
|
||||
Object.keys(parsed.options).forEach(function (key) {
|
||||
const option = parsed.options[key];
|
||||
if (!$(`#cmd_opt_${key}`).hasOwnProperty('checked')) {
|
||||
$(`#cmd_opt_${key}`).val(option);
|
||||
} else {
|
||||
$(`#cmd_opt_${key}`)[0].checked = option;
|
||||
}
|
||||
});
|
||||
if (parsed.options.hasOwnProperty('u')) {
|
||||
// parse -u v[:i] and check the appropriate radio button with id #resample_v
|
||||
const [resampleValue, resampleInterpolation] = parsed.options.u.split(':');
|
||||
$(`#resample_${resampleValue}`).prop('checked', true);
|
||||
// if resampleinterpolation is set, check resample_i checkbox
|
||||
if (resampleInterpolation) {
|
||||
$('#resample_i').prop('checked', true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function showLocalMessage(message, severity) {
|
||||
const msg = {
|
||||
message: message,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
target_add_binary_data( __idf_wifi-manager webapp/dist/css/index.7964a13ec910c36040b8.css.gz BINARY)
|
||||
target_add_binary_data( __idf_wifi-manager webapp/dist/css/index.cd56ff129e3113d8cd3a.css.gz BINARY)
|
||||
target_add_binary_data( __idf_wifi-manager webapp/dist/favicon-32x32.png BINARY)
|
||||
target_add_binary_data( __idf_wifi-manager webapp/dist/index.html.gz BINARY)
|
||||
target_add_binary_data( __idf_wifi-manager webapp/dist/js/index.44748c.bundle.js.gz BINARY)
|
||||
target_add_binary_data( __idf_wifi-manager webapp/dist/js/node_vendors.44748c.bundle.js.gz BINARY)
|
||||
target_add_binary_data( __idf_wifi-manager webapp/dist/js/index.0748ab.bundle.js.gz BINARY)
|
||||
target_add_binary_data( __idf_wifi-manager webapp/dist/js/node_vendors.0748ab.bundle.js.gz BINARY)
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
// Automatically generated. Do not edit manually!.
|
||||
#include <inttypes.h>
|
||||
extern const uint8_t _index_7964a13ec910c36040b8_css_gz_start[] asm("_binary_index_7964a13ec910c36040b8_css_gz_start");
|
||||
extern const uint8_t _index_7964a13ec910c36040b8_css_gz_end[] asm("_binary_index_7964a13ec910c36040b8_css_gz_end");
|
||||
extern const uint8_t _index_cd56ff129e3113d8cd3a_css_gz_start[] asm("_binary_index_cd56ff129e3113d8cd3a_css_gz_start");
|
||||
extern const uint8_t _index_cd56ff129e3113d8cd3a_css_gz_end[] asm("_binary_index_cd56ff129e3113d8cd3a_css_gz_end");
|
||||
extern const uint8_t _favicon_32x32_png_start[] asm("_binary_favicon_32x32_png_start");
|
||||
extern const uint8_t _favicon_32x32_png_end[] asm("_binary_favicon_32x32_png_end");
|
||||
extern const uint8_t _index_html_gz_start[] asm("_binary_index_html_gz_start");
|
||||
extern const uint8_t _index_html_gz_end[] asm("_binary_index_html_gz_end");
|
||||
extern const uint8_t _index_44748c_bundle_js_gz_start[] asm("_binary_index_44748c_bundle_js_gz_start");
|
||||
extern const uint8_t _index_44748c_bundle_js_gz_end[] asm("_binary_index_44748c_bundle_js_gz_end");
|
||||
extern const uint8_t _node_vendors_44748c_bundle_js_gz_start[] asm("_binary_node_vendors_44748c_bundle_js_gz_start");
|
||||
extern const uint8_t _node_vendors_44748c_bundle_js_gz_end[] asm("_binary_node_vendors_44748c_bundle_js_gz_end");
|
||||
extern const uint8_t _index_0748ab_bundle_js_gz_start[] asm("_binary_index_0748ab_bundle_js_gz_start");
|
||||
extern const uint8_t _index_0748ab_bundle_js_gz_end[] asm("_binary_index_0748ab_bundle_js_gz_end");
|
||||
extern const uint8_t _node_vendors_0748ab_bundle_js_gz_start[] asm("_binary_node_vendors_0748ab_bundle_js_gz_start");
|
||||
extern const uint8_t _node_vendors_0748ab_bundle_js_gz_end[] asm("_binary_node_vendors_0748ab_bundle_js_gz_end");
|
||||
const char * resource_lookups[] = {
|
||||
"/css/index.7964a13ec910c36040b8.css.gz",
|
||||
"/css/index.cd56ff129e3113d8cd3a.css.gz",
|
||||
"/favicon-32x32.png",
|
||||
"/index.html.gz",
|
||||
"/js/index.44748c.bundle.js.gz",
|
||||
"/js/node_vendors.44748c.bundle.js.gz",
|
||||
"/js/index.0748ab.bundle.js.gz",
|
||||
"/js/node_vendors.0748ab.bundle.js.gz",
|
||||
""
|
||||
};
|
||||
const uint8_t * resource_map_start[] = {
|
||||
_index_7964a13ec910c36040b8_css_gz_start,
|
||||
_index_cd56ff129e3113d8cd3a_css_gz_start,
|
||||
_favicon_32x32_png_start,
|
||||
_index_html_gz_start,
|
||||
_index_44748c_bundle_js_gz_start,
|
||||
_node_vendors_44748c_bundle_js_gz_start
|
||||
_index_0748ab_bundle_js_gz_start,
|
||||
_node_vendors_0748ab_bundle_js_gz_start
|
||||
};
|
||||
const uint8_t * resource_map_end[] = {
|
||||
_index_7964a13ec910c36040b8_css_gz_end,
|
||||
_index_cd56ff129e3113d8cd3a_css_gz_end,
|
||||
_favicon_32x32_png_end,
|
||||
_index_html_gz_end,
|
||||
_index_44748c_bundle_js_gz_end,
|
||||
_node_vendors_44748c_bundle_js_gz_end
|
||||
_index_0748ab_bundle_js_gz_end,
|
||||
_node_vendors_0748ab_bundle_js_gz_end
|
||||
};
|
||||
|
||||
@@ -10,6 +10,7 @@ const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
|
||||
const webpack = require("webpack");
|
||||
const path = require("path");
|
||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||
|
||||
const globSync = require("glob").sync;
|
||||
const glob = require('glob');
|
||||
const { merge } = require('webpack-merge');
|
||||
@@ -39,7 +40,15 @@ class BuildEventsHook {
|
||||
module.exports = (env, options) => (
|
||||
merge(
|
||||
env.WEBPACK_SERVE ? devserver : {},
|
||||
env.ANALYZE_SIZE?{ plugins: [ new BundleAnalyzerPlugin() ]}:{},
|
||||
env.ANALYZE_SIZE?{ plugins: [ new BundleAnalyzerPlugin(
|
||||
{
|
||||
analyzerMode: 'static',
|
||||
generateStatsFile: true,
|
||||
statsFilename: 'stats.json',
|
||||
}
|
||||
) ]}:{},
|
||||
|
||||
|
||||
{
|
||||
entry:
|
||||
{
|
||||
@@ -170,7 +179,6 @@ module.exports = (env, options) => (
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
|
||||
new HtmlWebpackPlugin({
|
||||
title: 'SqueezeESP32',
|
||||
template: './src/index.ejs',
|
||||
@@ -328,6 +336,7 @@ extern const uint8_t * resource_map_end[];`;
|
||||
optimization: {
|
||||
minimize: true,
|
||||
providedExports: true,
|
||||
usedExports: true,
|
||||
minimizer: [
|
||||
|
||||
new TerserPlugin({
|
||||
@@ -340,7 +349,14 @@ extern const uint8_t * resource_map_end[];`;
|
||||
// enable parallel running
|
||||
parallel: true,
|
||||
}),
|
||||
new HtmlMinimizerPlugin(),
|
||||
new HtmlMinimizerPlugin({
|
||||
minimizerOptions: {
|
||||
removeComments: true,
|
||||
removeOptionalTags: true,
|
||||
|
||||
}
|
||||
}
|
||||
),
|
||||
new CssMinimizerPlugin(),
|
||||
new ImageMinimizerPlugin({
|
||||
minimizer: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/***********************************
|
||||
webpack_headers
|
||||
dist/css/index.7964a13ec910c36040b8.css.gz,dist/favicon-32x32.png,dist/index.html.gz,dist/js/index.44748c.bundle.js.gz,dist/js/node_vendors.44748c.bundle.js.gz
|
||||
dist/css/index.cd56ff129e3113d8cd3a.css.gz,dist/favicon-32x32.png,dist/index.html.gz,dist/js/index.0748ab.bundle.js.gz,dist/js/node_vendors.0748ab.bundle.js.gz
|
||||
***********************************/
|
||||
#pragma once
|
||||
#include <inttypes.h>
|
||||
|
||||
@@ -6,6 +6,7 @@ const HtmlWebPackPlugin = require('html-webpack-plugin');
|
||||
const { Command } = require('commander');
|
||||
let cmdLines= { };
|
||||
var { parseArgsStringToArgv } = require('string-argv');
|
||||
const PORT = 9100;
|
||||
|
||||
const data = {
|
||||
messages: require("../mock/messages.json"),
|
||||
@@ -133,11 +134,10 @@ const connectReturnCode = {
|
||||
}
|
||||
module.exports ={
|
||||
entry: {
|
||||
test: './src/test.ts',
|
||||
test: './src/test.ts'
|
||||
|
||||
},
|
||||
devServer: {
|
||||
|
||||
|
||||
static: {
|
||||
directory: path.resolve(__dirname, './dist'),
|
||||
staticOptions: {},
|
||||
@@ -158,11 +158,10 @@ module.exports ={
|
||||
},
|
||||
open: true,
|
||||
compress: true,
|
||||
port: 9100,
|
||||
port: PORT,
|
||||
host: '127.0.0.1',//your ip address
|
||||
allowedHosts: "all",
|
||||
headers: {'Access-Control-Allow-Origin': '*',
|
||||
'Accept-Encoding': 'identity'},
|
||||
headers: {'Access-Control-Allow-Origin': '*', 'Accept-Encoding': 'identity'},
|
||||
client: {
|
||||
logging: "verbose",
|
||||
// Can be used only for `errors`/`warnings`
|
||||
@@ -179,8 +178,18 @@ module.exports ={
|
||||
throw new Error('webpack-dev-server is not defined');
|
||||
}
|
||||
|
||||
const port = devServer.server.address().port;
|
||||
console.log('Listening on port:', port);
|
||||
const PORT = devServer.server.address().port;
|
||||
|
||||
// get the path to the test page
|
||||
const compiler = devServer.compiler;
|
||||
const entry = compiler.options.entry;
|
||||
const testEntry = entry['test'].import[0];
|
||||
const testPath = testEntry.replace('./src/', '').replace('.ts', '.html');
|
||||
|
||||
// open the test page
|
||||
import('open').then((open) => open.default(`http://localhost:${PORT}/${testPath}`));
|
||||
|
||||
|
||||
},
|
||||
|
||||
onBeforeSetupMiddleware: function (devServer) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
idf_component_register(SRC_DIRS .
|
||||
PRIV_REQUIRES _override esp_common wifi-manager pthread squeezelite-ota platform_console telnet display targets
|
||||
EMBED_FILES ../server_certs/github.pem
|
||||
LDFRAGMENTS "linker.lf"
|
||||
)
|
||||
#get_target_property(ill ${COMPONENT_LIB} INTERFACE_LINK_LIBRARIES)
|
||||
|
||||
@@ -381,13 +381,6 @@ void app_main()
|
||||
GDS_TextPos(display, GDS_FONT_DEFAULT, GDS_TEXT_CENTERED, GDS_TEXT_CLEAR | GDS_TEXT_UPDATE, "RECOVERY");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
ESP_LOGI(TAG,"Checking if certificates need to be updated");
|
||||
update_certificates(false);
|
||||
MEMTRACE_PRINT_DELTA();
|
||||
*/
|
||||
|
||||
ESP_LOGD(TAG,"Getting firmware OTA URL (if any)");
|
||||
fwurl = process_ota_url();
|
||||
|
||||
|
||||
BIN
server_certs/DigiCertGlobalRootCA.crt.28
Normal file
BIN
server_certs/DigiCertGlobalRootCA.crt.28
Normal file
Binary file not shown.
BIN
server_certs/DigiCertGlobalRootCA.crt.29
Normal file
BIN
server_certs/DigiCertGlobalRootCA.crt.29
Normal file
Binary file not shown.
BIN
server_certs/DigiCertGlobalRootCA.crt.30
Normal file
BIN
server_certs/DigiCertGlobalRootCA.crt.30
Normal file
Binary file not shown.
BIN
server_certs/DigiCertGlobalRootCA.crt.31
Normal file
BIN
server_certs/DigiCertGlobalRootCA.crt.31
Normal file
Binary file not shown.
@@ -1,13 +1,13 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFajCCBPCgAwIBAgIQBRiaVOvox+kD4KsNklVF3jAKBggqhkjOPQQDAzBWMQsw
|
||||
MIIFajCCBPGgAwIBAgIQDNCovsYyz+ZF7KCpsIT7HDAKBggqhkjOPQQDAzBWMQsw
|
||||
CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMTAwLgYDVQQDEydEaWdp
|
||||
Q2VydCBUTFMgSHlicmlkIEVDQyBTSEEzODQgMjAyMCBDQTEwHhcNMjIwMzE1MDAw
|
||||
MDAwWhcNMjMwMzE1MjM1OTU5WjBmMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2Fs
|
||||
Q2VydCBUTFMgSHlicmlkIEVDQyBTSEEzODQgMjAyMCBDQTEwHhcNMjMwMjE0MDAw
|
||||
MDAwWhcNMjQwMzE0MjM1OTU5WjBmMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2Fs
|
||||
aWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMR2l0SHVi
|
||||
LCBJbmMuMRMwEQYDVQQDEwpnaXRodWIuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D
|
||||
AQcDQgAESrCTcYUh7GI/y3TARsjnANwnSjJLitVRgwgRI1JlxZ1kdZQQn5ltP3v7
|
||||
KTtYuDdUeEu3PRx3fpDdu2cjMlyA0aOCA44wggOKMB8GA1UdIwQYMBaAFAq8CCkX
|
||||
jKU5bXoOzjPHLrPt+8N6MB0GA1UdDgQWBBR4qnLGcWloFLVZsZ6LbitAh0I7HjAl
|
||||
AQcDQgAEo6QDRgPfRlFWy8k5qyLN52xZlnqToPu5QByQMog2xgl2nFD1Vfd2Xmgg
|
||||
nO4i7YMMFTAQQUReMqyQodWq8uVDs6OCA48wggOLMB8GA1UdIwQYMBaAFAq8CCkX
|
||||
jKU5bXoOzjPHLrPt+8N6MB0GA1UdDgQWBBTHByd4hfKdM8lMXlZ9XNaOcmfr3jAl
|
||||
BgNVHREEHjAcggpnaXRodWIuY29tgg53d3cuZ2l0aHViLmNvbTAOBgNVHQ8BAf8E
|
||||
BAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMIGbBgNVHR8EgZMw
|
||||
gZAwRqBEoEKGQGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRMU0h5
|
||||
@@ -17,15 +17,15 @@ cmwwPgYDVR0gBDcwNTAzBgZngQwBAgIwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3
|
||||
dy5kaWdpY2VydC5jb20vQ1BTMIGFBggrBgEFBQcBAQR5MHcwJAYIKwYBBQUHMAGG
|
||||
GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBPBggrBgEFBQcwAoZDaHR0cDovL2Nh
|
||||
Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VExTSHlicmlkRUNDU0hBMzg0MjAy
|
||||
MENBMS0xLmNydDAJBgNVHRMEAjAAMIIBfwYKKwYBBAHWeQIEAgSCAW8EggFrAWkA
|
||||
dgCt9776fP8QyIudPZwePhhqtGcpXc+xDCTKhYY069yCigAAAX+Oi8SRAAAEAwBH
|
||||
MEUCIAR9cNnvYkZeKs9JElpeXwztYB2yLhtc8bB0rY2ke98nAiEAjiML8HZ7aeVE
|
||||
P/DkUltwIS4c73VVrG9JguoRrII7gWMAdwA1zxkbv7FsV78PrUxtQsu7ticgJlHq
|
||||
P+Eq76gDwzvWTAAAAX+Oi8R7AAAEAwBIMEYCIQDNckqvBhup7GpANMf0WPueytL8
|
||||
u/PBaIAObzNZeNMpOgIhAMjfEtE6AJ2fTjYCFh/BNVKk1mkTwBTavJlGmWomQyaB
|
||||
AHYAs3N3B+GEUPhjhtYFqdwRCUp5LbFnDAuH3PADDnk2pZoAAAF/jovErAAABAMA
|
||||
RzBFAiEA9Uj5Ed/XjQpj/MxQRQjzG0UFQLmgWlc73nnt3CJ7vskCICqHfBKlDz7R
|
||||
EHdV5Vk8bLMBW1Q6S7Ga2SbFuoVXs6zFMAoGCCqGSM49BAMDA2gAMGUCMCiVhqft
|
||||
7L/stBmv1XqSRNfE/jG/AqKIbmjGTocNbuQ7kt1Cs7kRg+b3b3C9Ipu5FQIxAM7c
|
||||
tGKrYDGt0pH8iF6rzbp9Q4HQXMZXkNxg+brjWxnaOVGTDNwNH7048+s/hT9bUQ==
|
||||
MENBMS0xLmNydDAJBgNVHRMEAjAAMIIBgAYKKwYBBAHWeQIEAgSCAXAEggFsAWoA
|
||||
dwDuzdBk1dsazsVct520zROiModGfLzs3sNRSFlGcR+1mwAAAYZQ3Rv6AAAEAwBI
|
||||
MEYCIQDkFq7T4iy6gp+pefJLxpRS7U3gh8xQymmxtI8FdzqU6wIhALWfw/nLD63Q
|
||||
YPIwG3EFchINvWUfB6mcU0t2lRIEpr8uAHYASLDja9qmRzQP5WoC+p0w6xxSActW
|
||||
3SyB2bu/qznYhHMAAAGGUN0cKwAABAMARzBFAiAePGAyfiBR9dbhr31N9ZfESC5G
|
||||
V2uGBTcyTyUENrH3twIhAPwJfsB8A4MmNr2nW+sdE1n2YiCObW+3DTHr2/UR7lvU
|
||||
AHcAO1N3dT4tuYBOizBbBv5AO2fYT8P0x70ADS1yb+H61BcAAAGGUN0cOgAABAMA
|
||||
SDBGAiEAzOBr9OZ0+6OSZyFTiywN64PysN0FLeLRyL5jmEsYrDYCIQDu0jtgWiMI
|
||||
KU6CM0dKcqUWLkaFE23c2iWAhYAHqrFRRzAKBggqhkjOPQQDAwNnADBkAjAE3A3U
|
||||
3jSZCpwfqOHBdlxi9ASgKTU+wg0qw3FqtfQ31OwLYFdxh0MlNk/HwkjRSWgCMFbQ
|
||||
vMkXEPvNvv4t30K6xtpG26qmZ+6OiISBIIXMljWnsiYR1gyZnTzIg3AQSw4Vmw==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
@@ -73,15 +73,15 @@ ce1XR2bFuAJKZTRei9AqPCCcUZlM51Ke92sRKw2Sfh3oius2FkOH6ipjv3U/697E
|
||||
A7sKPPcw7+uvTPyLNhBzPvOk
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFajCCBPCgAwIBAgIQBRiaVOvox+kD4KsNklVF3jAKBggqhkjOPQQDAzBWMQsw
|
||||
MIIFajCCBPGgAwIBAgIQDNCovsYyz+ZF7KCpsIT7HDAKBggqhkjOPQQDAzBWMQsw
|
||||
CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMTAwLgYDVQQDEydEaWdp
|
||||
Q2VydCBUTFMgSHlicmlkIEVDQyBTSEEzODQgMjAyMCBDQTEwHhcNMjIwMzE1MDAw
|
||||
MDAwWhcNMjMwMzE1MjM1OTU5WjBmMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2Fs
|
||||
Q2VydCBUTFMgSHlicmlkIEVDQyBTSEEzODQgMjAyMCBDQTEwHhcNMjMwMjE0MDAw
|
||||
MDAwWhcNMjQwMzE0MjM1OTU5WjBmMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2Fs
|
||||
aWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMR2l0SHVi
|
||||
LCBJbmMuMRMwEQYDVQQDEwpnaXRodWIuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D
|
||||
AQcDQgAESrCTcYUh7GI/y3TARsjnANwnSjJLitVRgwgRI1JlxZ1kdZQQn5ltP3v7
|
||||
KTtYuDdUeEu3PRx3fpDdu2cjMlyA0aOCA44wggOKMB8GA1UdIwQYMBaAFAq8CCkX
|
||||
jKU5bXoOzjPHLrPt+8N6MB0GA1UdDgQWBBR4qnLGcWloFLVZsZ6LbitAh0I7HjAl
|
||||
AQcDQgAEo6QDRgPfRlFWy8k5qyLN52xZlnqToPu5QByQMog2xgl2nFD1Vfd2Xmgg
|
||||
nO4i7YMMFTAQQUReMqyQodWq8uVDs6OCA48wggOLMB8GA1UdIwQYMBaAFAq8CCkX
|
||||
jKU5bXoOzjPHLrPt+8N6MB0GA1UdDgQWBBTHByd4hfKdM8lMXlZ9XNaOcmfr3jAl
|
||||
BgNVHREEHjAcggpnaXRodWIuY29tgg53d3cuZ2l0aHViLmNvbTAOBgNVHQ8BAf8E
|
||||
BAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMIGbBgNVHR8EgZMw
|
||||
gZAwRqBEoEKGQGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRMU0h5
|
||||
@@ -91,123 +91,98 @@ cmwwPgYDVR0gBDcwNTAzBgZngQwBAgIwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3
|
||||
dy5kaWdpY2VydC5jb20vQ1BTMIGFBggrBgEFBQcBAQR5MHcwJAYIKwYBBQUHMAGG
|
||||
GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBPBggrBgEFBQcwAoZDaHR0cDovL2Nh
|
||||
Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VExTSHlicmlkRUNDU0hBMzg0MjAy
|
||||
MENBMS0xLmNydDAJBgNVHRMEAjAAMIIBfwYKKwYBBAHWeQIEAgSCAW8EggFrAWkA
|
||||
dgCt9776fP8QyIudPZwePhhqtGcpXc+xDCTKhYY069yCigAAAX+Oi8SRAAAEAwBH
|
||||
MEUCIAR9cNnvYkZeKs9JElpeXwztYB2yLhtc8bB0rY2ke98nAiEAjiML8HZ7aeVE
|
||||
P/DkUltwIS4c73VVrG9JguoRrII7gWMAdwA1zxkbv7FsV78PrUxtQsu7ticgJlHq
|
||||
P+Eq76gDwzvWTAAAAX+Oi8R7AAAEAwBIMEYCIQDNckqvBhup7GpANMf0WPueytL8
|
||||
u/PBaIAObzNZeNMpOgIhAMjfEtE6AJ2fTjYCFh/BNVKk1mkTwBTavJlGmWomQyaB
|
||||
AHYAs3N3B+GEUPhjhtYFqdwRCUp5LbFnDAuH3PADDnk2pZoAAAF/jovErAAABAMA
|
||||
RzBFAiEA9Uj5Ed/XjQpj/MxQRQjzG0UFQLmgWlc73nnt3CJ7vskCICqHfBKlDz7R
|
||||
EHdV5Vk8bLMBW1Q6S7Ga2SbFuoVXs6zFMAoGCCqGSM49BAMDA2gAMGUCMCiVhqft
|
||||
7L/stBmv1XqSRNfE/jG/AqKIbmjGTocNbuQ7kt1Cs7kRg+b3b3C9Ipu5FQIxAM7c
|
||||
tGKrYDGt0pH8iF6rzbp9Q4HQXMZXkNxg+brjWxnaOVGTDNwNH7048+s/hT9bUQ==
|
||||
MENBMS0xLmNydDAJBgNVHRMEAjAAMIIBgAYKKwYBBAHWeQIEAgSCAXAEggFsAWoA
|
||||
dwDuzdBk1dsazsVct520zROiModGfLzs3sNRSFlGcR+1mwAAAYZQ3Rv6AAAEAwBI
|
||||
MEYCIQDkFq7T4iy6gp+pefJLxpRS7U3gh8xQymmxtI8FdzqU6wIhALWfw/nLD63Q
|
||||
YPIwG3EFchINvWUfB6mcU0t2lRIEpr8uAHYASLDja9qmRzQP5WoC+p0w6xxSActW
|
||||
3SyB2bu/qznYhHMAAAGGUN0cKwAABAMARzBFAiAePGAyfiBR9dbhr31N9ZfESC5G
|
||||
V2uGBTcyTyUENrH3twIhAPwJfsB8A4MmNr2nW+sdE1n2YiCObW+3DTHr2/UR7lvU
|
||||
AHcAO1N3dT4tuYBOizBbBv5AO2fYT8P0x70ADS1yb+H61BcAAAGGUN0cOgAABAMA
|
||||
SDBGAiEAzOBr9OZ0+6OSZyFTiywN64PysN0FLeLRyL5jmEsYrDYCIQDu0jtgWiMI
|
||||
KU6CM0dKcqUWLkaFE23c2iWAhYAHqrFRRzAKBggqhkjOPQQDAwNnADBkAjAE3A3U
|
||||
3jSZCpwfqOHBdlxi9ASgKTU+wg0qw3FqtfQ31OwLYFdxh0MlNk/HwkjRSWgCMFbQ
|
||||
vMkXEPvNvv4t30K6xtpG26qmZ+6OiISBIIXMljWnsiYR1gyZnTzIg3AQSw4Vmw==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIHFDCCBfygAwIBAgIQCLS/dX/bKN3zuMTJNXxaSTANBgkqhkiG9w0BAQsFADBP
|
||||
MIIHEjCCBfqgAwIBAgIQBE1y13zdpwLdWmfyoju92TANBgkqhkiG9w0BAQsFADBP
|
||||
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMSkwJwYDVQQDEyBE
|
||||
aWdpQ2VydCBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTAeFw0yMjA0MDcwMDAwMDBa
|
||||
Fw0yMzA0MDcyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9y
|
||||
aWdpQ2VydCBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTAeFw0yMzAyMjEwMDAwMDBa
|
||||
Fw0yNDAzMjAyMzU5NTlaMGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9y
|
||||
bmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRUwEwYDVQQKEwxHaXRIdWIsIElu
|
||||
Yy4xFTATBgNVBAMMDCouZ2l0aHViLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBALyqZjatk2jnqiWmp6eusW70yJlreKz8mllyRSPxnIVeuwCHGzeQ
|
||||
pGOOZkdRiBLcC2SWM3WgwQjBVBzqS1hWgoP5e6hzuXvGM3anlgJDE9dDUJfdC/Is
|
||||
nzB4Q5Y4TU3FcRCUaK4GMoJGC0fu0fDbH927yKAnvdErG4u+jFSqIidwEaEfPWCC
|
||||
o3xCyQLHTknXQ9aaDvU6GHNX0us6G+bjdErIwQtC56F0ke7biV0A/DWX5V+hVsVY
|
||||
jY9JbYNx+KFjmUxLibccXzXs0pJ+a6Xa4OhhrFebPwS+SQA+gxTTvZotj4J5kf2l
|
||||
nM9H+1whu6I5qPebhlTRTKpxdPm9V647Zj8CAwEAAaOCA9EwggPNMB8GA1UdIwQY
|
||||
MBaAFLdrouqoqoSMeeq02g+YssWVdrn0MB0GA1UdDgQWBBRWmrM0shNZi0idiZiI
|
||||
7l3ryIMwdDB7BgNVHREEdDByggwqLmdpdGh1Yi5jb22CDnd3dy5naXRodWIuY29t
|
||||
gglnaXRodWIuaW+CCmdpdGh1Yi5jb22CCyouZ2l0aHViLmlvghVnaXRodWJ1c2Vy
|
||||
Y29udGVudC5jb22CFyouZ2l0aHVidXNlcmNvbnRlbnQuY29tMA4GA1UdDwEB/wQE
|
||||
AwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwgY8GA1UdHwSBhzCB
|
||||
hDBAoD6gPIY6aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VExTUlNB
|
||||
U0hBMjU2MjAyMENBMS00LmNybDBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQu
|
||||
Y29tL0RpZ2lDZXJ0VExTUlNBU0hBMjU2MjAyMENBMS00LmNybDA+BgNVHSAENzA1
|
||||
MDMGBmeBDAECAjApMCcGCCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2ljZXJ0LmNv
|
||||
bS9DUFMwfwYIKwYBBQUHAQEEczBxMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5k
|
||||
aWdpY2VydC5jb20wSQYIKwYBBQUHMAKGPWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0
|
||||
LmNvbS9EaWdpQ2VydFRMU1JTQVNIQTI1NjIwMjBDQTEtMS5jcnQwCQYDVR0TBAIw
|
||||
ADCCAX8GCisGAQQB1nkCBAIEggFvBIIBawFpAHYA6D7Q2j71BjUy51covIlryQPT
|
||||
y9ERa+zraeF3fW0GvW4AAAGABfvdbAAABAMARzBFAiAGLk49aFP9ARwPXCa59WnI
|
||||
f5jIU5eFmqR6/W3Zm38KiwIhAIp8FySKqbKk600uO4iPsS6TW8hJl67PprwXYMlr
|
||||
o3wPAHcANc8ZG7+xbFe/D61MbULLu7YnICZR6j/hKu+oA8M71kwAAAGABfvdXQAA
|
||||
BAMASDBGAiEAjFarHnzcbBvQ8//um0zVd4G3T5zbW4XSUIJSTc5JGo8CIQDaT5K8
|
||||
pji9egTYSypP9XfRK+Z2wID3j43uuGjiKSOKyQB2ALNzdwfhhFD4Y4bWBancEQlK
|
||||
eS2xZwwLh9zwAw55NqWaAAABgAX73YsAAAQDAEcwRQIhAO/PWksY7Zd7W5NJr3e4
|
||||
xRkx8J6Qv7a33VA3tkm96k4WAiBshJWPE2BjKzuQ/KEfiKnvD4dDa3btkmcWlpiD
|
||||
R8AvQDANBgkqhkiG9w0BAQsFAAOCAQEARtY8iVMqqBCXGZj2NRhpxA4eS2b/e/56
|
||||
JhnRWGz3wxf0aRjbaZ2sUH3aHe1UDyg4jVPgnSLsGnBMmN5Rk32uiB/5v6/uRhCa
|
||||
l26Yi9MYbeQpt0980MxT5hhv8bThRiNa77+oAOcrYMJEGIf2/9k0yoefblEZTR02
|
||||
6UU6pkDhxjMtpyNRr+IdqQM/4lCM6nu8FZ/qaLltvta1Enq+jEwEObo/PoBoQJzJ
|
||||
j7hcu7rkyPQIK1raQ9pK7uFJ2/FgtxIUuT+by06LnUp82VB7QxlniXO2R4XgDzWd
|
||||
umlpkAFJQvZ+Sa2rSdjynrTDedjQIv3s1jH2Tvao5fR23tW2XAQhVg==
|
||||
Yy4xFDASBgNVBAMMCyouZ2l0aHViLmlvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
||||
MIIBCgKCAQEAuLBgDhov8bGGS2TsEZ+meb7oh/GIxbRJmxC7yq/qr75UDHhDf8p7
|
||||
TkVbCyQp8bsj/Bmkx2xwSXZT0wkjZbJIe7Ycqgca4nka+Xpe5xb4pkrVOaPiDfdX
|
||||
7+34CHZbUtqL0OYebi/5D5lLalLKNOGkySAz05foenfFAxAmQYJhR6KvxFY/dqI4
|
||||
y7JwrnJ6Q8F+J6Ne1uP256UwcL0qlid6e/tA0ld3ryMSJ0I6xgtqjL26Le4/nxXu
|
||||
YlekppVQr0OwrHa44Q7Z/1bsdFCGtR+WLNGVBeW3BWeTTp7yWjgfp49DWt48V9pI
|
||||
elDGiDgVyJcsLOz4OQk2vRmNA1ZBZgck4wIDAQABo4ID0DCCA8wwHwYDVR0jBBgw
|
||||
FoAUt2ui6qiqhIx56rTaD5iyxZV2ufQwHQYDVR0OBBYEFI0CHHVazcamQXhpKMP3
|
||||
qqeYO9W7MHsGA1UdEQR0MHKCCyouZ2l0aHViLmlvgglnaXRodWIuaW+CDCouZ2l0
|
||||
aHViLmNvbYIKZ2l0aHViLmNvbYIOd3d3LmdpdGh1Yi5jb22CFyouZ2l0aHVidXNl
|
||||
cmNvbnRlbnQuY29tghVnaXRodWJ1c2VyY29udGVudC5jb20wDgYDVR0PAQH/BAQD
|
||||
AgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjCBjwYDVR0fBIGHMIGE
|
||||
MECgPqA8hjpodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUTFNSU0FT
|
||||
SEEyNTYyMDIwQ0ExLTQuY3JsMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2VydC5j
|
||||
b20vRGlnaUNlcnRUTFNSU0FTSEEyNTYyMDIwQ0ExLTQuY3JsMD4GA1UdIAQ3MDUw
|
||||
MwYGZ4EMAQICMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29t
|
||||
L0NQUzB/BggrBgEFBQcBAQRzMHEwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp
|
||||
Z2ljZXJ0LmNvbTBJBggrBgEFBQcwAoY9aHR0cDovL2NhY2VydHMuZGlnaWNlcnQu
|
||||
Y29tL0RpZ2lDZXJ0VExTUlNBU0hBMjU2MjAyMENBMS0xLmNydDAJBgNVHRMEAjAA
|
||||
MIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdwB2/4g/Crb7lVHCYcz1h7o0tKTN
|
||||
uyncaEIKn+ZnTFo6dAAAAYZ0gHV7AAAEAwBIMEYCIQCqfmfSO8MxeeVZ/fJzqqBB
|
||||
p+VqeRDUOUBVGyTTOn43ewIhAJT0S27mmGUlpqNiDADP+Jo8C6kYHF+7U6TY74bH
|
||||
XHAaAHYAc9meiRtMlnigIH1HneayxhzQUV5xGSqMa4AQesF3crUAAAGGdIB1agAA
|
||||
BAMARzBFAiEAguB+XQVANBj2MPcJzbz+LBPrkDDOEO3op52jdHUSW3ICIF0fnYdW
|
||||
qvdtmgQNSns13pAppdQWp4/f/jerNYskI7krAHUASLDja9qmRzQP5WoC+p0w6xxS
|
||||
ActW3SyB2bu/qznYhHMAAAGGdIB1SgAABAMARjBEAiAT/wA2qGGHSKZqBAm84z6q
|
||||
E+dGPQZ1aCMY52pFSfcw8QIgP/SciuZG02X2mBO/miDT2hCp4y5d2sc7FE5PThyC
|
||||
pbMwDQYJKoZIhvcNAQELBQADggEBADekGxEin/yfyWcHj6qGE5/gCB1uDI1l+wN5
|
||||
UMZ2ujCQoKQceRMHuVoYjZdMBXGK0CIXxhmiIosD9iyEcWxV3+KZQ2Xl17e3N0zG
|
||||
yOXx2Kd7B13ruBxQpKOO8Ez4uGpyWb5DDoretV6Pnj9aQ2SCzODedvS+phIKBmi7
|
||||
d+FM70tNZ6/2csdrG5xIU6d/7XYYXPD2xkwkU1dX4UKmPa7h9ZPyavopcgE+twbx
|
||||
LxoOkcXsNb/12jOV3iQSDfXDI41AgtFc694KCOjlg+UKizpemE53T5/cq37OqChP
|
||||
qnlPyb6PYIhua/kgbH84ltba1xEDQ9i4UYfOMiJNZEzEdSfQ498=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIHozCCBougAwIBAgIQBG+MjTu2U2CAH+MEm6l61jANBgkqhkiG9w0BAQsFADBG
|
||||
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg
|
||||
Q0EgMUIxDzANBgNVBAMTBkFtYXpvbjAeFw0yMjA0MDEwMDAwMDBaFw0yMzAzMzAy
|
||||
MzU5NTlaMBsxGTAXBgNVBAMTEHMzLmFtYXpvbmF3cy5jb20wggEiMA0GCSqGSIb3
|
||||
DQEBAQUAA4IBDwAwggEKAoIBAQCjOMyeQT6RFlYmYfjj08zVKFFdJUIIBLNVC2Ij
|
||||
chWl7zswWUmTtxj/cifpMx64WsGOSzwNZP+zpUX/0miTawNJOMi53taVwKt8PY03
|
||||
Ud2Yr/RkRBGKsUTUYpIlSj4plJ6p2gdAqNMsI9dnYketpff5K9vmqQYh/qDeI4NQ
|
||||
5+PsK22emJMgvjNaEOlOU95Xk5E02M9S2UB3MXlLO2G+YTTbsZW0QRQe6GDp/qXy
|
||||
aGGHQbAL4Gthz8xm4C5+scBI0dMvjVcnW78IEO/YaB+zNsVkiMXV7OBtRIy5JJLB
|
||||
EPc0QT2cl4h1ktcqVdKzQnCRfb53V9KA2gdAkmih47fAHQTfAgMBAAGjggS2MIIE
|
||||
sjAfBgNVHSMEGDAWgBRZpGYGUqB7lZI8o5QHJ5Z0W/k90DAdBgNVHQ4EFgQURXXo
|
||||
9PzHJg3VN6E4crTKJmllGZkwggHkBgNVHREEggHbMIIB14IQczMuYW1hem9uYXdz
|
||||
LmNvbYISKi5zMy5hbWF6b25hd3MuY29tgiYqLnMzLmR1YWxzdGFjay51cy1lYXN0
|
||||
LTEuYW1hem9uYXdzLmNvbYIkczMuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25h
|
||||
d3MuY29tghwqLnMzLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tghpzMy51cy1lYXN0
|
||||
LTEuYW1hem9uYXdzLmNvbYIkKi5zMy1jb250cm9sLnVzLWVhc3QtMS5hbWF6b25h
|
||||
d3MuY29tgiJzMy1jb250cm9sLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgi4qLnMz
|
||||
LWNvbnRyb2wuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgixzMy1j
|
||||
b250cm9sLmR1YWxzdGFjay51cy1lYXN0LTEuYW1hem9uYXdzLmNvbYIoKi5zMy1h
|
||||
Y2Nlc3Nwb2ludC51cy1lYXN0LTEuYW1hem9uYXdzLmNvbYIyKi5zMy1hY2Nlc3Nw
|
||||
b2ludC5kdWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CISouczMudXMt
|
||||
ZWFzdC0xLnZwY2UuYW1hem9uYXdzLmNvbTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0l
|
||||
BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6
|
||||
Ly9jcmwuc2NhMWIuYW1hem9udHJ1c3QuY29tL3NjYTFiLTEuY3JsMBMGA1UdIAQM
|
||||
MAowCAYGZ4EMAQIBMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcwAYYhaHR0cDov
|
||||
L29jc3Auc2NhMWIuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAChipodHRwOi8v
|
||||
Y3J0LnNjYTFiLmFtYXpvbnRydXN0LmNvbS9zY2ExYi5jcnQwDAYDVR0TAQH/BAIw
|
||||
ADCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHYA6D7Q2j71BjUy51covIlryQPT
|
||||
y9ERa+zraeF3fW0GvW4AAAF/5g3wggAABAMARzBFAiEAi/U3UhS0wBO3ENr60raR
|
||||
eLOh2AG97uiMu5/XTpOitzkCIBS3J35I01Px5yxWB03Wbp5Q15rKflPnGdk4OxqA
|
||||
YhwCAHUANc8ZG7+xbFe/D61MbULLu7YnICZR6j/hKu+oA8M71kwAAAF/5g3wxwAA
|
||||
BAMARjBEAiBVLkL7vmHrvdgj4f9/EkWear0/EifCefzHAIkmZXROGgIgLM/cG6C/
|
||||
oz8y8uDEZI6ijXsmlpPDe4azrAL9qMZ1LHcAdwCzc3cH4YRQ+GOG1gWp3BEJSnkt
|
||||
sWcMC4fc8AMOeTalmgAAAX/mDfDrAAAEAwBIMEYCIQCc2ZP3gCZGJ8PQFrVZGk2K
|
||||
4L4ebIhQQrfp9irYeyyBXgIhAPF45dE3vSvxkf/Qr1yba0eYQa+F0P92wV6Cpkqa
|
||||
SHfrMA0GCSqGSIb3DQEBCwUAA4IBAQA4tbiyX/J+awY2zXRv7MhFFn5lg4qZLl59
|
||||
DKoxuVQ3/os1UkOE3z7rNJVQZ9v1DrsadooHIQ69Uz5JUcdpVz57tSZs5H6Cf5EW
|
||||
GaNgeeXvloME0G5KXAXBQ6NZrCaKzpOrGJRhKJGvrVgGhPqYAZ0fTXJ81vt5AICp
|
||||
55pwVIMTLPR4ewD/l/OWuned8zXjBF2+WQ7Ex5E0VIv9MuFN/URXGWQ+I+2uGyfW
|
||||
zlX9SweWNfLYYxTtY1duU7nzqnK6u2/N2IxO4Hkqehll3Ineyqdni4/CeMHOD06B
|
||||
ox01tCIdK1Wz5I7K/F2jc6jinmZHYlX+oHaY5lAh9FLsQ+luBgHd
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIESTCCAzGgAwIBAgITBn+UV4WH6Kx33rJTMlu8mYtWDTANBgkqhkiG9w0BAQsF
|
||||
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
|
||||
b24gUm9vdCBDQSAxMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjEL
|
||||
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENB
|
||||
IDFCMQ8wDQYDVQQDEwZBbWF6b24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
|
||||
AoIBAQDCThZn3c68asg3Wuw6MLAd5tES6BIoSMzoKcG5blPVo+sDORrMd4f2AbnZ
|
||||
cMzPa43j4wNxhplty6aUKk4T1qe9BOwKFjwK6zmxxLVYo7bHViXsPlJ6qOMpFge5
|
||||
blDP+18x+B26A0piiQOuPkfyDyeR4xQghfj66Yo19V+emU3nazfvpFA+ROz6WoVm
|
||||
B5x+F2pV8xeKNR7u6azDdU5YVX1TawprmxRC1+WsAYmz6qP+z8ArDITC2FMVy2fw
|
||||
0IjKOtEXc/VfmtTFch5+AfGYMGMqqvJ6LcXiAhqG5TI+Dr0RtM88k+8XUBCeQ8IG
|
||||
KuANaL7TiItKZYxK1MMuTJtV9IblAgMBAAGjggE7MIIBNzASBgNVHRMBAf8ECDAG
|
||||
AQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUWaRmBlKge5WSPKOUByeW
|
||||
dFv5PdAwHwYDVR0jBBgwFoAUhBjMhTTsvAyUlC4IWZzHshBOCggwewYIKwYBBQUH
|
||||
AQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5yb290Y2ExLmFtYXpvbnRy
|
||||
dXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDovL2NydC5yb290Y2ExLmFtYXpvbnRy
|
||||
dXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3Js
|
||||
LnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jvb3RjYTEuY3JsMBMGA1UdIAQMMAow
|
||||
CAYGZ4EMAQIBMA0GCSqGSIb3DQEBCwUAA4IBAQCFkr41u3nPo4FCHOTjY3NTOVI1
|
||||
59Gt/a6ZiqyJEi+752+a1U5y6iAwYfmXss2lJwJFqMp2PphKg5625kXg8kP2CN5t
|
||||
6G7bMQcT8C8xDZNtYTd7WPD8UZiRKAJPBXa30/AbwuZe0GaFEQ8ugcYQgSn+IGBI
|
||||
8/LwhBNTZTUVEWuCUUBVV18YtbAiPq3yXqMB48Oz+ctBWuZSkbvkNodPLamkB2g1
|
||||
upRyzQ7qDn1X8nn8N8V7YJ6y68AtkHcNSRAnpTitxBKjtKPISLMVCx7i4hncxHZS
|
||||
yLyKQXhw2W2Xs0qLeC1etA+jTGDK4UfLeC0SF7FSi8o5LL21L8IzApar2pR/
|
||||
MIIHljCCBn6gAwIBAgIQC65deUww9ISBucGLLymfiTANBgkqhkiG9w0BAQsFADA8
|
||||
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g
|
||||
UlNBIDIwNDggTTAxMB4XDTIyMTIwNjAwMDAwMFoXDTIzMTIwNTIzNTk1OVowGzEZ
|
||||
MBcGA1UEAxMQczMuYW1hem9uYXdzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAOai9pH7hBruq8Z2Nh7PM3wTYkupXpQsfyV1aIoDE2Wb5Eq6j6lc
|
||||
XstKcAHOSBZomYCqRVjB06hWhT/Vmi8jCIUKj/4ylgl/OUD1Fmp3zPzzp0xXo6W1
|
||||
nMI8t66EnzHzMmUAFcaobb/+XGnsBM/JnOvFgcsnit5b0ohHSrrBkhqoPG9UV6s1
|
||||
ihoIu/inxP/OZK3julKF9DQeQFik+aY5xHyR7NU/YFvgXLOjFtZHNV4M/37K+E8q
|
||||
BG2Fc+23sn+6fRyhkgldIwbUcIgEVfbkRVWBP5zJVbYo7V3yOpauit3FIhTpVATO
|
||||
50AdnLYIPa8HtkEt74uKoiPAvEsX1KLlbFECAwEAAaOCBLMwggSvMB8GA1UdIwQY
|
||||
MBaAFIG4DmOKiRIY5fo7O1CVn+blkBOFMB0GA1UdDgQWBBQYwyLcdwl9dkli9Knk
|
||||
oe8DnTMQQzCCAeQGA1UdEQSCAdswggHXghBzMy5hbWF6b25hd3MuY29tghIqLnMz
|
||||
LmFtYXpvbmF3cy5jb22CJiouczMuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25h
|
||||
d3MuY29tgiRzMy5kdWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CHCou
|
||||
czMudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CGnMzLnVzLWVhc3QtMS5hbWF6b25h
|
||||
d3MuY29tgiQqLnMzLWNvbnRyb2wudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CInMz
|
||||
LWNvbnRyb2wudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CLiouczMtY29udHJvbC5k
|
||||
dWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CLHMzLWNvbnRyb2wuZHVh
|
||||
bHN0YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgigqLnMzLWFjY2Vzc3BvaW50
|
||||
LnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgjIqLnMzLWFjY2Vzc3BvaW50LmR1YWxz
|
||||
dGFjay51cy1lYXN0LTEuYW1hem9uYXdzLmNvbYIhKi5zMy51cy1lYXN0LTEudnBj
|
||||
ZS5hbWF6b25hd3MuY29tMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEF
|
||||
BQcDAQYIKwYBBQUHAwIwOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5yMm0w
|
||||
MS5hbWF6b250cnVzdC5jb20vcjJtMDEuY3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIB
|
||||
MHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcwAYYhaHR0cDovL29jc3AucjJtMDEu
|
||||
YW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAChipodHRwOi8vY3J0LnIybTAxLmFt
|
||||
YXpvbnRydXN0LmNvbS9yMm0wMS5jZXIwDAYDVR0TAQH/BAIwADCCAX0GCisGAQQB
|
||||
1nkCBAIEggFtBIIBaQFnAHYA6D7Q2j71BjUy51covIlryQPTy9ERa+zraeF3fW0G
|
||||
vW4AAAGE6TiWGwAABAMARzBFAiEAm7EmdOlYh6ZqCbcL031TNYm1It2F9ZOECd9k
|
||||
Efd5rR0CIARC57eeRuS5w2mHogwnKEokTsA8MiMDQs/ysF8NJAQhAHUAs3N3B+GE
|
||||
UPhjhtYFqdwRCUp5LbFnDAuH3PADDnk2pZoAAAGE6TiWJQAABAMARjBEAiAyQAFf
|
||||
DUdoch036Wz41eG8ukNAIZUNSo2XqOFUhGTrMQIgFwfTZ+Wk3DeuitGUeqRLTLOI
|
||||
/RDTjp6k9iwL5ScBYSwAdgC3Pvsk35xNunXyOcW6WPRsXfxCz3qfNcSeHQmBJe20
|
||||
mQAAAYTpOJXyAAAEAwBHMEUCIEjQE4RdlG0zH2oWP1OSi24e25WyUx3ww3fgLRMH
|
||||
MYWSAiEA795WZhOkmboCZi2wrStw4+nBQLtStAUYbbXGXhX1bWEwDQYJKoZIhvcN
|
||||
AQELBQADggEBAJO/33aYKDV+t01OfLUvRGR6wzcfW1dHmddMkH2CU0I+XJO8+rNe
|
||||
1txfh00UpBDxG/CP/rx+ulA72+XgiXURFC5NtKiyUXit58rMujj21UTmqf3/70DB
|
||||
KdJmMoXTIdz93ttmV4JpF3Oo3Wp8jXcRRKAJdH0aSOH1Fx+fcVa8u56WxsA7khGG
|
||||
/XJcCJomARKpf1W3x9tRAOq6hVkWKSC8V4pyhc6qvymcvgvPHysC+xrRD9RZ38Ui
|
||||
gijCabOG5gYIxE8DCBtVksYq2vxqVod8w8Kp+zHrLYwQbAbrk8JRsdT75GJ/LZhl
|
||||
XAauB98KOqLvlBtdpu8GaAvtpN95tRMkab8=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIHFDCCBfygAwIBAgIQCLS/dX/bKN3zuMTJNXxaSTANBgkqhkiG9w0BAQsFADBP
|
||||
MIIHEjCCBfqgAwIBAgIQBE1y13zdpwLdWmfyoju92TANBgkqhkiG9w0BAQsFADBP
|
||||
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMSkwJwYDVQQDEyBE
|
||||
aWdpQ2VydCBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTAeFw0yMjA0MDcwMDAwMDBa
|
||||
Fw0yMzA0MDcyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9y
|
||||
aWdpQ2VydCBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTAeFw0yMzAyMjEwMDAwMDBa
|
||||
Fw0yNDAzMjAyMzU5NTlaMGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9y
|
||||
bmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRUwEwYDVQQKEwxHaXRIdWIsIElu
|
||||
Yy4xFTATBgNVBAMMDCouZ2l0aHViLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBALyqZjatk2jnqiWmp6eusW70yJlreKz8mllyRSPxnIVeuwCHGzeQ
|
||||
pGOOZkdRiBLcC2SWM3WgwQjBVBzqS1hWgoP5e6hzuXvGM3anlgJDE9dDUJfdC/Is
|
||||
nzB4Q5Y4TU3FcRCUaK4GMoJGC0fu0fDbH927yKAnvdErG4u+jFSqIidwEaEfPWCC
|
||||
o3xCyQLHTknXQ9aaDvU6GHNX0us6G+bjdErIwQtC56F0ke7biV0A/DWX5V+hVsVY
|
||||
jY9JbYNx+KFjmUxLibccXzXs0pJ+a6Xa4OhhrFebPwS+SQA+gxTTvZotj4J5kf2l
|
||||
nM9H+1whu6I5qPebhlTRTKpxdPm9V647Zj8CAwEAAaOCA9EwggPNMB8GA1UdIwQY
|
||||
MBaAFLdrouqoqoSMeeq02g+YssWVdrn0MB0GA1UdDgQWBBRWmrM0shNZi0idiZiI
|
||||
7l3ryIMwdDB7BgNVHREEdDByggwqLmdpdGh1Yi5jb22CDnd3dy5naXRodWIuY29t
|
||||
gglnaXRodWIuaW+CCmdpdGh1Yi5jb22CCyouZ2l0aHViLmlvghVnaXRodWJ1c2Vy
|
||||
Y29udGVudC5jb22CFyouZ2l0aHVidXNlcmNvbnRlbnQuY29tMA4GA1UdDwEB/wQE
|
||||
AwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwgY8GA1UdHwSBhzCB
|
||||
hDBAoD6gPIY6aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VExTUlNB
|
||||
U0hBMjU2MjAyMENBMS00LmNybDBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQu
|
||||
Y29tL0RpZ2lDZXJ0VExTUlNBU0hBMjU2MjAyMENBMS00LmNybDA+BgNVHSAENzA1
|
||||
MDMGBmeBDAECAjApMCcGCCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2ljZXJ0LmNv
|
||||
bS9DUFMwfwYIKwYBBQUHAQEEczBxMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5k
|
||||
aWdpY2VydC5jb20wSQYIKwYBBQUHMAKGPWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0
|
||||
LmNvbS9EaWdpQ2VydFRMU1JTQVNIQTI1NjIwMjBDQTEtMS5jcnQwCQYDVR0TBAIw
|
||||
ADCCAX8GCisGAQQB1nkCBAIEggFvBIIBawFpAHYA6D7Q2j71BjUy51covIlryQPT
|
||||
y9ERa+zraeF3fW0GvW4AAAGABfvdbAAABAMARzBFAiAGLk49aFP9ARwPXCa59WnI
|
||||
f5jIU5eFmqR6/W3Zm38KiwIhAIp8FySKqbKk600uO4iPsS6TW8hJl67PprwXYMlr
|
||||
o3wPAHcANc8ZG7+xbFe/D61MbULLu7YnICZR6j/hKu+oA8M71kwAAAGABfvdXQAA
|
||||
BAMASDBGAiEAjFarHnzcbBvQ8//um0zVd4G3T5zbW4XSUIJSTc5JGo8CIQDaT5K8
|
||||
pji9egTYSypP9XfRK+Z2wID3j43uuGjiKSOKyQB2ALNzdwfhhFD4Y4bWBancEQlK
|
||||
eS2xZwwLh9zwAw55NqWaAAABgAX73YsAAAQDAEcwRQIhAO/PWksY7Zd7W5NJr3e4
|
||||
xRkx8J6Qv7a33VA3tkm96k4WAiBshJWPE2BjKzuQ/KEfiKnvD4dDa3btkmcWlpiD
|
||||
R8AvQDANBgkqhkiG9w0BAQsFAAOCAQEARtY8iVMqqBCXGZj2NRhpxA4eS2b/e/56
|
||||
JhnRWGz3wxf0aRjbaZ2sUH3aHe1UDyg4jVPgnSLsGnBMmN5Rk32uiB/5v6/uRhCa
|
||||
l26Yi9MYbeQpt0980MxT5hhv8bThRiNa77+oAOcrYMJEGIf2/9k0yoefblEZTR02
|
||||
6UU6pkDhxjMtpyNRr+IdqQM/4lCM6nu8FZ/qaLltvta1Enq+jEwEObo/PoBoQJzJ
|
||||
j7hcu7rkyPQIK1raQ9pK7uFJ2/FgtxIUuT+by06LnUp82VB7QxlniXO2R4XgDzWd
|
||||
umlpkAFJQvZ+Sa2rSdjynrTDedjQIv3s1jH2Tvao5fR23tW2XAQhVg==
|
||||
Yy4xFDASBgNVBAMMCyouZ2l0aHViLmlvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
||||
MIIBCgKCAQEAuLBgDhov8bGGS2TsEZ+meb7oh/GIxbRJmxC7yq/qr75UDHhDf8p7
|
||||
TkVbCyQp8bsj/Bmkx2xwSXZT0wkjZbJIe7Ycqgca4nka+Xpe5xb4pkrVOaPiDfdX
|
||||
7+34CHZbUtqL0OYebi/5D5lLalLKNOGkySAz05foenfFAxAmQYJhR6KvxFY/dqI4
|
||||
y7JwrnJ6Q8F+J6Ne1uP256UwcL0qlid6e/tA0ld3ryMSJ0I6xgtqjL26Le4/nxXu
|
||||
YlekppVQr0OwrHa44Q7Z/1bsdFCGtR+WLNGVBeW3BWeTTp7yWjgfp49DWt48V9pI
|
||||
elDGiDgVyJcsLOz4OQk2vRmNA1ZBZgck4wIDAQABo4ID0DCCA8wwHwYDVR0jBBgw
|
||||
FoAUt2ui6qiqhIx56rTaD5iyxZV2ufQwHQYDVR0OBBYEFI0CHHVazcamQXhpKMP3
|
||||
qqeYO9W7MHsGA1UdEQR0MHKCCyouZ2l0aHViLmlvgglnaXRodWIuaW+CDCouZ2l0
|
||||
aHViLmNvbYIKZ2l0aHViLmNvbYIOd3d3LmdpdGh1Yi5jb22CFyouZ2l0aHVidXNl
|
||||
cmNvbnRlbnQuY29tghVnaXRodWJ1c2VyY29udGVudC5jb20wDgYDVR0PAQH/BAQD
|
||||
AgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjCBjwYDVR0fBIGHMIGE
|
||||
MECgPqA8hjpodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUTFNSU0FT
|
||||
SEEyNTYyMDIwQ0ExLTQuY3JsMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2VydC5j
|
||||
b20vRGlnaUNlcnRUTFNSU0FTSEEyNTYyMDIwQ0ExLTQuY3JsMD4GA1UdIAQ3MDUw
|
||||
MwYGZ4EMAQICMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29t
|
||||
L0NQUzB/BggrBgEFBQcBAQRzMHEwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp
|
||||
Z2ljZXJ0LmNvbTBJBggrBgEFBQcwAoY9aHR0cDovL2NhY2VydHMuZGlnaWNlcnQu
|
||||
Y29tL0RpZ2lDZXJ0VExTUlNBU0hBMjU2MjAyMENBMS0xLmNydDAJBgNVHRMEAjAA
|
||||
MIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdwB2/4g/Crb7lVHCYcz1h7o0tKTN
|
||||
uyncaEIKn+ZnTFo6dAAAAYZ0gHV7AAAEAwBIMEYCIQCqfmfSO8MxeeVZ/fJzqqBB
|
||||
p+VqeRDUOUBVGyTTOn43ewIhAJT0S27mmGUlpqNiDADP+Jo8C6kYHF+7U6TY74bH
|
||||
XHAaAHYAc9meiRtMlnigIH1HneayxhzQUV5xGSqMa4AQesF3crUAAAGGdIB1agAA
|
||||
BAMARzBFAiEAguB+XQVANBj2MPcJzbz+LBPrkDDOEO3op52jdHUSW3ICIF0fnYdW
|
||||
qvdtmgQNSns13pAppdQWp4/f/jerNYskI7krAHUASLDja9qmRzQP5WoC+p0w6xxS
|
||||
ActW3SyB2bu/qznYhHMAAAGGdIB1SgAABAMARjBEAiAT/wA2qGGHSKZqBAm84z6q
|
||||
E+dGPQZ1aCMY52pFSfcw8QIgP/SciuZG02X2mBO/miDT2hCp4y5d2sc7FE5PThyC
|
||||
pbMwDQYJKoZIhvcNAQELBQADggEBADekGxEin/yfyWcHj6qGE5/gCB1uDI1l+wN5
|
||||
UMZ2ujCQoKQceRMHuVoYjZdMBXGK0CIXxhmiIosD9iyEcWxV3+KZQ2Xl17e3N0zG
|
||||
yOXx2Kd7B13ruBxQpKOO8Ez4uGpyWb5DDoretV6Pnj9aQ2SCzODedvS+phIKBmi7
|
||||
d+FM70tNZ6/2csdrG5xIU6d/7XYYXPD2xkwkU1dX4UKmPa7h9ZPyavopcgE+twbx
|
||||
LxoOkcXsNb/12jOV3iQSDfXDI41AgtFc694KCOjlg+UKizpemE53T5/cq37OqChP
|
||||
qnlPyb6PYIhua/kgbH84ltba1xEDQ9i4UYfOMiJNZEzEdSfQ498=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
BIN
server_certs/r2m01.cer
Normal file
BIN
server_certs/r2m01.cer
Normal file
Binary file not shown.
BIN
server_certs/r2m01.cer.1
Normal file
BIN
server_certs/r2m01.cer.1
Normal file
Binary file not shown.
BIN
server_certs/r2m01.cer.2
Normal file
BIN
server_certs/r2m01.cer.2
Normal file
Binary file not shown.
BIN
server_certs/r2m01.cer.3
Normal file
BIN
server_certs/r2m01.cer.3
Normal file
Binary file not shown.
@@ -1,43 +1,43 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIHozCCBougAwIBAgIQBG+MjTu2U2CAH+MEm6l61jANBgkqhkiG9w0BAQsFADBG
|
||||
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg
|
||||
Q0EgMUIxDzANBgNVBAMTBkFtYXpvbjAeFw0yMjA0MDEwMDAwMDBaFw0yMzAzMzAy
|
||||
MzU5NTlaMBsxGTAXBgNVBAMTEHMzLmFtYXpvbmF3cy5jb20wggEiMA0GCSqGSIb3
|
||||
DQEBAQUAA4IBDwAwggEKAoIBAQCjOMyeQT6RFlYmYfjj08zVKFFdJUIIBLNVC2Ij
|
||||
chWl7zswWUmTtxj/cifpMx64WsGOSzwNZP+zpUX/0miTawNJOMi53taVwKt8PY03
|
||||
Ud2Yr/RkRBGKsUTUYpIlSj4plJ6p2gdAqNMsI9dnYketpff5K9vmqQYh/qDeI4NQ
|
||||
5+PsK22emJMgvjNaEOlOU95Xk5E02M9S2UB3MXlLO2G+YTTbsZW0QRQe6GDp/qXy
|
||||
aGGHQbAL4Gthz8xm4C5+scBI0dMvjVcnW78IEO/YaB+zNsVkiMXV7OBtRIy5JJLB
|
||||
EPc0QT2cl4h1ktcqVdKzQnCRfb53V9KA2gdAkmih47fAHQTfAgMBAAGjggS2MIIE
|
||||
sjAfBgNVHSMEGDAWgBRZpGYGUqB7lZI8o5QHJ5Z0W/k90DAdBgNVHQ4EFgQURXXo
|
||||
9PzHJg3VN6E4crTKJmllGZkwggHkBgNVHREEggHbMIIB14IQczMuYW1hem9uYXdz
|
||||
LmNvbYISKi5zMy5hbWF6b25hd3MuY29tgiYqLnMzLmR1YWxzdGFjay51cy1lYXN0
|
||||
LTEuYW1hem9uYXdzLmNvbYIkczMuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25h
|
||||
d3MuY29tghwqLnMzLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tghpzMy51cy1lYXN0
|
||||
LTEuYW1hem9uYXdzLmNvbYIkKi5zMy1jb250cm9sLnVzLWVhc3QtMS5hbWF6b25h
|
||||
d3MuY29tgiJzMy1jb250cm9sLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgi4qLnMz
|
||||
LWNvbnRyb2wuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgixzMy1j
|
||||
b250cm9sLmR1YWxzdGFjay51cy1lYXN0LTEuYW1hem9uYXdzLmNvbYIoKi5zMy1h
|
||||
Y2Nlc3Nwb2ludC51cy1lYXN0LTEuYW1hem9uYXdzLmNvbYIyKi5zMy1hY2Nlc3Nw
|
||||
b2ludC5kdWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CISouczMudXMt
|
||||
ZWFzdC0xLnZwY2UuYW1hem9uYXdzLmNvbTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0l
|
||||
BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6
|
||||
Ly9jcmwuc2NhMWIuYW1hem9udHJ1c3QuY29tL3NjYTFiLTEuY3JsMBMGA1UdIAQM
|
||||
MAowCAYGZ4EMAQIBMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcwAYYhaHR0cDov
|
||||
L29jc3Auc2NhMWIuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAChipodHRwOi8v
|
||||
Y3J0LnNjYTFiLmFtYXpvbnRydXN0LmNvbS9zY2ExYi5jcnQwDAYDVR0TAQH/BAIw
|
||||
ADCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHYA6D7Q2j71BjUy51covIlryQPT
|
||||
y9ERa+zraeF3fW0GvW4AAAF/5g3wggAABAMARzBFAiEAi/U3UhS0wBO3ENr60raR
|
||||
eLOh2AG97uiMu5/XTpOitzkCIBS3J35I01Px5yxWB03Wbp5Q15rKflPnGdk4OxqA
|
||||
YhwCAHUANc8ZG7+xbFe/D61MbULLu7YnICZR6j/hKu+oA8M71kwAAAF/5g3wxwAA
|
||||
BAMARjBEAiBVLkL7vmHrvdgj4f9/EkWear0/EifCefzHAIkmZXROGgIgLM/cG6C/
|
||||
oz8y8uDEZI6ijXsmlpPDe4azrAL9qMZ1LHcAdwCzc3cH4YRQ+GOG1gWp3BEJSnkt
|
||||
sWcMC4fc8AMOeTalmgAAAX/mDfDrAAAEAwBIMEYCIQCc2ZP3gCZGJ8PQFrVZGk2K
|
||||
4L4ebIhQQrfp9irYeyyBXgIhAPF45dE3vSvxkf/Qr1yba0eYQa+F0P92wV6Cpkqa
|
||||
SHfrMA0GCSqGSIb3DQEBCwUAA4IBAQA4tbiyX/J+awY2zXRv7MhFFn5lg4qZLl59
|
||||
DKoxuVQ3/os1UkOE3z7rNJVQZ9v1DrsadooHIQ69Uz5JUcdpVz57tSZs5H6Cf5EW
|
||||
GaNgeeXvloME0G5KXAXBQ6NZrCaKzpOrGJRhKJGvrVgGhPqYAZ0fTXJ81vt5AICp
|
||||
55pwVIMTLPR4ewD/l/OWuned8zXjBF2+WQ7Ex5E0VIv9MuFN/URXGWQ+I+2uGyfW
|
||||
zlX9SweWNfLYYxTtY1duU7nzqnK6u2/N2IxO4Hkqehll3Ineyqdni4/CeMHOD06B
|
||||
ox01tCIdK1Wz5I7K/F2jc6jinmZHYlX+oHaY5lAh9FLsQ+luBgHd
|
||||
MIIHljCCBn6gAwIBAgIQC65deUww9ISBucGLLymfiTANBgkqhkiG9w0BAQsFADA8
|
||||
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g
|
||||
UlNBIDIwNDggTTAxMB4XDTIyMTIwNjAwMDAwMFoXDTIzMTIwNTIzNTk1OVowGzEZ
|
||||
MBcGA1UEAxMQczMuYW1hem9uYXdzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAOai9pH7hBruq8Z2Nh7PM3wTYkupXpQsfyV1aIoDE2Wb5Eq6j6lc
|
||||
XstKcAHOSBZomYCqRVjB06hWhT/Vmi8jCIUKj/4ylgl/OUD1Fmp3zPzzp0xXo6W1
|
||||
nMI8t66EnzHzMmUAFcaobb/+XGnsBM/JnOvFgcsnit5b0ohHSrrBkhqoPG9UV6s1
|
||||
ihoIu/inxP/OZK3julKF9DQeQFik+aY5xHyR7NU/YFvgXLOjFtZHNV4M/37K+E8q
|
||||
BG2Fc+23sn+6fRyhkgldIwbUcIgEVfbkRVWBP5zJVbYo7V3yOpauit3FIhTpVATO
|
||||
50AdnLYIPa8HtkEt74uKoiPAvEsX1KLlbFECAwEAAaOCBLMwggSvMB8GA1UdIwQY
|
||||
MBaAFIG4DmOKiRIY5fo7O1CVn+blkBOFMB0GA1UdDgQWBBQYwyLcdwl9dkli9Knk
|
||||
oe8DnTMQQzCCAeQGA1UdEQSCAdswggHXghBzMy5hbWF6b25hd3MuY29tghIqLnMz
|
||||
LmFtYXpvbmF3cy5jb22CJiouczMuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25h
|
||||
d3MuY29tgiRzMy5kdWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CHCou
|
||||
czMudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CGnMzLnVzLWVhc3QtMS5hbWF6b25h
|
||||
d3MuY29tgiQqLnMzLWNvbnRyb2wudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CInMz
|
||||
LWNvbnRyb2wudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CLiouczMtY29udHJvbC5k
|
||||
dWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CLHMzLWNvbnRyb2wuZHVh
|
||||
bHN0YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgigqLnMzLWFjY2Vzc3BvaW50
|
||||
LnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgjIqLnMzLWFjY2Vzc3BvaW50LmR1YWxz
|
||||
dGFjay51cy1lYXN0LTEuYW1hem9uYXdzLmNvbYIhKi5zMy51cy1lYXN0LTEudnBj
|
||||
ZS5hbWF6b25hd3MuY29tMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEF
|
||||
BQcDAQYIKwYBBQUHAwIwOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5yMm0w
|
||||
MS5hbWF6b250cnVzdC5jb20vcjJtMDEuY3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIB
|
||||
MHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcwAYYhaHR0cDovL29jc3AucjJtMDEu
|
||||
YW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAChipodHRwOi8vY3J0LnIybTAxLmFt
|
||||
YXpvbnRydXN0LmNvbS9yMm0wMS5jZXIwDAYDVR0TAQH/BAIwADCCAX0GCisGAQQB
|
||||
1nkCBAIEggFtBIIBaQFnAHYA6D7Q2j71BjUy51covIlryQPTy9ERa+zraeF3fW0G
|
||||
vW4AAAGE6TiWGwAABAMARzBFAiEAm7EmdOlYh6ZqCbcL031TNYm1It2F9ZOECd9k
|
||||
Efd5rR0CIARC57eeRuS5w2mHogwnKEokTsA8MiMDQs/ysF8NJAQhAHUAs3N3B+GE
|
||||
UPhjhtYFqdwRCUp5LbFnDAuH3PADDnk2pZoAAAGE6TiWJQAABAMARjBEAiAyQAFf
|
||||
DUdoch036Wz41eG8ukNAIZUNSo2XqOFUhGTrMQIgFwfTZ+Wk3DeuitGUeqRLTLOI
|
||||
/RDTjp6k9iwL5ScBYSwAdgC3Pvsk35xNunXyOcW6WPRsXfxCz3qfNcSeHQmBJe20
|
||||
mQAAAYTpOJXyAAAEAwBHMEUCIEjQE4RdlG0zH2oWP1OSi24e25WyUx3ww3fgLRMH
|
||||
MYWSAiEA795WZhOkmboCZi2wrStw4+nBQLtStAUYbbXGXhX1bWEwDQYJKoZIhvcN
|
||||
AQELBQADggEBAJO/33aYKDV+t01OfLUvRGR6wzcfW1dHmddMkH2CU0I+XJO8+rNe
|
||||
1txfh00UpBDxG/CP/rx+ulA72+XgiXURFC5NtKiyUXit58rMujj21UTmqf3/70DB
|
||||
KdJmMoXTIdz93ttmV4JpF3Oo3Wp8jXcRRKAJdH0aSOH1Fx+fcVa8u56WxsA7khGG
|
||||
/XJcCJomARKpf1W3x9tRAOq6hVkWKSC8V4pyhc6qvymcvgvPHysC+xrRD9RZ38Ui
|
||||
gijCabOG5gYIxE8DCBtVksYq2vxqVod8w8Kp+zHrLYwQbAbrk8JRsdT75GJ/LZhl
|
||||
XAauB98KOqLvlBtdpu8GaAvtpN95tRMkab8=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
Binary file not shown.
@@ -1,25 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIESTCCAzGgAwIBAgITBn+UV4WH6Kx33rJTMlu8mYtWDTANBgkqhkiG9w0BAQsF
|
||||
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
|
||||
b24gUm9vdCBDQSAxMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjEL
|
||||
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENB
|
||||
IDFCMQ8wDQYDVQQDEwZBbWF6b24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
|
||||
AoIBAQDCThZn3c68asg3Wuw6MLAd5tES6BIoSMzoKcG5blPVo+sDORrMd4f2AbnZ
|
||||
cMzPa43j4wNxhplty6aUKk4T1qe9BOwKFjwK6zmxxLVYo7bHViXsPlJ6qOMpFge5
|
||||
blDP+18x+B26A0piiQOuPkfyDyeR4xQghfj66Yo19V+emU3nazfvpFA+ROz6WoVm
|
||||
B5x+F2pV8xeKNR7u6azDdU5YVX1TawprmxRC1+WsAYmz6qP+z8ArDITC2FMVy2fw
|
||||
0IjKOtEXc/VfmtTFch5+AfGYMGMqqvJ6LcXiAhqG5TI+Dr0RtM88k+8XUBCeQ8IG
|
||||
KuANaL7TiItKZYxK1MMuTJtV9IblAgMBAAGjggE7MIIBNzASBgNVHRMBAf8ECDAG
|
||||
AQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUWaRmBlKge5WSPKOUByeW
|
||||
dFv5PdAwHwYDVR0jBBgwFoAUhBjMhTTsvAyUlC4IWZzHshBOCggwewYIKwYBBQUH
|
||||
AQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5yb290Y2ExLmFtYXpvbnRy
|
||||
dXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDovL2NydC5yb290Y2ExLmFtYXpvbnRy
|
||||
dXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3Js
|
||||
LnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jvb3RjYTEuY3JsMBMGA1UdIAQMMAow
|
||||
CAYGZ4EMAQIBMA0GCSqGSIb3DQEBCwUAA4IBAQCFkr41u3nPo4FCHOTjY3NTOVI1
|
||||
59Gt/a6ZiqyJEi+752+a1U5y6iAwYfmXss2lJwJFqMp2PphKg5625kXg8kP2CN5t
|
||||
6G7bMQcT8C8xDZNtYTd7WPD8UZiRKAJPBXa30/AbwuZe0GaFEQ8ugcYQgSn+IGBI
|
||||
8/LwhBNTZTUVEWuCUUBVV18YtbAiPq3yXqMB48Oz+ctBWuZSkbvkNodPLamkB2g1
|
||||
upRyzQ7qDn1X8nn8N8V7YJ6y68AtkHcNSRAnpTitxBKjtKPISLMVCx7i4hncxHZS
|
||||
yLyKQXhw2W2Xs0qLeC1etA+jTGDK4UfLeC0SF7FSi8o5LL21L8IzApar2pR/
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,3 +1,13 @@
|
||||
|
||||
# Check if the required dependencies are installed
|
||||
find_package(Python3 COMPONENTS Interpreter)
|
||||
if(Python3_Interpreter_FOUND)
|
||||
execute_process(COMMAND pip3 install protobuf grpcio-tools)
|
||||
else()
|
||||
message(FATAL_ERROR "Python3 interpreter not found. Please install Python3 before building the project.")
|
||||
endif()
|
||||
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
function(___register_flash partition_name sub_type)
|
||||
|
||||
Reference in New Issue
Block a user