psoc062s2/src/pv_audio_rec.c
Go to the documentation of this file.
1 /*
2  Copyright 2021 Picovoice Inc.
3 
4  You may not use this file except in compliance with the license. A copy of the license is located in the "LICENSE"
5  file accompanying this source.
6 
7  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8  an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9  specific language governing permissions and limitations under the License.
10 */
11 
12 #include <float.h>
13 #include <limits.h>
14 #include <math.h>
15 #include <stdbool.h>
16 #include <stdint.h>
17 #include <stdlib.h>
18 #include <stdio.h>
19 
20 #include "cybsp.h"
21 #include "cyhal.h"
22 
23 #include "picovoice.h"
24 
25 #define PV_AUDIO_REC_AUDIO_FREQUENCY (16000U)
26 #define PV_AUDIO_REC_CHANNEL_NUMBER (1)
27 #define PV_AUDIO_REC_RECORD_BUFFER_SIZE (512)
28 #define DECIMATION_RATE (96u)
29 #define AUDIO_SYS_CLOCK_HZ (24576000u)
30 #define PDM_DATA (P10_5)
31 #define PDM_CLK (P10_4)
32 
33 void pdm_pcm_isr_handler(void *arg, cyhal_pdm_pcm_event_t event);
34 
35 cyhal_pdm_pcm_t pdm_pcm;
36 cyhal_clock_t audio_clock;
37 cyhal_clock_t pll_clock;
38 
39 const cyhal_pdm_pcm_cfg_t pdm_pcm_cfg =
40 {
41  .sample_rate = PV_AUDIO_REC_AUDIO_FREQUENCY,
42  .decimation_rate = DECIMATION_RATE,
43  .mode = CYHAL_PDM_PCM_MODE_LEFT,
44  .word_length = 16, /* bits */
45  .left_gain = 21, /* dB */
46  .right_gain = 21, /* dB */
47 };
48 
50 static int32_t last_read_index = -1;
51 static int32_t read_index = -1;
52 static int32_t write_index = 1;
53 
54 struct {
55  uint32_t channel_number;
56  uint32_t audio_frequency;
59 } pv_audio_rec;
60 
61 cy_rslt_t pdm_pcm_clock_init(void) {
62  cy_rslt_t result;
63  result = cyhal_clock_get(&pll_clock, &CYHAL_CLOCK_PLL[1]);
64 
65  if (result == CY_RSLT_SUCCESS) {
66  result = cyhal_clock_init(&pll_clock);
67  }
68 
69  if (result == CY_RSLT_SUCCESS) {
70  result = cyhal_clock_set_frequency(&pll_clock, AUDIO_SYS_CLOCK_HZ, NULL);
71  }
72 
73  if (result == CY_RSLT_SUCCESS) {
74  result = cyhal_clock_set_enabled(&pll_clock, true, true);
75  }
76 
77  if (result == CY_RSLT_SUCCESS) {
78  result = cyhal_clock_get(&audio_clock, &CYHAL_CLOCK_HF[1]);
79  }
80 
81  if (result == CY_RSLT_SUCCESS) {
82  result = cyhal_clock_init(&audio_clock);
83  }
84 
85  if (result == CY_RSLT_SUCCESS) {
86  result = cyhal_clock_set_source(&audio_clock, &pll_clock);
87  }
88 
89  if (result == CY_RSLT_SUCCESS) {
90  result = cyhal_clock_set_enabled(&audio_clock, true, true);
91  }
92 
93  return result;
94 }
95 
97  cy_rslt_t result;
98  result = pdm_pcm_clock_init();
99  if (result != CY_RSLT_SUCCESS) {
101  }
102 
103  result = cyhal_pdm_pcm_init(&pdm_pcm, PDM_DATA, PDM_CLK, &audio_clock, &pdm_pcm_cfg);
104  if (result != CY_RSLT_SUCCESS) {
106  }
107 
108  cyhal_pdm_pcm_register_callback(&pdm_pcm, pdm_pcm_isr_handler, NULL);
109  cyhal_pdm_pcm_enable_event(&pdm_pcm, CYHAL_PDM_PCM_ASYNC_COMPLETE, CYHAL_ISR_PRIORITY_DEFAULT, true);
110 
111  pv_audio_rec.channel_number = PV_AUDIO_REC_CHANNEL_NUMBER;
112  pv_audio_rec.audio_frequency = PV_AUDIO_REC_AUDIO_FREQUENCY;
113  pv_audio_rec.record_buffer_size = PV_AUDIO_REC_RECORD_BUFFER_SIZE;
114 
115  return PV_STATUS_SUCCESS;
116 }
117 
119  cyhal_pdm_pcm_start(&pdm_pcm);
120 
121  cyhal_pdm_pcm_read_async(&pdm_pcm, &ping_pong_buffer[write_index][0], PV_AUDIO_REC_RECORD_BUFFER_SIZE);
122 
123  pv_audio_rec.is_recording = true;
124  return PV_STATUS_SUCCESS;
125 }
126 
128  cyhal_pdm_pcm_stop(&pdm_pcm);
129  pv_audio_rec.is_recording = false;
130  return PV_STATUS_SUCCESS;
131 }
132 
134  if (read_index == -1) {
135  return -FLT_MAX;
136  }
137 
138  if (pv_audio_rec.is_recording) {
139  int64_t sum = 0;
140  const int16_t *pcm_buffer = (const int16_t *) ping_pong_buffer[read_index];
141  for (uint32_t i = 0; i < PV_AUDIO_REC_RECORD_BUFFER_SIZE; i++) {
142  sum += (int64_t) pcm_buffer[i] * (int64_t) pcm_buffer[i];
143  }
144  return (10 * log10f( ((float) sum + FLT_EPSILON) / ( PV_AUDIO_REC_RECORD_BUFFER_SIZE) / (SHRT_MAX * SHRT_MAX)));
145  } else {
146  return -FLT_MAX;
147  }
148 }
149 
150 const int16_t *pv_audio_rec_get_new_buffer(void) {
151  if (read_index == -1) {
152  return NULL;
153  }
154 
155  if (last_read_index == read_index) {
156  return NULL;
157  }
158 
160 
162 }
163 
164 void pdm_pcm_isr_handler(void *arg, cyhal_pdm_pcm_event_t event) {
165  (void) arg;
166  (void) event;
167 
168  cyhal_pdm_pcm_read_async(&pdm_pcm, &ping_pong_buffer[write_index][0], PV_AUDIO_REC_RECORD_BUFFER_SIZE);
170  write_index = (write_index == 1) ? 0 : 1;
171 }
172 
174  cyhal_clock_free(&audio_clock);
175  cyhal_clock_free(&pll_clock);
176 }
PDM_CLK
#define PDM_CLK
Definition: psoc062s2/src/pv_audio_rec.c:31
AUDIO_SYS_CLOCK_HZ
#define AUDIO_SYS_CLOCK_HZ
Definition: psoc062s2/src/pv_audio_rec.c:29
is_recording
bool is_recording
Definition: psoc062s2/src/pv_audio_rec.c:58
read_index
static int32_t read_index
Definition: psoc062s2/src/pv_audio_rec.c:51
ping_pong_buffer
static int16_t ping_pong_buffer[2][PV_AUDIO_REC_RECORD_BUFFER_SIZE]
Definition: psoc062s2/src/pv_audio_rec.c:49
NULL
#define NULL
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/speex_resampler/thirdparty/resample.c:92
PV_STATUS_INVALID_STATE
@ PV_STATUS_INVALID_STATE
Definition: porcupine/include/picovoice.h:40
pv_audio_rec
struct @371 pv_audio_rec
pll_clock
cyhal_clock_t pll_clock
Definition: psoc062s2/src/pv_audio_rec.c:37
audio_clock
cyhal_clock_t audio_clock
Definition: psoc062s2/src/pv_audio_rec.c:36
pdm_pcm
cyhal_pdm_pcm_t pdm_pcm
Definition: psoc062s2/src/pv_audio_rec.c:35
DECIMATION_RATE
#define DECIMATION_RATE
Definition: psoc062s2/src/pv_audio_rec.c:28
pv_audio_rec_get_new_buffer
const int16_t * pv_audio_rec_get_new_buffer(void)
Definition: psoc062s2/src/pv_audio_rec.c:150
pv_audio_rec_loudness_db
float pv_audio_rec_loudness_db(void)
Definition: psoc062s2/src/pv_audio_rec.c:133
PV_STATUS_SUCCESS
@ PV_STATUS_SUCCESS
Definition: porcupine/include/picovoice.h:34
PDM_DATA
#define PDM_DATA
Definition: psoc062s2/src/pv_audio_rec.c:30
PV_AUDIO_REC_CHANNEL_NUMBER
#define PV_AUDIO_REC_CHANNEL_NUMBER
Definition: psoc062s2/src/pv_audio_rec.c:26
pv_status_t
pv_status_t
Definition: porcupine/include/picovoice.h:33
pv_audio_rec_init
pv_status_t pv_audio_rec_init(void)
Definition: psoc062s2/src/pv_audio_rec.c:96
pv_audio_rec_deinit
void pv_audio_rec_deinit(void)
Definition: psoc062s2/src/pv_audio_rec.c:173
pv_audio_rec_stop
pv_status_t pv_audio_rec_stop(void)
Definition: psoc062s2/src/pv_audio_rec.c:127
audio_frequency
uint32_t audio_frequency
Definition: psoc062s2/src/pv_audio_rec.c:56
pdm_pcm_clock_init
cy_rslt_t pdm_pcm_clock_init(void)
Definition: psoc062s2/src/pv_audio_rec.c:61
pdm_pcm_isr_handler
void pdm_pcm_isr_handler(void *arg, cyhal_pdm_pcm_event_t event)
Definition: psoc062s2/src/pv_audio_rec.c:164
record_buffer_size
uint32_t record_buffer_size
Definition: psoc062s2/src/pv_audio_rec.c:57
PV_AUDIO_REC_AUDIO_FREQUENCY
#define PV_AUDIO_REC_AUDIO_FREQUENCY
Definition: psoc062s2/src/pv_audio_rec.c:25
last_read_index
static int32_t last_read_index
Definition: psoc062s2/src/pv_audio_rec.c:50
pdm_pcm_cfg
const cyhal_pdm_pcm_cfg_t pdm_pcm_cfg
Definition: psoc062s2/src/pv_audio_rec.c:39
PV_AUDIO_REC_RECORD_BUFFER_SIZE
#define PV_AUDIO_REC_RECORD_BUFFER_SIZE
Definition: psoc062s2/src/pv_audio_rec.c:27
write_index
static int32_t write_index
Definition: psoc062s2/src/pv_audio_rec.c:52
pv_audio_rec_start
pv_status_t pv_audio_rec_start(void)
Definition: psoc062s2/src/pv_audio_rec.c:118
channel_number
uint32_t channel_number
Definition: psoc062s2/src/pv_audio_rec.c:55


picovoice_driver
Author(s):
autogenerated on Fri Apr 1 2022 02:14:50