diff --git a/CMakeLists.txt b/CMakeLists.txt index 93922b9..534d257 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,8 +4,11 @@ project(pipedal DESCRIPTION "PiPedal Guitar Effect Pedal For Raspberry Pi" HOMEPAGE_URL "https://rerdavies.github.io/pipedal" ) + +EXECUTE_PROCESS( COMMAND dpkg --print-architecture COMMAND tr -d '\n' OUTPUT_VARIABLE DEBIAN_ARCHITECTURE ) + set (DISPLAY_VERSION "PiPedal v1.3.66-Release") -set (PACKAGE_ARCHITECTURE "arm64") +set (PACKAGE_ARCHITECTURE ${DEBIAN_ARCHITECTURE}) set (CMAKE_INSTALL_PREFIX "/usr/") include(CTest) @@ -28,16 +31,6 @@ add_subdirectory("src") # install (TARGETS pipedal_nm_p2pd DESTINATION ${CMAKE_INSTALL_PREFIX}/sbin # ) -# select LV2 source directory for the current build architecture - -message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") -set(LV2_SOURCE_DIRECTORY ${PROJECT_SOURCE_DIR}/lv2/${CMAKE_SYSTEM_PROCESSOR}/ToobAmp.lv2) - -if (NOT EXISTS ${LV2_SOURCE_DIRECTORY}) - message(FATAL_ERROR "Lv2 Binaries for architecture '${CMAKE_SYSTEM_PROCESSOR}' have not been provisioned. See lv2/Readme.md") -endif() -# add_subdirectory("test") - # add_test(NAME Test COMMAND piddletest) set (REACT_BUILD_DIRECTORY ${PROJECT_SOURCE_DIR}/build/react/build/) @@ -73,22 +66,34 @@ install ( DESTINATION /etc/pipedal/config ) -install (DIRECTORY ${LV2_SOURCE_DIRECTORY} - DESTINATION /usr/lib/lv2 -) -install(CODE -[[ - file(GET_RUNTIME_DEPENDENCIES - EXECUTABLES - ${CMAKE_INSTALL_PREFIX}/sbin/pipedaladmind - ${CMAKE_INSTALL_PREFIX}/sbin/pipedald - ${CMAKE_INSTALL_PREFIX}/sbin/pipedal_update - #${CMAKE_INSTALL_PREFIX}/sbin/pipedal_nm_p2pd - #${CMAKE_INSTALL_PREFIX}/sbin/pipedal_p2pd - ${CMAKE_INSTALL_PREFIX}/bin/pipedalconfig +message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") + + +if ("${DEBIAN_ARCHITECTURE}" MATCHES "arm64") + + # select LV2 source directory for the current build architecture + + set(LV2_SOURCE_DIRECTORY ${PROJECT_SOURCE_DIR}/build/lv2/${CMAKE_SYSTEM_PROCESSOR}/ToobAmp.lv2) + + install (DIRECTORY ${LV2_SOURCE_DIRECTORY} + DESTINATION /usr/lib/lv2 ) -]] -) +elseif("${DEBIAN_ARCHITECTURE}" MATCHES "amd64") + + add_custom_target(extract_toobamp_lv2_files ALL + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/lv2/x86_64/unpackArtifact.sh + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Extracting x64 ToobAmp components" + ) + + set(LV2_SOURCE_DIRECTORY ${PROJECT_SOURCE_DIR}/build/lv2_x64/pkg/usr/lib/lv2/ToobAmp.lv2) + + install (DIRECTORY ${LV2_SOURCE_DIRECTORY} + DESTINATION /usr/lib/lv2 + ) +else() + message(FATAL_ERROR "Unknown/unsupported build architecture: ${DEBIAN_ARCHITECTURE}") +endif() set(CPACK_GENERATOR "DEB") @@ -99,9 +104,7 @@ set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "IoT guitar effect pedal for Raspberry Pi" set(CPACK_DEBIAN_PACKAGE_SECTION sound) set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE) -#set(CPACK_DEBIAN_PACKAGE_DEPENDS "jackd2, hostapd, dhcpcd, dnsmasq" ) set(CPACK_DEBIAN_PACKAGE_DEPENDS "lv2-dev, authbind, gpg" ) -#set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "arm64") set(CPACK_PACKAGING_INSTALL_PREFIX /usr) set(CPACK_PROJECT_NAME ${PROJECT_NAME}) set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) diff --git a/lv2/Readme.md b/lv2/Readme.md index b4e7df5..7d59e52 100644 --- a/lv2/Readme.md +++ b/lv2/Readme.md @@ -3,3 +3,12 @@ This folder contains pre-built binaries for an initial bundle of Lv2 plugins. This arrangment is temporary, and is expected to go away, once a reliable distribution of this project and the ToobAmp project via apt can be arranged. +To update the arm64 binaries for ToobAmp, build the ToobAmp project, run `./install.sh` in the ToobAmp project directory, +and then run `./provisionLv2` in the pipedal root directory. This copies the ToobAmp binaries into the pipedal source tree. + +The x86_64 binaries are, instead built from an artifact provided by the github CMake build action. Currently, these +binaries are built on an Ubuntu 24.04 LTS build runner. PiPedals's build runner should run on the same build runner +configuration. The CMake build process will unpack the artifact, and extract ToobAmp LV2 binaries into the build directory +where the debian package can pick them up. + + diff --git a/lv2/x86_64/artifact.zip b/lv2/x86_64/toobamp_1.1.53_amd64.deb similarity index 90% rename from lv2/x86_64/artifact.zip rename to lv2/x86_64/toobamp_1.1.53_amd64.deb index 962e9b1..4023bf9 100644 Binary files a/lv2/x86_64/artifact.zip and b/lv2/x86_64/toobamp_1.1.53_amd64.deb differ diff --git a/lv2/x86_64/unpackArtifact.sh b/lv2/x86_64/unpackArtifact.sh new file mode 100755 index 0000000..a01412f --- /dev/null +++ b/lv2/x86_64/unpackArtifact.sh @@ -0,0 +1,7 @@ +#!/usr/bin/bash + +rm -rf build/lv2_x64 +mkdir build/lv2_x64 + +mkdir build/lv2_x64/pkg +dpkg-deb -x lv2/x86_64/toobamp_*_amd64.deb build/lv2_x64/pkg \ No newline at end of file diff --git a/react/src/GovernorSettings.tsx b/react/src/GovernorSettings.tsx index 6190491..ed13940 100644 --- a/react/src/GovernorSettings.tsx +++ b/react/src/GovernorSettings.tsx @@ -21,6 +21,7 @@ export default class GovernorSettings { deserialize(input: any) : GovernorSettings{ + this.hasGovernor = input.hasGovernor; this.governors = input.governors; this.governor = input.governor; return this; @@ -29,6 +30,7 @@ export default class GovernorSettings { { return new GovernorSettings().deserialize(this); } + hasGovernor: boolean = true; governors: string[] = ["ondemand","performance"]; governor: string = "performance"; diff --git a/react/src/JackHostStatus.tsx b/react/src/JackHostStatus.tsx index 359671c..673a00d 100644 --- a/react/src/JackHostStatus.tsx +++ b/react/src/JackHostStatus.tsx @@ -19,10 +19,10 @@ import React from 'react'; import Typography from '@mui/material/Typography'; -import {isDarkMode} from './DarkMode'; +import { isDarkMode } from './DarkMode'; -const RED_COLOR = isDarkMode()? "#F88":"#C00"; -const GREEN_COLOR = isDarkMode()? "rgba(255,255,255,0.7)": "#666"; +const RED_COLOR = isDarkMode() ? "#F88" : "#C00"; +const GREEN_COLOR = isDarkMode() ? "rgba(255,255,255,0.7)" : "#666"; @@ -33,23 +33,18 @@ function cpuDisplay(cpu: number): string { return cpu.toFixed(1) + "%"; } -function fmtCpuFreq(freq: number): string -{ - if (freq >= 100000000) - { - return (freq/1000000).toFixed(1) + " GHz"; +function fmtCpuFreq(freq: number): string { + if (freq >= 100000000) { + return (freq / 1000000).toFixed(1) + " GHz"; } - if (freq >= 10000000) - { - return (freq/1000000).toFixed(2) + " GHz"; + if (freq >= 10000000) { + return (freq / 1000000).toFixed(2) + " GHz"; } - if (freq >= 1000000) - { - return (freq/1000000).toFixed(3) + " GHz"; + if (freq >= 1000000) { + return (freq / 1000000).toFixed(3) + " GHz"; } - if (freq >= 1000) - { - return (freq/1000).toFixed(3) + " MHz"; + if (freq >= 1000) { + return (freq / 1000).toFixed(3) + " MHz"; } return freq + " KHz"; } @@ -65,6 +60,7 @@ export default class JackHostStatus { this.temperaturemC = input.temperaturemC; this.cpuFreqMax = input.cpuFreqMax; this.cpuFreqMin = input.cpuFreqMin; + this.hasCpuGovernor = input.hasCpuGovernor; this.governor = input.governor; return this; } @@ -80,6 +76,7 @@ export default class JackHostStatus { temperaturemC: number = -1000000; cpuFreqMax: number = 0; cpuFreqMin: number = 0; + hasCpuGovernor: boolean = false; governor: string = ""; static getCpuInfo(label: string, status?: JackHostStatus): React.ReactNode { @@ -91,18 +88,21 @@ export default class JackHostStatus { } return (
{label} - - { - (status.cpuFreqMax === status.cpuFreqMin)? - ( - {status.governor} {fmtCpuFreq(status.cpuFreqMax)} - ) - :( - {status.governor} {fmtCpuFreq(status.cpuFreqMax)}-{fmtCpuFreq(status.cpuFreqMax)} + {(status.cpuFreqMin != 0 || status.cpuFreqMax != 0) && + ( + + { + (status.cpuFreqMax === status.cpuFreqMin) ? + ( + {status.governor} {fmtCpuFreq(status.cpuFreqMax)} + ) + : ( + {status.governor} {fmtCpuFreq(status.cpuFreqMax)}-{fmtCpuFreq(status.cpuFreqMax)} - ) - } - + ) + } + + )}
); diff --git a/src/AdminClient.cpp b/src/AdminClient.cpp index 7db67ca..55dadc4 100644 --- a/src/AdminClient.cpp +++ b/src/AdminClient.cpp @@ -28,6 +28,7 @@ #include #include #include "Ipv6Helpers.hpp" +#include "CpuGovernor.hpp" using namespace pipedal; @@ -143,6 +144,10 @@ void AdminClient::SetGovernorSettings(const std::string &settings) { throw PiPedalException("Can't use AdminClient when running interactively."); } + if (!HasCpuGovernor()) + { + return; + } std::stringstream cmd; cmd << "GovernorSettings "; json_writer writer(cmd, true); @@ -161,6 +166,10 @@ void AdminClient::MonitorGovernor(const std::string &governor) { return; } + if (!HasCpuGovernor()) + { + return; + } std::stringstream cmd; cmd << "MonitorGovernor "; json_writer writer(cmd, true); @@ -178,6 +187,10 @@ void AdminClient::UnmonitorGovernor() { return; } + if (!HasCpuGovernor()) + { + return; + } std::stringstream cmd; cmd << "UnmonitorGovernor"; cmd << '\n'; diff --git a/src/AdminInstallUpdate.cpp b/src/AdminInstallUpdate.cpp index ebd6f1e..8e613ed 100644 --- a/src/AdminInstallUpdate.cpp +++ b/src/AdminInstallUpdate.cpp @@ -76,7 +76,7 @@ static int exec(const std::string &command) if ((pid = fork()) == 0) { execv(argv[0], (char *const *)argv.data()); - write(1,"!\n",2); + auto _ = write(1,"!\n",2); exit(EXIT_FAILURE); } else @@ -84,7 +84,7 @@ static int exec(const std::string &command) if (pid == -1) { - write(1,"*",1); + auto _ = write(1,"*",1); perror("execv"); return EXIT_FAILURE; } @@ -99,8 +99,8 @@ static int exec(const std::string &command) void updateLog(const std::string &message) { - write(1,message.c_str(),message.length()); - write(1,"\n",1); + auto _ = write(1,message.c_str(),message.length()); + _ = write(1,"\n",1); } diff --git a/src/AdminMain.cpp b/src/AdminMain.cpp index 04d0ca4..2bf2b09 100644 --- a/src/AdminMain.cpp +++ b/src/AdminMain.cpp @@ -63,6 +63,10 @@ public: void Start(std::string governor) { std::unique_lock lock(mutex); + if (!HasCpuGovernor()) + { + return; + } if (!pThread) { this->governor = governor; @@ -81,6 +85,10 @@ public: } void Stop() { + if (!HasCpuGovernor()) + { + return; + } std::unique_lock lock(mutex); if (pThread) { @@ -109,6 +117,10 @@ private: std::string savedGovernor; void ServiceProc() { + if (!HasCpuGovernor()) + { + return; + } savedGovernor = pipedal::GetCpuGovernor(); pipedal::SetCpuGovernor(this->governor); while (true) @@ -303,7 +315,10 @@ private: { throw PiPedalArgumentException("Invalid arguments."); } - governorMonitorThread.SetGovernor(governor); + if (HasCpuGovernor()) + { + governorMonitorThread.SetGovernor(governor); + } result = 0; } else if (command == "WifiConfigSettings") diff --git a/src/AudioHost.cpp b/src/AudioHost.cpp index fef5e8c..3f5cce8 100644 --- a/src/AudioHost.cpp +++ b/src/AudioHost.cpp @@ -101,8 +101,8 @@ static void GetCpuFrequency(uint64_t *freqMin, uint64_t *freqMax) catch (const std::exception &) { } - if (fMin == 0) - fMax = 0; + if (fMax == 0) + fMin = 0; *freqMin = fMin; *freqMax = fMax; } @@ -2091,7 +2091,13 @@ public: result.cpuUsage_ = audioDriver->CpuUse(); } GetCpuFrequency(&result.cpuFreqMax_, &result.cpuFreqMin_); - result.governor_ = GetGovernor(); + result.hasCpuGovernor_ = HasCpuGovernor(); + if (result.hasCpuGovernor_) + { + result.governor_ = GetGovernor(); + } else { + result.governor_ = ""; + } return result; } @@ -2278,5 +2284,6 @@ JSON_MAP_REFERENCE(JackHostStatus, msSinceLastUnderrun) JSON_MAP_REFERENCE(JackHostStatus, temperaturemC) JSON_MAP_REFERENCE(JackHostStatus, cpuFreqMin) JSON_MAP_REFERENCE(JackHostStatus, cpuFreqMax) +JSON_MAP_REFERENCE(JackHostStatus, hasCpuGovernor) JSON_MAP_REFERENCE(JackHostStatus, governor) JSON_MAP_END() diff --git a/src/AudioHost.hpp b/src/AudioHost.hpp index 8245dfe..cbaf7d2 100644 --- a/src/AudioHost.hpp +++ b/src/AudioHost.hpp @@ -184,6 +184,7 @@ namespace pipedal int32_t temperaturemC_ = -100000; uint64_t cpuFreqMax_ = 0; uint64_t cpuFreqMin_ = 0; + bool hasCpuGovernor_ = true; std::string governor_; DECLARE_JSON_MAP(JackHostStatus); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8f45399..2ccb744 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -737,14 +737,16 @@ set (DEBIAN_COPYRIGHT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../debian/copyright) # generate Copyright section of settings page. # warning: there may be multiple versions. Pick the latest. -if(EXISTS "/usr/share/doc/libboost1.74-dev") +if(EXISTS "/usr/share/doc/libboost1.83-dev") + set (BOOST_COPYRIGHT_DIR "libboost1.83-dev") +elseif(EXISTS "/usr/share/doc/libboost1.74-dev") set (BOOST_COPYRIGHT_DIR "libboost1.74-dev") elseif(EXISTS "/usr/share/doc/libboost1.71-dev") set (BOOST_COPYRIGHT_DIR "libboost1.71-dev") elseif(EXISTS "/usr/share/doc/libboost1.67-dev") set (BOOST_COPYRIGHT_DIR "libboost1.67-dev") else() - message(ERROR "Boost libary version has changed. Please update me.") + message(FATAL_ERROR "Boost libary version has changed. Please update me.") endif() diff --git a/src/CpuGovernor.cpp b/src/CpuGovernor.cpp index d74db5d..66ae0c5 100644 --- a/src/CpuGovernor.cpp +++ b/src/CpuGovernor.cpp @@ -26,26 +26,34 @@ using namespace pipedal; -#ifdef __WIN32__ - -// not a feature on Win32. -void pipedal::SetCpuGovernor(const std::string &governor) { } -std::vector pipedal::GetAvailableGovernors() { return std::vector(); } - -#else static const int SYSFS_RETRIES = 3; +bool pipedal::HasCpuGovernor() +{ +#ifdef __WIN32__ + return false; +#else + std::filesystem::path sysFsPath = SS("/sys/devices/system/cpu/cpu" << 0 << "/cpufreq/scaling_governor"); + return std::filesystem::exists(sysFsPath); + +#endif +} + std::string pipedal::GetCpuGovernor() { std::string result; try { std::ifstream f("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"); + if (!f.is_open()) + { + return ""; + } f >> result; } catch (const std::exception &) { - + return result; } return result; @@ -115,6 +123,10 @@ void pipedal::SetCpuGovernor(const std::string &governor) { break; std::filesystem::path sysFsPath = SS("/sys/devices/system/cpu/cpu" << nCpu << "/cpufreq/scaling_governor"); + if (!std::filesystem::exists(sysFsPath)) + { + return; + } if (!writeAndVerify(sysFsPath,governor)) { @@ -125,17 +137,13 @@ void pipedal::SetCpuGovernor(const std::string &governor) { } } std::vector pipedal::GetAvailableGovernors() { + if (!HasCpuGovernor()) + { + return std::vector(); + } return std::vector { "performance", "ondemand", "powersave" }; } - - -#endif - - - void SetCpuGovernor(const std::string &governor); - - std::vector GetAvailableGovernors(); diff --git a/src/CpuGovernor.hpp b/src/CpuGovernor.hpp index 6e282bf..9ec59fa 100644 --- a/src/CpuGovernor.hpp +++ b/src/CpuGovernor.hpp @@ -23,6 +23,7 @@ #include namespace pipedal { + bool HasCpuGovernor(); std::string GetCpuGovernor(); void SetCpuGovernor(const std::string &governor); diff --git a/src/Updater.cpp b/src/Updater.cpp index 9b64974..ba2d8a8 100644 --- a/src/Updater.cpp +++ b/src/Updater.cpp @@ -50,6 +50,7 @@ namespace fs = std::filesystem; #include "GithubResponseHeaders.hpp" + class pipedal::UpdaterImpl : public Updater { public: @@ -236,7 +237,7 @@ void UpdaterImpl::Stop() if (event_writer != -1) { uint64_t value = CLOSE_EVENT; - write(this->event_writer, &value, sizeof(uint64_t)); + auto _ = write(this->event_writer, &value, sizeof(uint64_t)); } if (thread) { @@ -256,7 +257,7 @@ void UpdaterImpl::Stop() void UpdaterImpl::CheckNow() { uint64_t value = CHECK_NOW_EVENT; - write(this->event_writer, &value, sizeof(uint64_t)); + auto _ = write(this->event_writer, &value, sizeof(uint64_t)); } void UpdaterImpl::SetUpdateListener(UpdateListener &&listener) @@ -912,7 +913,7 @@ void UpdaterImpl::SetUpdatePolicy(UpdatePolicyT updatePolicy) void UpdaterImpl::ForceUpdateCheck() { uint64_t value = UNCACHED_CHECK_NOW_EVENT; - write(this->event_writer, &value, sizeof(uint64_t)); + auto _ = write(this->event_writer, &value, sizeof(uint64_t)); } UpdateStatus::UpdateStatus() diff --git a/src/main.cpp b/src/main.cpp index 42e127e..e211bde 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -97,7 +97,7 @@ void segvHandler(int sig) { // Print out all the frames to stderr const char *message = "Error: SEGV signal received.\n"; - write(STDERR_FILENO,message,strlen(message)); + auto _ = write(STDERR_FILENO,message,strlen(message)); backtrace_symbols_fd(array+2, size-2, STDERR_FILENO); _exit(EXIT_FAILURE); diff --git a/src/makeReleaseMain.cpp b/src/makeReleaseMain.cpp index ad00bbb..6032e60 100644 --- a/src/makeReleaseMain.cpp +++ b/src/makeReleaseMain.cpp @@ -14,6 +14,7 @@ #include "TemporaryFile.hpp" #include "json_variant.hpp" #include "GithubResponseHeaders.hpp" +#include "Finally.hpp" using namespace std; using namespace pipedal; @@ -37,12 +38,15 @@ std::string psystem(const std::string &command) std::string cmdRedirected = command + " 2>&1"; std::array buffer; std::string result; - std::unique_ptr pipe(popen(cmdRedirected.c_str(), "r"), pclose); + FILE *pipe = popen(cmdRedirected.c_str(), "r"); if (!pipe) { throw std::runtime_error("popen() failed!"); } - while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) + Finally ([pipe]() { + pclose(pipe); + }); + while (fgets(buffer.data(), buffer.size(), pipe) != nullptr) { result += buffer.data(); }