From 6add75c64e32c9b410a9b4b3c55d6676d19bc743 Mon Sep 17 00:00:00 2001 From: Nathan GOUARDERES Date: Fri, 30 Jul 2021 10:59:34 +0200 Subject: [PATCH] cava with pipe, and template --- RpiLedBars/cava_config | 2 +- RpiLedBars/cava_config_namedpipe | 25 ++++ RpiLedBars/src/drivers/gpio/rpi_gpio.c | 17 ++- .../src/drivers/selector/rpi_selector.c | 40 +++++- .../src/drivers/selector/rpi_selector.h | 36 +++++- RpiLedBars/src/main.c | 20 +-- RpiLedBars/src/rpi_midi_controller.c | 6 +- RpiLedBars/src/rpi_midi_controller.h | 6 +- RpiLedBars/src/tasks/artnet/rpi_artnet.c | 120 +++++++++++++----- RpiLedBars/src/tasks/artnet/rpi_artnet.h | 46 ++++++- RpiLedBars/src/tasks/cava/rpi_cava.c | 120 +++++++++++++++--- RpiLedBars/src/tasks/cava/rpi_cava.h | 25 ++++ 12 files changed, 378 insertions(+), 85 deletions(-) create mode 100644 RpiLedBars/cava_config_namedpipe diff --git a/RpiLedBars/cava_config b/RpiLedBars/cava_config index b3c7247..be06609 100644 --- a/RpiLedBars/cava_config +++ b/RpiLedBars/cava_config @@ -12,7 +12,7 @@ source = plughw:1 method = raw channels = mono mono_option = left -raw_target = /tmp/cava_output +;raw_target = /dev/stdout data_format = ascii ascii_max_range=65535 bit_format = 16bit diff --git a/RpiLedBars/cava_config_namedpipe b/RpiLedBars/cava_config_namedpipe new file mode 100644 index 0000000..b3c7247 --- /dev/null +++ b/RpiLedBars/cava_config_namedpipe @@ -0,0 +1,25 @@ +[general] +framerate = 60 +autosens = 0 +sensitivity = 200 +bars = 128 + +[input] +method = alsa +source = plughw:1 + +[output] +method = raw +channels = mono +mono_option = left +raw_target = /tmp/cava_output +data_format = ascii +ascii_max_range=65535 +bit_format = 16bit + +[smoothing] +integral = 0 +monstercat = 1 +waves = 0 +gravity = 0 + diff --git a/RpiLedBars/src/drivers/gpio/rpi_gpio.c b/RpiLedBars/src/drivers/gpio/rpi_gpio.c index 3e3d24c..57cfa71 100644 --- a/RpiLedBars/src/drivers/gpio/rpi_gpio.c +++ b/RpiLedBars/src/drivers/gpio/rpi_gpio.c @@ -1,5 +1,6 @@ #include "rpi_gpio.h" +#include #include #include #include @@ -17,6 +18,8 @@ #define GPIO_MODE_STRS "IN", "OUT", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3" +bool isInitialized = false; + // Virtual memory pointers to acceess GPIO, DMA and PWM from user space MEM_MAP gpio_regs; @@ -24,9 +27,19 @@ char *gpio_mode_strs[] = {GPIO_MODE_STRS}; // definitions -void gpio_setup() { map_periph(&gpio_regs, (void *)GPIO_BASE, PAGE_SIZE); } +void gpio_setup() { + if (!isInitialized) { + map_periph(&gpio_regs, (void *)GPIO_BASE, PAGE_SIZE); + isInitialized = true; + } +} -void gpio_close() { unmap_periph_mem(&gpio_regs); } +void gpio_close() { + if (isInitialized) { + unmap_periph_mem(&gpio_regs); + isInitialized = true; + } +} // Set input or output with pullups void gpio_set(int pin, int mode, int pull) { diff --git a/RpiLedBars/src/drivers/selector/rpi_selector.c b/RpiLedBars/src/drivers/selector/rpi_selector.c index e526379..d2ff7a4 100644 --- a/RpiLedBars/src/drivers/selector/rpi_selector.c +++ b/RpiLedBars/src/drivers/selector/rpi_selector.c @@ -1,11 +1,37 @@ +/** \file rpi_selector.c + * \brief This module is used to manage selector on gpio + */ + +/*************************************************************************************************** + * Includes + **************************************************************************************************/ #include #include #include +/*************************************************************************************************** + * Preprocessor Constants and Macros + **************************************************************************************************/ + +/*************************************************************************************************** + * Type and Contant Definitions + **************************************************************************************************/ unsigned const selectorPinNumber = 4; +/* TODO use GPIO function from ../gpio/gipo.h (same pin number) */ int selectorPins[4] = {5, 6, 26, 27}; -void setup_selector() { +/*************************************************************************************************** + * Persistent Variables + **************************************************************************************************/ + +/*************************************************************************************************** + * Internal Function Prototypes + **************************************************************************************************/ + +/*************************************************************************************************** + * External Function Definitions + **************************************************************************************************/ +void selector_setup() { wiringPiSetupGpio(); for (size_t i = 0; i < selectorPinNumber; ++i) { @@ -14,7 +40,7 @@ void setup_selector() { } } -int get_selector_position() { +int selector_get_position() { for (size_t i = 0; i < selectorPinNumber; ++i) { if (digitalRead(selectorPins[i])) { return i; @@ -23,10 +49,14 @@ int get_selector_position() { return -1; } -void print_selector() { +void selector_print() { char modeStr[] = "0 | 0 | 0 | 0 \n"; for (size_t i = 0; i < selectorPinNumber; ++i) { modeStr[i * 4] = digitalRead(selectorPins[i]) ? '1' : '0'; } - printf(modeStr); -} \ No newline at end of file + fprintf(stderr, modeStr); +} + +/*************************************************************************************************** + * Internal Function Definitions + **************************************************************************************************/ \ No newline at end of file diff --git a/RpiLedBars/src/drivers/selector/rpi_selector.h b/RpiLedBars/src/drivers/selector/rpi_selector.h index e084f1a..a2718ec 100644 --- a/RpiLedBars/src/drivers/selector/rpi_selector.h +++ b/RpiLedBars/src/drivers/selector/rpi_selector.h @@ -1,10 +1,40 @@ +/** \file rpi_selector.h + * \brief This module is used to manage selector on gpio + */ +/*************************************************************************************************** + * Includes + **************************************************************************************************/ #if !defined(__RPI_SELECTOR_H__) #define __RPI_SELECTOR_H__ -void setup_selector(); +/*************************************************************************************************** + * Preprocessor Constants and Macros + **************************************************************************************************/ -int get_selector_position(); +/*************************************************************************************************** + * Type and Contant Definitions + **************************************************************************************************/ -void print_selector(); +/*************************************************************************************************** + * Global Variables + **************************************************************************************************/ + +/*************************************************************************************************** + * External Function Prototypes + **************************************************************************************************/ +/** + * \brief setup the selector module + **/ +void selector_setup(); + +/** + * \brief get the selector position + **/ +int selector_get_position(); + +/** + * \brief debug: print the selector position + **/ +void selector_print(); #endif /* __RPI_SELECTOR_H__ */ \ No newline at end of file diff --git a/RpiLedBars/src/main.c b/RpiLedBars/src/main.c index 978686c..d49b82c 100644 --- a/RpiLedBars/src/main.c +++ b/RpiLedBars/src/main.c @@ -49,18 +49,10 @@ int main(int argc, char const *argv[]) { fprintf(stderr, "WARNING: Failed to set stepper thread to real-time priority\n"); } - setup_selector(); - - // // setup led - // map_devices(); - // init_smi(LED_NCHANS, SMI_TIMING); - // map_uncached_mem(&vc_mem, VC_MEM_SIZE); - - // setup_smi_dma(&vc_mem, TX_BUFF_LEN(chanLedCount), &txdata); - + midi_controller_setup(); + selector_setup(); leddriver_setup(); - setup_midi_controller(); artnet_init(); setup_cava(); @@ -68,8 +60,8 @@ int main(int argc, char const *argv[]) { while (1) { struct timespec loopStart; clock_gettime(CLOCK_MONOTONIC, &loopStart); - int mode = get_selector_position(); - execute_midi_controller(); + int mode = selector_get_position(); + midi_controller_execute(); if (mode != -1) { if (mode != previousMode) { @@ -79,7 +71,7 @@ int main(int argc, char const *argv[]) { /* stop previous bg task */ switch (previousMode) { case 1: - stop_artnet_bg_worker(); + artnet_stop(); break; case 2: stop_cava_bg_worker(); @@ -91,7 +83,7 @@ int main(int argc, char const *argv[]) { /* start new bg task */ switch (mode) { case 1: - start_artnet_bg_worker(); + artnet_start(); break; case 2: start_cava_bg_worker(); diff --git a/RpiLedBars/src/rpi_midi_controller.c b/RpiLedBars/src/rpi_midi_controller.c index 929efcf..e112b59 100644 --- a/RpiLedBars/src/rpi_midi_controller.c +++ b/RpiLedBars/src/rpi_midi_controller.c @@ -14,7 +14,7 @@ void handle_system_port_events(snd_seq_event_t *ev); void handle_in_port_events(snd_seq_event_t *ev); -void setup_midi_controller() { +void midi_controller_setup() { if (snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_INPUT, SND_SEQ_NONBLOCK) != 0) { SNDERR("snd_seq_open"); } @@ -45,7 +45,7 @@ void setup_midi_controller() { subscribe_midi_controller(controller); } -void execute_midi_controller() { +void midi_controller_execute() { snd_seq_event_t *ev = NULL; int ret; while ((ret = snd_seq_event_input(seq_handle, &ev)) > 0) { @@ -63,7 +63,7 @@ void execute_midi_controller() { } } -void close_midi_controller() {} +void midi_controller_close() {} void subscribe_system_port() { snd_seq_addr_t sender = {.client = 0, .port = SND_SEQ_PORT_SYSTEM_ANNOUNCE}; diff --git a/RpiLedBars/src/rpi_midi_controller.h b/RpiLedBars/src/rpi_midi_controller.h index 73b6066..60db392 100644 --- a/RpiLedBars/src/rpi_midi_controller.h +++ b/RpiLedBars/src/rpi_midi_controller.h @@ -1,10 +1,10 @@ #if !defined(__RPI_MIDI_CONTROLLER_H__) #define __RPI_MIDI_CONTROLLER_H__ -void setup_midi_controller(); +void midi_controller_setup(); -void execute_midi_controller(); +void midi_controller_execute(); -void close_midi_controller(); +void midi_controller_close(); #endif /* __RPI_MIDI_CONTROLLER_H__ */ \ No newline at end of file diff --git a/RpiLedBars/src/tasks/artnet/rpi_artnet.c b/RpiLedBars/src/tasks/artnet/rpi_artnet.c index 49de7ad..531eac8 100644 --- a/RpiLedBars/src/tasks/artnet/rpi_artnet.c +++ b/RpiLedBars/src/tasks/artnet/rpi_artnet.c @@ -1,3 +1,12 @@ +/** \file rpi_artnet.c + * \brief This module contains continuous tasks for artnet node communications. + * + * This is the implementation file. + */ + +/*************************************************************************************************** + * Includes + **************************************************************************************************/ #include "rpi_artnet.h" #include @@ -13,19 +22,57 @@ #include "rpi_artnet_utils.h" -int udpSocket = -1; -char buffer[1024]; +/*************************************************************************************************** + * Preprocessor Constants and Macros + **************************************************************************************************/ + +/*************************************************************************************************** + * Type and Contant Definitions + **************************************************************************************************/ + +/*************************************************************************************************** + * Persistent Variables + **************************************************************************************************/ +/** + * Boolean for interrupting the main thread loop + */ bool isUdpListenerRunning = false; +/** + * Task thread identifier + */ pthread_t udpListener; +/** + * Buffer for storing artnet dmx data received + */ uint8_t artDmxBufferArray[16][512]; +/*************************************************************************************************** + * Internal Function Prototypes + **************************************************************************************************/ + +/** + * \brief This function is used to thread main execution function + * + * \param arg not used. + * + * \return NULL. + */ static void *artnet_udp_handler(void *arg); -void artnet_send_poll_reply(struct sockaddr_in srcAddr); +/** + * \brief This function is used to send an artnet poll reply packet + * + * \param[in] fdUdpSocket The UDP socket file descriptor. + * + * \param[in] senderAddr The adress of poll emiter. + */ +static void artnet_send_poll_reply(int fdUdpSocket, struct sockaddr_in senderAddr); -void artnet_init() {} +/*************************************************************************************************** + * External Function Definitions + **************************************************************************************************/ -void start_artnet_bg_worker() { +void artnet_start() { isUdpListenerRunning = true; if (pthread_create(&udpListener, NULL, artnet_udp_handler, NULL) < 0) { @@ -33,7 +80,7 @@ void start_artnet_bg_worker() { } } -void stop_artnet_bg_worker() { +void artnet_stop() { isUdpListenerRunning = false; if (pthread_join(udpListener, NULL) != 0) { @@ -41,7 +88,7 @@ void stop_artnet_bg_worker() { } } -int artnet_get_dmx_data(unsigned int univerve, uint8_t **dmxData) { +int artnet_get_dmx_data(unsigned int univerve, uint8_t *dmxData[]) { if (univerve > 8) { fprintf(stderr, "Universe %d out of bounds %d\n", univerve, 16); *dmxData = NULL; @@ -51,27 +98,32 @@ int artnet_get_dmx_data(unsigned int univerve, uint8_t **dmxData) { return 0; } +/*************************************************************************************************** + * Internal Function Definitions + **************************************************************************************************/ static void *artnet_udp_handler(void *arg) { - struct sockaddr_in serverAddr; - struct pollfd fds[1]; + int fdUdpSocket = -1; + struct pollfd pollFdArray[1]; int timeoutMs; - int ret; int flags; + char buffer[ARTNET_MAX_BUFFER]; + struct sockaddr_in serverAddr, srcAddr; + socklen_t srcLen = sizeof(struct sockaddr_in); /* Create UDP socket */ - udpSocket = socket(PF_INET, SOCK_DGRAM, 0); - if (udpSocket < 0) { + fdUdpSocket = socket(PF_INET, SOCK_DGRAM, 0); + if (fdUdpSocket < 0) { perror("Opening socket failed"); } /* Set non-blocking socket */ - flags = fcntl(udpSocket, F_GETFL, 0); - fcntl(udpSocket, F_SETFL, flags | O_NONBLOCK); + flags = fcntl(fdUdpSocket, F_GETFL, 0); + fcntl(fdUdpSocket, F_SETFL, flags | O_NONBLOCK); /* pollfd structure and timeout */ - memset(fds, 0, sizeof(fds)); - fds[0].fd = udpSocket; - fds[0].events = POLLIN; + memset(pollFdArray, 0, sizeof(pollFdArray)); + pollFdArray[0].fd = fdUdpSocket; + pollFdArray[0].events = POLLIN; timeoutMs = 10; /* Configure settings in address struct */ @@ -81,16 +133,14 @@ static void *artnet_udp_handler(void *arg) { memset(serverAddr.sin_zero, '\0', sizeof(serverAddr.sin_zero)); /* Bind socket with address struct */ - bind(udpSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)); - - struct sockaddr_in srcAddr; - socklen_t srcLen = sizeof(srcAddr); + bind(fdUdpSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)); while (isUdpListenerRunning) { - if ((ret = poll(fds, 1, timeoutMs)) == 1) { + int pollReturn; + if ((pollReturn = poll(pollFdArray, 1, timeoutMs)) == 1) { ssize_t bufferLen = - recvfrom(udpSocket, buffer, ARTNET_MAX_BUFFER, 0, (struct sockaddr *)&srcAddr, &srcLen); + recvfrom(fdUdpSocket, buffer, ARTNET_MAX_BUFFER, 0, (struct sockaddr *)&srcAddr, &srcLen); if (bufferLen <= ARTNET_MAX_BUFFER && bufferLen > sizeof(artnetHeader_t)) { artnetHeader_t *artnetHeader = (artnetHeader_t *)buffer; @@ -110,7 +160,7 @@ static void *artnet_udp_handler(void *arg) { break; case OpPoll: - artnet_send_poll_reply(srcAddr); + artnet_send_poll_reply(fdUdpSocket, srcAddr); break; default: @@ -118,22 +168,26 @@ static void *artnet_udp_handler(void *arg) { } } } - } else if (ret < 0) { - fprintf(stderr, "error polling %d: %s\n", udpSocket, strerror(errno)); + + } else if (pollReturn < 0) { + fprintf(stderr, "error polling %d: %s\n", fdUdpSocket, strerror(errno)); } } - close(udpSocket); + close(fdUdpSocket); return NULL; } -void artnet_send_poll_reply(struct sockaddr_in srcAddr) { +static void artnet_send_poll_reply(int fdUdpSocket, struct sockaddr_in senderAddr) { /* Configure settings in address struct */ - srcAddr.sin_family = AF_INET; - srcAddr.sin_port = htons(ARTNET_PORT); - memset(srcAddr.sin_zero, '\0', sizeof(srcAddr.sin_zero)); + senderAddr.sin_family = AF_INET; + senderAddr.sin_port = htons(ARTNET_PORT); + memset(senderAddr.sin_zero, '\0', sizeof(senderAddr.sin_zero)); - sendto(udpSocket, (uint8_t *)&artPollReply, sizeof(artPollReply_t), 0, - (struct sockaddr *)&srcAddr, sizeof(srcAddr)); + if (sendto(fdUdpSocket, (uint8_t *)&artPollReply, sizeof(artPollReply_t), 0, + (struct sockaddr *)&senderAddr, sizeof(senderAddr)) < 0) { + fprintf(stderr, "Error sending poll reply to %s:%d: %s\n", inet_ntoa(senderAddr.sin_addr), + strerror(errno)); + } } \ No newline at end of file diff --git a/RpiLedBars/src/tasks/artnet/rpi_artnet.h b/RpiLedBars/src/tasks/artnet/rpi_artnet.h index 818e59f..8be76de 100644 --- a/RpiLedBars/src/tasks/artnet/rpi_artnet.h +++ b/RpiLedBars/src/tasks/artnet/rpi_artnet.h @@ -1,14 +1,50 @@ +/** \file rpi_artnet.h + * \brief This module contains continuous tasks for artnet node communications. + * + * This is the header file for the definition of services to allow managing thread acting as artnet + * node. + */ #if !defined(__RPI_ARTNET_H__) #define __RPI_ARTNET_H__ +/*************************************************************************************************** + * Includes + **************************************************************************************************/ #include "rpi_artnet_packets.h" -void artnet_init(); +/*************************************************************************************************** + * Preprocessor Constants and Macros + **************************************************************************************************/ -void start_artnet_bg_worker(); +/*************************************************************************************************** + * Type and Contant Definitions + **************************************************************************************************/ -void stop_artnet_bg_worker(); +/*************************************************************************************************** + * Global Variables + **************************************************************************************************/ -int artnet_get_dmx_data(unsigned int univerve, uint8_t **dmxData); +/*************************************************************************************************** + * External Function Prototypes + **************************************************************************************************/ -#endif // __RPI_ARTNET_H__ +/** + * \brief Start artnet node module + **/ +void artnet_start(); + +/** + * \brief Stop artnet node module + */ +void artnet_stop(); + +/** + * \brief Get last DMX data received for the specified universe + * + * \param[in] univerve The universe to get data from + * + * \param[out] dmxData The pointer to the DMX data array + */ +int artnet_get_dmx_data(unsigned int univerve, uint8_t *dmxData[]); + +#endif /* __RPI_ARTNET_H__ */ diff --git a/RpiLedBars/src/tasks/cava/rpi_cava.c b/RpiLedBars/src/tasks/cava/rpi_cava.c index 4b823bb..141f4d4 100644 --- a/RpiLedBars/src/tasks/cava/rpi_cava.c +++ b/RpiLedBars/src/tasks/cava/rpi_cava.c @@ -1,3 +1,10 @@ +/** \file rpi_cava.h + * \brief This module contains continuous tasks for cava (spectrum analyzer) comunication + */ + +/*************************************************************************************************** + * Includes + **************************************************************************************************/ #include "rpi_cava.h" #include @@ -9,23 +16,59 @@ #include #include #include -#ifdef _WIN32 -#include -#else #include -#endif +/*************************************************************************************************** + * Preprocessor Constants and Macros + **************************************************************************************************/ + +/** + * Constant for Maximum char in a line (128 number of (5 char + 1 delim) + \n ) + */ #define MAXLINECHAR 128 * (5 + 1) + 1 +/*************************************************************************************************** + * Type and Contant Definitions + **************************************************************************************************/ + +/*************************************************************************************************** + * Persistent Variables + **************************************************************************************************/ + +/** + * Cava process id + */ pid_t cavaPid; +/** + * Boolean for interrupting the main thread loop + */ bool isFifoReaderRunning = false; +/** + * Task thread identifier + */ pthread_t fifoReader; -int cavaFifo; + +int fdCavaInput; char lineBuffer[MAXLINECHAR]; uint16_t buffer[128 + 2]; +/*************************************************************************************************** + * Internal Function Prototypes + **************************************************************************************************/ + +/** + * \brief This function is used to thread main execution function + * + * \param arg not used. + * + * \return NULL. + */ static void *fifo_to_buffer(void *arg); +/*************************************************************************************************** + * External Function Definitions + **************************************************************************************************/ + void setup_cava() { if ((cavaPid = fork()) == -1) { perror("fork"); @@ -34,7 +77,6 @@ void setup_cava() { if (cavaPid == 0) { /* Child process*/ - pthread_setschedprio(pthread_self(), 30); char *args[] = {"/usr/local/bin/cava", "-p", "/home/pi/LedBars/RpiLedBars/cava_config", NULL}; if (execv(args[0], args) != 0) { @@ -68,33 +110,36 @@ int get_cava_buffer(uint16_t **buffer_dst) { return 0; } -size_t valueIndex = 0, charOffset = 0; -char strValue[6] = "0\0"; -bool hasToBeDiscarded = false; +/*************************************************************************************************** + * Internal Function Definitions + **************************************************************************************************/ static void *fifo_to_buffer(void *arg) { struct pollfd fds[1]; int timeoutMs; int ret; + size_t valueIndex = 0, charOffset = 0; + char strValue[6] = "0\0"; + bool hasToBeDiscarded = true; - if ((cavaFifo = open("/tmp/cava_output", O_RDONLY | O_NONBLOCK)) < 0) { + if start_cava_process () + ; + if ((fdCavaInput = open("/tmp/cava_output", O_RDONLY | O_NONBLOCK)) < 0) { perror("open"); close_cava(); exit(1); } memset(fds, 0, sizeof(fds)); - fds[0].fd = cavaFifo; + fds[0].fd = fdCavaInput; fds[0].events = POLLIN; timeoutMs = 10; - hasToBeDiscarded = true; - while (isFifoReaderRunning) { if ((ret = poll(fds, 1, timeoutMs)) == 1) { int nread; - nread = read(cavaFifo, lineBuffer, 128 + 1); + nread = read(fdCavaInput, lineBuffer, 128 + 1); if (nread >= 0) { for (size_t i = 0; i < nread; ++i) { @@ -136,11 +181,54 @@ static void *fifo_to_buffer(void *arg) { } } } else if (ret < 0) { - fprintf(stderr, "error polling %d: %s\n", cavaFifo, strerror(errno)); + fprintf(stderr, "error polling %d: %s\n", fdCavaInput, strerror(errno)); } } - close(cavaFifo); + close(fdCavaInput); return NULL; } + +static int start_cava_process() { + int fdCavaPipe[2]; + + if (pipe(fdCavaPipe) < 0) { + fprintf(stderr, "Cava pipe failure: %s\n", strerror(errno)); + return -EXIT_FAILURE; + } + + if ((cavaPid = fork()) < 0) { + fprintf(stderr, "Cava fork failure: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + + if (cavaPid == 0) { + /* Child process*/ + char *args[] = {"cava", "-p", "/home/pi/LedBars/RpiLedBars/cava_config", NULL}; + + /* Close reading end of the pipe */ + close(fdCavaPipe[0]); + /* Dup writing end of the pipe in place of stdout */ + dup2(fdCavaPipe[1], STDOUT_FILENO); + /* Close writing end of the pipe */ + close(fdCavaPipe[1]); + + execvp(args[0], args); + fprintf(stderr, "Cava execvp failure or return: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } else { + /* Close writing end of the pipe */ + close(fdCavaPipe[1]); + /* Set reading end of the pipe non-blocking */ + flags = fcntl(fdCavaPipe[0], F_GETFL, 0); + fcntl(fdCavaPipe[0], F_SETFL, flags | O_NONBLOCK); + /* Return reading end of the pipe */ + return fdCavaPipe[0]; + } + + /* Unreachable */ + return -1; +} + +static void stop_cava_process() { kill(cavaPid, SIGTERM); } diff --git a/RpiLedBars/src/tasks/cava/rpi_cava.h b/RpiLedBars/src/tasks/cava/rpi_cava.h index 0aaf0cd..4eacffb 100644 --- a/RpiLedBars/src/tasks/cava/rpi_cava.h +++ b/RpiLedBars/src/tasks/cava/rpi_cava.h @@ -1,8 +1,33 @@ +/** \file rpi_cava.h + * \brief This module contains continuous tasks for cava (spectrum analyzer) comunication + */ #if !defined(__RPI_CAVA_H__) #define __RPI_CAVA_H__ +/*************************************************************************************************** + * Includes + **************************************************************************************************/ #include +/*************************************************************************************************** + * Preprocessor Constants and Macros + **************************************************************************************************/ + +/*************************************************************************************************** + * Type and Contant Definitions + **************************************************************************************************/ + +/*************************************************************************************************** + * Global Variables + **************************************************************************************************/ + +/*************************************************************************************************** + * External Function Prototypes + **************************************************************************************************/ + +/** + * \brief Start artnet node module + **/ void setup_cava(); int get_cava_buffer(uint16_t **buffer_dst);