cava with pipe, and template
This commit is contained in:
		@@ -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 <arpa/inet.h>
 | 
			
		||||
@@ -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));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -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 <errno.h>
 | 
			
		||||
@@ -9,23 +16,59 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#include <Windows.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#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); }
 | 
			
		||||
 
 | 
			
		||||
@@ -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 <stdint.h>
 | 
			
		||||
 | 
			
		||||
/***************************************************************************************************
 | 
			
		||||
 * 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);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user