Step 7.5b1: cspot (philippe44 fork) builds and links on the P4
- external/cspot: git submodule, pinned to philippe44/cspot 3010349 (bell ed2d6e9); GPL-3.0. - components/spotify: project component wrapping cspot. bell trimmed to what cspot needs (Tremor Vorbis; no codec wrapper, sinks, MQTT, web server, fmt, regex; cJSON from IDF). Xtensa biquad assembly filtered out (P4 is RISC-V). CMAKE_POLICY_VERSION_MINIMUM 3.5 for CMake 4. - Patches in components/spotify/patches, applied at configure time: nanopb generator works with protobuf >= 5 (MakeClass removed); URLParser.cpp missing <cstdio>/<cstring> for GCC 14. - CONFIG_COMPILER_CXX_EXCEPTIONS=y (cspot needs exceptions). - spotify_init() only builds a LoginBlob (link check). - CLAUDE.md: submodule init and IDF-venv Python packages for nanopb. - Verified on board: "cspot linked: device "P4 AES67", zeroconf info 588 bytes"; HLS still playing, PTP locked; image 1.83 MB (70% free). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
# Spotify Connect via cspot (philippe44 fork, git submodule external/cspot). GPL-3.0.
|
||||
# Project component (not part of the reusable aes67_* core).
|
||||
idf_component_register(SRCS "spotify.cpp"
|
||||
INCLUDE_DIRS "include"
|
||||
PRIV_REQUIRES espressif__mdns mbedtls json pthread lwip esp_timer)
|
||||
|
||||
# bell: only what cspot needs (Tremor Vorbis inside; no codec wrapper, sinks, MQTT, web server).
|
||||
set(BELL_DISABLE_CODECS ON CACHE BOOL "" FORCE)
|
||||
set(BELL_DISABLE_SINKS ON CACHE BOOL "" FORCE)
|
||||
set(BELL_DISABLE_MQTT ON CACHE BOOL "" FORCE)
|
||||
set(BELL_DISABLE_WEBSERVER ON CACHE BOOL "" FORCE)
|
||||
set(BELL_DISABLE_FMT ON CACHE BOOL "" FORCE)
|
||||
set(BELL_DISABLE_REGEX ON CACHE BOOL "" FORCE)
|
||||
set(BELL_ONLY_CJSON ON CACHE BOOL "" FORCE)
|
||||
set(BELL_EXTERNAL_CJSON idf::json CACHE STRING "" FORCE)
|
||||
option(BUILD_TESTING OFF)
|
||||
|
||||
# Our fixes to the pinned cspot / bell sources (newer GCC, protobuf, CMake), kept as patch files:
|
||||
# patches/cspot/*.patch apply in external/cspot, patches/bell/*.patch in external/cspot/cspot/bell.
|
||||
# Each is applied once (skipped when it already reverse-applies).
|
||||
function(spotify_apply_patches dir repo)
|
||||
file(GLOB patches "${CMAKE_CURRENT_LIST_DIR}/patches/${dir}/*.patch")
|
||||
list(SORT patches)
|
||||
foreach(p ${patches})
|
||||
execute_process(COMMAND git apply --reverse --check "${p}" WORKING_DIRECTORY "${repo}"
|
||||
RESULT_VARIABLE applied OUTPUT_QUIET ERROR_QUIET)
|
||||
if(NOT applied EQUAL 0)
|
||||
execute_process(COMMAND git apply "${p}" WORKING_DIRECTORY "${repo}" RESULT_VARIABLE rc)
|
||||
if(NOT rc EQUAL 0)
|
||||
message(FATAL_ERROR "spotify: patch does not apply: ${p}")
|
||||
endif()
|
||||
message(STATUS "spotify: applied ${p}")
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
spotify_apply_patches(cspot "${PROJECT_DIR}/external/cspot")
|
||||
spotify_apply_patches(bell "${PROJECT_DIR}/external/cspot/cspot/bell")
|
||||
|
||||
# cspot/bell declare cmake_minimum_required(2.8.12); CMake 4 rejects < 3.5 unless told otherwise.
|
||||
set(CMAKE_POLICY_VERSION_MINIMUM 3.5)
|
||||
add_subdirectory(${PROJECT_DIR}/external/cspot/cspot ${CMAKE_CURRENT_BINARY_DIR}/cspot)
|
||||
|
||||
# bell adds Xtensa (ESP32) assembly for a DSP biquad; the P4 is RISC-V and cspot does not use it.
|
||||
get_target_property(BELL_SRCS bell SOURCES)
|
||||
list(FILTER BELL_SRCS EXCLUDE REGEX "\\.S$")
|
||||
set_target_properties(bell PROPERTIES SOURCES "${BELL_SRCS}")
|
||||
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE cspot)
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE -std=gnu++20)
|
||||
@@ -0,0 +1,14 @@
|
||||
// Spotify Connect (cspot). Project code; GPL-3.0 through cspot.
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
esp_err_t spotify_init(const char *device_name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
diff --git a/external/nanopb/generator/nanopb_generator.py b/external/nanopb/generator/nanopb_generator.py
|
||||
index e40f18b..64dad5e 100755
|
||||
--- a/external/nanopb/generator/nanopb_generator.py
|
||||
+++ b/external/nanopb/generator/nanopb_generator.py
|
||||
@@ -1463,7 +1463,12 @@ class Message(ProtoElement):
|
||||
optional_only.ClearField(str('extension'))
|
||||
optional_only.ClearField(str('enum_type'))
|
||||
desc = google.protobuf.descriptor.MakeDescriptor(optional_only)
|
||||
- msg = reflection.MakeClass(desc)()
|
||||
+ # protobuf >= 5 removed reflection.MakeClass (patch for this project)
|
||||
+ try:
|
||||
+ msg = reflection.MakeClass(desc)()
|
||||
+ except AttributeError:
|
||||
+ from google.protobuf import message_factory
|
||||
+ msg = message_factory.GetMessageClass(desc)()
|
||||
|
||||
for field in optional_only.field:
|
||||
if field.type == FieldD.TYPE_STRING:
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/main/io/URLParser.cpp b/main/io/URLParser.cpp
|
||||
index 4a50ab1..af679ec 100644
|
||||
--- a/main/io/URLParser.cpp
|
||||
+++ b/main/io/URLParser.cpp
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "URLParser.h"
|
||||
|
||||
+#include <cstdio> // sscanf (GCC 14 / ESP-IDF 5.5: not included transitively)
|
||||
+#include <cstring> // strstr
|
||||
+
|
||||
namespace bell {
|
||||
|
||||
#ifdef BELL_DISABLE_REGEX
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "spotify.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "LoginBlob.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "spotify";
|
||||
|
||||
// Step 7.5b1: link check only. Zeroconf, login and audio follow in b2/b3.
|
||||
extern "C" esp_err_t spotify_init(const char *device_name)
|
||||
{
|
||||
auto blob = std::make_shared<cspot::LoginBlob>(device_name);
|
||||
std::string info = blob->buildZeroconfInfo();
|
||||
ESP_LOGI(TAG, "cspot linked: device \"%s\", zeroconf info %u bytes", device_name, (unsigned)info.size());
|
||||
return ESP_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user