STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
VUMeter.c
Go to the documentation of this file.
1 /*
2  * VUMeter.c
3  *
4  * Created on: May 30, 2016
5  * Author: Torsten
6  */
7 
8 #include "VUMeter.h"
9 
10 /* the VU meter variables */
11 static t_VUparams l_params;
12 static int16_t last_input[NUM_CHANNELS];
13 
19 void VUMETER_Analyse(void)
20 {
21  int16_t *sampleBuf, sample;
22  int bufLen;
23 
24  bufLen = AUDIO_PLAYER_GetBuffer((uint8_t **)&sampleBuf);
26  {
27  //second buffer was played - now the first is active
28  sampleBuf += bufLen / (2 + sizeof(int16_t));
29  }
30  else
31  {
32  //first buffer was played - now the second is active
34  }
35 
36  bufLen /= (2 + sizeof(int16_t)); //in words, for half-buffer
37  while (bufLen > 0)
38  {
39  sample = *sampleBuf++;
40  if ( ! (sample & 0x8000))
41  {
42  if (sample > l_params.vuInput[0])
43  l_params.vuInput[0] = sample;
44  }
45  sample = *sampleBuf++;
46  if ( ! (sample & 0x8000))
47  {
48  if (sample > l_params.vuInput[1])
49  l_params.vuInput[1] = sample;
50  }
51  bufLen -= 2;
52  }
53 }
54 
60 void VUMETER_Input(int channel)
61 {
62  if (l_params.vuInput[channel] > last_input[channel]) // update if higher input level
63  last_input[channel] = l_params.vuInput[channel];
64  if (l_params.vuInput[channel] > l_params.vuPeak[channel]) // set peak hold
65  l_params.vuPeak[channel] = l_params.vuInput[channel];
66 }
67 
68 static void VUMETER_Move(int channel)
69 {
70  uint32_t curTick = HAL_GetTick();
71  uint32_t curTickDelta;
72 
73  if (curTick > l_params.vuTick[channel] )
74  curTickDelta = curTick - l_params.vuTick[channel];
75  else
76  curTickDelta = l_params.vuTick[channel] - curTick;
77 
78  if (curTickDelta > LEVELMOVE)
79  {
80  l_params.vuInput[channel] -= l_params.vuInput[channel] >> 4;
81  l_params.vuTick[channel] = curTick;
82  }
83 
84  if (curTick > l_params.vuTickPeak[channel])
85  curTickDelta = curTick - l_params.vuTickPeak[channel];
86  else
87  curTickDelta = l_params.vuTickPeak[channel] - curTick;
88  if (curTickDelta > PEAKHOLD) // reset peak hold after 2000ms
89  {
90  l_params.vuPeak[channel] = l_params.vuInput[channel];
91  l_params.vuTickPeak[channel] = curTick;
92  }
93 }
94 
100 void VUMETER_Display(int channel)
101 {
102  // Scale to make it fit to number of segments
103  uint8_t Level = (l_params.vuInput[channel] / (MAX_VALUE / SEGMENTS));
104  uint8_t Peak = (l_params.vuPeak [channel] / (MAX_VALUE / SEGMENTS));
105  int i;
106  int colSet = 0;
107 
108  for (i = 0; i < (SEGMENTS); i++)
109  {
110  if (Level > i)
111  {
112  if (i == (SEGMENTS - 3))
114  else
115  if (i == (SEGMENTS - 6))
117  else
118  {
119  if ( ! (colSet & 1))
120  {
122  colSet |= 1;
123  }
124  }
125  }
126  else
127  {
128  if ( ! (colSet & 2))
129  {
131  colSet |= 2;
132  }
133  }
134 
135  BSP_LCD_FillRect(X_START + i * (X_WIDTH + XY_GAP), Y_START + channel * (Y_WIDTH + XY_GAP), X_WIDTH, Y_WIDTH); // draw rectangles from left to right
136  }
137 
138  //draw the peak marker
140  if (Peak >= SEGMENTS)
141  Peak--;
142  BSP_LCD_FillRect(X_START + Peak * (X_WIDTH + XY_GAP), Y_START + channel * (Y_WIDTH + XY_GAP), X_WIDTH, Y_WIDTH); // draw peak value
143 
144  //move the peak markers
145  VUMETER_Move(channel);
146 }
#define LEVELMOVE
Definition: VUMeter.h:23
#define LCD_COLOR_GREEN
Green value in ARGB8888 format.
#define LCD_COLOR_YELLOW
Yellow value in ARGB8888 format.
void BSP_LCD_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
Draws a full rectangle in currently active layer.
#define NUM_CHANNELS
Definition: VUMeter.h:13
#define SEGMENTS
Definition: VUMeter.h:15
uint32_t vuTickPeak[NUM_CHANNELS]
Definition: VUMeter.h:31
#define X_START
Definition: VUMeter.h:16
#define LCD_COLOR_MAGENTA
Magenta value in ARGB8888 format.
#define X_WIDTH
Definition: VUMeter.h:18
void VUMETER_Input(int channel)
Analyze the peak meter for the audio input.
Definition: VUMeter.c:60
#define LCD_COLOR_GRAY
Gray value in ARGB8888 format.
int16_t vuInput[NUM_CHANNELS]
Definition: VUMeter.h:28
void BSP_LCD_SetTextColor(uint32_t Color)
Sets the LCD text color.
void VUMETER_Display(int channel)
Display the peak meter.
Definition: VUMeter.c:100
#define PEAKHOLD
Definition: VUMeter.h:22
#define MAX_VALUE
Definition: VUMeter.h:14
#define Y_START
Definition: VUMeter.h:17
int AUDIO_PLAYER_GetState(void)
Definition: AudioPlayer.c:109
void VUMETER_Analyse(void)
Analyse the peak meter value.
Definition: VUMeter.c:19
int16_t vuPeak[NUM_CHANNELS]
Definition: VUMeter.h:29
int AUDIO_PLAYER_GetBuffer(uint8_t **out_BufAddr)
Definition: AudioPlayer.c:117
uint32_t vuTick[NUM_CHANNELS]
Definition: VUMeter.h:30
uint32_t HAL_GetTick(void)
Provides a tick value in millisecond.
#define Y_WIDTH
Definition: VUMeter.h:19
#define LCD_COLOR_RED
Red value in ARGB8888 format.
#define XY_GAP
Definition: VUMeter.h:20