mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-08 20:47:08 +03:00
move to Apple alac decoder, update partition size
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,55 +0,0 @@
|
|||||||
#ifndef __ALAC__DECOMP_H
|
|
||||||
#define __ALAC__DECOMP_H
|
|
||||||
|
|
||||||
typedef struct alac_file alac_file;
|
|
||||||
|
|
||||||
alac_file *create_alac(int samplesize, int numchannels);
|
|
||||||
void delete_alac(alac_file *alac);
|
|
||||||
void decode_frame(alac_file *alac,
|
|
||||||
unsigned char *inbuffer,
|
|
||||||
void *outbuffer, int *outputsize);
|
|
||||||
void alac_set_info(alac_file *alac, char *inputbuffer);
|
|
||||||
void allocate_buffers(alac_file *alac);
|
|
||||||
|
|
||||||
struct alac_file
|
|
||||||
{
|
|
||||||
unsigned char *input_buffer;
|
|
||||||
int input_buffer_bitaccumulator; /* used so we can do arbitary
|
|
||||||
bit reads */
|
|
||||||
|
|
||||||
int samplesize;
|
|
||||||
int numchannels;
|
|
||||||
int bytespersample;
|
|
||||||
|
|
||||||
|
|
||||||
/* buffers */
|
|
||||||
int32_t *predicterror_buffer_a;
|
|
||||||
int32_t *predicterror_buffer_b;
|
|
||||||
|
|
||||||
int32_t *outputsamples_buffer_a;
|
|
||||||
int32_t *outputsamples_buffer_b;
|
|
||||||
|
|
||||||
int32_t *uncompressed_bytes_buffer_a;
|
|
||||||
int32_t *uncompressed_bytes_buffer_b;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* stuff from setinfo */
|
|
||||||
uint32_t setinfo_max_samples_per_frame; /* 0x1000 = 4096 */ /* max samples per frame? */
|
|
||||||
uint8_t setinfo_7a; /* 0x00 */
|
|
||||||
uint8_t setinfo_sample_size; /* 0x10 */
|
|
||||||
uint8_t setinfo_rice_historymult; /* 0x28 */
|
|
||||||
uint8_t setinfo_rice_initialhistory; /* 0x0a */
|
|
||||||
uint8_t setinfo_rice_kmodifier; /* 0x0e */
|
|
||||||
uint8_t setinfo_7f; /* 0x02 */
|
|
||||||
uint16_t setinfo_80; /* 0x00ff */
|
|
||||||
uint32_t setinfo_82; /* 0x000020e7 */ /* max sample size?? */
|
|
||||||
uint32_t setinfo_86; /* 0x00069fe4 */ /* bit rate (avarge)?? */
|
|
||||||
uint32_t setinfo_8a_rate; /* 0x0000ac44 */
|
|
||||||
/* end setinfo stuff */
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __ALAC__DECOMP_H */
|
|
||||||
|
|
||||||
@@ -109,13 +109,13 @@ struct raop_ctx_s *raop_create(struct in_addr host, char *name,
|
|||||||
struct raop_ctx_s *ctx = malloc(sizeof(struct raop_ctx_s));
|
struct raop_ctx_s *ctx = malloc(sizeof(struct raop_ctx_s));
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
char id[64];
|
char id[64];
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
socklen_t nlen = sizeof(struct sockaddr);
|
socklen_t nlen = sizeof(struct sockaddr);
|
||||||
char *txt[] = { "am=airesp32", "tp=UDP", "sm=false", "sv=false", "ek=1",
|
char *txt[] = { "am=airesp32", "tp=UDP", "sm=false", "sv=false", "ek=1",
|
||||||
"et=0,1", "md=0,1,2", "cn=0,1", "ch=2",
|
"et=0,1", "md=0,1,2", "cn=0,1", "ch=2",
|
||||||
"ss=16", "sr=44100", "vn=3", "txtvers=1",
|
"ss=16", "sr=44100", "vn=3", "txtvers=1",
|
||||||
NULL };
|
NULL };
|
||||||
#else
|
#else
|
||||||
mdns_txt_item_t txt[] = {
|
mdns_txt_item_t txt[] = {
|
||||||
{"am", "airesp32"},
|
{"am", "airesp32"},
|
||||||
@@ -155,7 +155,8 @@ struct raop_ctx_s *raop_create(struct in_addr host, char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
addr.sin_addr.s_addr = host.s_addr;
|
addr.sin_addr.s_addr = host.s_addr;
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
ctx->port = 0;
|
ctx->port = 0;
|
||||||
addr.sin_port = htons(ctx->port);
|
addr.sin_port = htons(ctx->port);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* HairTunes - RAOP packet handler and slave-clocked replay engine
|
* HairTunes - RAOP packet handler and slave-clocked replay engine
|
||||||
* Copyright (c) James Laird 2011
|
* Copyright (c) James Laird 2011
|
||||||
@@ -47,14 +48,13 @@
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <openssl/aes.h>
|
#include <openssl/aes.h>
|
||||||
#include "alac.h"
|
#include "alac_wrapper.h"
|
||||||
#else
|
#else
|
||||||
#include "esp_pthread.h"
|
#include "esp_pthread.h"
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#include <mbedtls/version.h>
|
#include <mbedtls/version.h>
|
||||||
#include <mbedtls/aes.h>
|
#include <mbedtls/aes.h>
|
||||||
//#include "alac_wrapper.h"
|
#include "alac_wrapper.h"
|
||||||
#include "alac.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NTP2MS(ntp) ((((ntp) >> 10) * 1000L) >> 22)
|
#define NTP2MS(ntp) ((((ntp) >> 10) * 1000L) >> 22)
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
//#define __RTP_STORE
|
//#define __RTP_STORE
|
||||||
|
|
||||||
// default buffer size
|
// default buffer size
|
||||||
#define BUFFER_FRAMES ( (150 * RAOP_SAMPLE_RATE * 2) / (352 * 100) )
|
#define BUFFER_FRAMES ( (150 * RAOP_SAMPLE_RATE * 2) / (352 * 100) )
|
||||||
#define MAX_PACKET 1408
|
#define MAX_PACKET 1408
|
||||||
#define MIN_LATENCY 11025
|
#define MIN_LATENCY 11025
|
||||||
@@ -141,7 +141,8 @@ typedef struct rtp_s {
|
|||||||
#else
|
#else
|
||||||
TaskHandle_t thread, joiner;
|
TaskHandle_t thread, joiner;
|
||||||
StaticTask_t *xTaskBuffer;
|
StaticTask_t *xTaskBuffer;
|
||||||
StackType_t *xStack;
|
StackType_t *xStack;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct alac_codec_s *alac_codec;
|
struct alac_codec_s *alac_codec;
|
||||||
int flush_seqno;
|
int flush_seqno;
|
||||||
@@ -160,35 +161,42 @@ static void* rtp_thread_func(void *arg);
|
|||||||
static bool rtp_request_timing(rtp_t *ctx);
|
static bool rtp_request_timing(rtp_t *ctx);
|
||||||
static void* rtp_thread_func(void *arg);
|
static void* rtp_thread_func(void *arg);
|
||||||
static int seq_order(seq_t a, seq_t b);
|
static int seq_order(seq_t a, seq_t b);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static alac_file* alac_init(int fmtp[32]) {
|
static struct alac_codec_s* alac_init(int fmtp[32]) {
|
||||||
|
struct alac_codec_s *alac;
|
||||||
|
unsigned sample_rate;
|
||||||
|
unsigned char sample_size, channels;
|
||||||
|
struct {
|
||||||
|
uint32_t frameLength;
|
||||||
|
uint8_t compatibleVersion;
|
||||||
|
uint8_t bitDepth;
|
||||||
|
uint8_t pb;
|
||||||
|
uint8_t mb;
|
||||||
|
uint8_t kb;
|
||||||
|
uint8_t numChannels;
|
||||||
|
uint16_t maxRun;
|
||||||
|
uint32_t maxFrameBytes;
|
||||||
|
uint32_t avgBitRate;
|
||||||
uint32_t sampleRate;
|
uint32_t sampleRate;
|
||||||
int sample_size = fmtp[3];
|
} config;
|
||||||
|
|
||||||
if (sample_size != 16) {
|
config.frameLength = htonl(fmtp[1]);
|
||||||
LOG_ERROR("sample size must be 16 %d", sample_size);
|
config.compatibleVersion = fmtp[2];
|
||||||
return false;
|
config.bitDepth = fmtp[3];
|
||||||
}
|
config.pb = fmtp[4];
|
||||||
|
config.mb = fmtp[5];
|
||||||
|
config.kb = fmtp[6];
|
||||||
|
config.numChannels = fmtp[7];
|
||||||
|
config.maxRun = htons(fmtp[8]);
|
||||||
|
config.maxFrameBytes = htonl(fmtp[9]);
|
||||||
config.avgBitRate = htonl(fmtp[10]);
|
config.avgBitRate = htonl(fmtp[10]);
|
||||||
|
config.sampleRate = htonl(fmtp[11]);
|
||||||
|
|
||||||
alac = alac_create_decoder(sizeof(config), (unsigned char*) &config, &sample_size, &sample_rate, &channels);
|
alac = alac_create_decoder(sizeof(config), (unsigned char*) &config, &sample_size, &sample_rate, &channels);
|
||||||
if (!alac) {
|
if (!alac) {
|
||||||
LOG_ERROR("cannot create alac codec", NULL);
|
LOG_ERROR("cannot create alac codec", NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
alac->setinfo_max_samples_per_frame = fmtp[1];
|
|
||||||
alac->setinfo_7a = fmtp[2];
|
|
||||||
alac->setinfo_sample_size = sample_size;
|
|
||||||
alac->setinfo_rice_historymult = fmtp[4];
|
|
||||||
alac->setinfo_rice_initialhistory = fmtp[5];
|
|
||||||
alac->setinfo_rice_kmodifier = fmtp[6];
|
|
||||||
alac->setinfo_7f = fmtp[7];
|
|
||||||
alac->setinfo_80 = fmtp[8];
|
|
||||||
alac->setinfo_82 = fmtp[9];
|
|
||||||
alac->setinfo_86 = fmtp[10];
|
|
||||||
alac->setinfo_8a_rate = fmtp[11];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return alac;
|
return alac;
|
||||||
@@ -294,7 +302,7 @@ void rtp_end(rtp_t *ctx)
|
|||||||
#if !defined WIN32
|
#if !defined WIN32
|
||||||
ctx->joiner = xTaskGetCurrentTaskHandle();
|
ctx->joiner = xTaskGetCurrentTaskHandle();
|
||||||
#endif
|
#endif
|
||||||
ctx->running = false;
|
ctx->running = false;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
pthread_join(ctx->thread, NULL);
|
pthread_join(ctx->thread, NULL);
|
||||||
#else
|
#else
|
||||||
@@ -304,7 +312,7 @@ void rtp_end(rtp_t *ctx)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 3; i++) closesocket(ctx->rtp_sockets[i].sock);
|
for (i = 0; i < 3; i++) closesocket(ctx->rtp_sockets[i].sock);
|
||||||
|
|
||||||
if (ctx->alac_codec) alac_delete_decoder(ctx->alac_codec);
|
if (ctx->alac_codec) alac_delete_decoder(ctx->alac_codec);
|
||||||
if (ctx->decrypt_buf) free(ctx->decrypt_buf);
|
if (ctx->decrypt_buf) free(ctx->decrypt_buf);
|
||||||
@@ -396,8 +404,12 @@ static void alac_decode(rtp_t *ctx, s16_t *dest, char *buf, int len, int *outsiz
|
|||||||
AES_cbc_encrypt((unsigned char*)buf, ctx->decrypt_buf, aeslen, &ctx->aes, iv, AES_DECRYPT);
|
AES_cbc_encrypt((unsigned char*)buf, ctx->decrypt_buf, aeslen, &ctx->aes, iv, AES_DECRYPT);
|
||||||
#else
|
#else
|
||||||
mbedtls_aes_crypt_cbc(&ctx->aes, MBEDTLS_AES_DECRYPT, aeslen, iv, (unsigned char*) buf, ctx->decrypt_buf);
|
mbedtls_aes_crypt_cbc(&ctx->aes, MBEDTLS_AES_DECRYPT, aeslen, iv, (unsigned char*) buf, ctx->decrypt_buf);
|
||||||
#endif
|
#endif
|
||||||
memcpy(ctx->decrypt_buf+aeslen, buf+aeslen, len-aeslen);
|
memcpy(ctx->decrypt_buf+aeslen, buf+aeslen, len-aeslen);
|
||||||
|
alac_to_pcm(ctx->alac_codec, (unsigned char*) ctx->decrypt_buf, (unsigned char*) dest, 2, (unsigned int*) outsize);
|
||||||
|
} else {
|
||||||
|
alac_to_pcm(ctx->alac_codec, (unsigned char*) buf, (unsigned char*) dest, 2, (unsigned int*) outsize);
|
||||||
|
}
|
||||||
|
|
||||||
*outsize *= 4;
|
*outsize *= 4;
|
||||||
}
|
}
|
||||||
@@ -506,28 +518,8 @@ static void buffer_push_packet(rtp_t *ctx) {
|
|||||||
playtime = ctx->synchro.time + (((s32_t)(curframe->rtptime - ctx->synchro.rtp)) * 1000) / RAOP_SAMPLE_RATE;
|
playtime = ctx->synchro.time + (((s32_t)(curframe->rtptime - ctx->synchro.rtp)) * 1000) / RAOP_SAMPLE_RATE;
|
||||||
|
|
||||||
if (now > playtime) {
|
if (now > playtime) {
|
||||||
|
LOG_DEBUG("[%p]: discarded frame now:%u missed by:%d (W:%hu R:%hu)", ctx, now, now - playtime, ctx->ab_write, ctx->ab_read);
|
||||||
ctx->discarded++;
|
ctx->discarded++;
|
||||||
ctx->discarded++;
|
|
||||||
} else if (curframe->ready) {
|
|
||||||
/*
|
|
||||||
// some dirty code to see if the click problem comes from i2s stage or decoder stage
|
|
||||||
static s16_t sin_data[200];
|
|
||||||
static bool gen = false;
|
|
||||||
|
|
||||||
if (!gen) {
|
|
||||||
for (i = 0; i < 200; i++) sin_data[i] = 1024 * sin((2*3.14159*220.5*i)/44100.);
|
|
||||||
gen = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int c = 0;
|
|
||||||
int cnt = 0;
|
|
||||||
s16_t *p = (s16_t*) curframe->data;
|
|
||||||
|
|
||||||
while (cnt++ < 352) {
|
|
||||||
*p = sin_data[c++ % 200];
|
|
||||||
*(p+1) = *p;
|
|
||||||
p += 2;
|
|
||||||
}
|
|
||||||
curframe->ready = 0;
|
curframe->ready = 0;
|
||||||
} else if (curframe->ready) {
|
} else if (curframe->ready) {
|
||||||
ctx->data_cb((const u8_t*) curframe->data, curframe->len, playtime);
|
ctx->data_cb((const u8_t*) curframe->data, curframe->len, playtime);
|
||||||
|
|||||||
@@ -192,7 +192,6 @@ void raop_sink_cmd_handler(raop_event_t event, void *param)
|
|||||||
error = (raop_sync.playtime - now) - ms;
|
error = (raop_sync.playtime - now) - ms;
|
||||||
LOG_INFO("head local:%u, remote:%u (delta:%d)", ms, raop_sync.playtime - now, error);
|
LOG_INFO("head local:%u, remote:%u (delta:%d)", ms, raop_sync.playtime - now, error);
|
||||||
LOG_DEBUG("obuf:%u, sync_len:%u, devframes:%u, inproc:%u", _buf_used(outputbuf), raop_sync.len, output.device_frames, output.frames_in_process);
|
LOG_DEBUG("obuf:%u, sync_len:%u, devframes:%u, inproc:%u", _buf_used(outputbuf), raop_sync.len, output.device_frames, output.frames_in_process);
|
||||||
//break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error < -10 && raop_sync.error < -10) {
|
if (error < -10 && raop_sync.error < -10) {
|
||||||
@@ -208,7 +207,6 @@ void raop_sink_cmd_handler(raop_event_t event, void *param)
|
|||||||
}
|
}
|
||||||
|
|
||||||
raop_sync.error = error;
|
raop_sync.error = error;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RAOP_SETUP:
|
case RAOP_SETUP:
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
|
# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
|
||||||
nvs, data, nvs, 0x9000, 0x6000,
|
nvs, data, nvs, 0x9000, 0x6000,
|
||||||
phy_init, data, phy, 0xf000, 0x1000,
|
phy_init, data, phy, 0xf000, 0x1000,
|
||||||
factory, app, factory, 0x10000, 2M,
|
factory, app, factory, 0x10000, 3M,
|
||||||
storage, data, fat, , 819200,
|
storage, data, fat, , 819200,
|
||||||
coredump, data, coredump,, 64K
|
coredump, data, coredump,, 64K
|
||||||
|
Reference in New Issue
Block a user