1212#include <zephyr/logging/log.h>
1313LOG_MODULE_REGISTER (contin_array , CONFIG_CONTIN_ARRAY_LOG_LEVEL );
1414
15+ static void copy_samples (uint8_t * pcm_contin , uint32_t pcm_contin_size ,
16+ uint8_t const * const pcm_finite , uint32_t pcm_finite_size ,
17+ uint16_t * const _finite_pos , uint16_t step , uint8_t carrier_bytes )
18+ {
19+ for (size_t j = 0 ; j < pcm_contin_size ; j += carrier_bytes ) {
20+ for (size_t k = 0 ; k < carrier_bytes ; k ++ ) {
21+ * pcm_contin ++ = pcm_finite [(* _finite_pos )++ ];
22+
23+ if (* _finite_pos >= pcm_finite_size ) {
24+ * _finite_pos = 0 ;
25+ }
26+ }
27+
28+ pcm_contin += step ;
29+ }
30+ }
31+
1532int contin_array_create (void * const pcm_cont , uint32_t pcm_cont_size , void const * const pcm_finite ,
16- uint32_t pcm_finite_size , uint32_t * const finite_pos )
33+ uint32_t pcm_finite_size , uint32_t * const _finite_pos )
1734{
1835 LOG_DBG ("pcm_cont_size: %d pcm_finite_size %d" , pcm_cont_size , pcm_finite_size );
1936
@@ -22,17 +39,147 @@ int contin_array_create(void *const pcm_cont, uint32_t pcm_cont_size, void const
2239 }
2340
2441 if (!pcm_cont_size || !pcm_finite_size ) {
25- LOG_ERR ("size cannot be zero" );
42+ LOG_ERR ("Size cannot be zero" );
2643 return - EPERM ;
2744 }
2845
2946 for (uint32_t i = 0 ; i < pcm_cont_size ; i ++ ) {
30- if (* finite_pos > (pcm_finite_size - 1 )) {
31- * finite_pos = 0 ;
47+ if (* _finite_pos > (pcm_finite_size - 1 )) {
48+ * _finite_pos = 0 ;
3249 }
33- ((char * )pcm_cont )[i ] = ((char * )pcm_finite )[* finite_pos ];
34- (* finite_pos )++ ;
50+ ((char * )pcm_cont )[i ] = ((char * )pcm_finite )[* _finite_pos ];
51+ (* _finite_pos )++ ;
3552 }
3653
3754 return 0 ;
3855}
56+
57+ int contin_array_buf_create (struct net_buf * pcm_contin , void const * const pcm_finite ,
58+ uint16_t pcm_finite_size , uint32_t locations , uint16_t * _finite_pos )
59+ {
60+ struct audio_metadata * meta_contin ;
61+ uint8_t num_ch ;
62+ uint8_t count_ch ;
63+ uint8_t * output ;
64+ uint8_t carrier_bytes ;
65+ uint16_t step ;
66+ uint16_t frame_bytes ;
67+ uint16_t finite_start_pos ;
68+ uint32_t out_locs ;
69+
70+ if (pcm_contin == NULL || pcm_finite == NULL || _finite_pos == NULL ) {
71+ LOG_ERR ("Invalid parameter" );
72+ return - ENXIO ;
73+ }
74+
75+ if ((pcm_contin -> size == 0 ) || (pcm_finite_size == 0 ) ||
76+ (* _finite_pos >= pcm_finite_size )) {
77+ LOG_ERR ("Size or finite position out of range" );
78+ return - EPERM ;
79+ }
80+
81+ meta_contin = net_buf_user_data (pcm_contin );
82+ if (meta_contin == NULL ) {
83+ LOG_ERR ("No metadata" );
84+ return - ENXIO ;
85+ }
86+
87+ /* Here the number of common output locations is determined */
88+ if (meta_contin -> locations == 0 && locations == 0 ) {
89+ /* Both are mono buffers and hence have a single output location in common */
90+ out_locs = 0x01 ;
91+ } else {
92+ out_locs = meta_contin -> locations & locations ;
93+ }
94+
95+ if (out_locs == 0 ) {
96+ LOG_ERR ("Locations error" );
97+ return - EPERM ;
98+ }
99+
100+ if ((meta_contin -> carried_bits_per_sample == 0 ) ||
101+ (meta_contin -> carried_bits_per_sample > PCM_CONT_MAX_CARRIER_BIT_DEPTH ) ||
102+ (meta_contin -> carried_bits_per_sample % 8 )) {
103+ LOG_ERR ("Carrier bits invalid: %d" , meta_contin -> carried_bits_per_sample );
104+ return - EINVAL ;
105+ }
106+
107+ carrier_bytes = meta_contin -> carried_bits_per_sample / 8 ;
108+
109+ num_ch = audio_metadata_num_ch_get (meta_contin );
110+
111+ if (pcm_contin -> len == 0 ) {
112+ memset (pcm_contin -> data , 0 , meta_contin -> bytes_per_location * num_ch );
113+ net_buf_add (pcm_contin , meta_contin -> bytes_per_location * num_ch );
114+ }
115+
116+ finite_start_pos = * _finite_pos ;
117+
118+ if (meta_contin -> interleaved ) {
119+ step = carrier_bytes * (num_ch - 1 );
120+ frame_bytes = carrier_bytes ;
121+ } else {
122+ step = 0 ;
123+ frame_bytes = meta_contin -> bytes_per_location ;
124+ }
125+
126+ count_ch = 0 ;
127+
128+ /* While there are common output locations */
129+ while (out_locs ) {
130+ if (out_locs & 0x01 ) {
131+ output = & ((uint8_t * )pcm_contin -> data )[frame_bytes * count_ch ];
132+
133+ * _finite_pos = finite_start_pos ;
134+
135+ copy_samples (output , meta_contin -> bytes_per_location , (uint8_t * )pcm_finite ,
136+ pcm_finite_size , _finite_pos , step , carrier_bytes );
137+
138+ count_ch ++ ;
139+ }
140+
141+ out_locs >>= 1 ;
142+ }
143+
144+ return 0 ;
145+ }
146+
147+ int contin_array_net_buf_create (struct net_buf * pcm_contin , struct net_buf const * const pcm_finite ,
148+ uint32_t locations , uint16_t * const _finite_pos )
149+ {
150+ struct audio_metadata * meta_contin ;
151+ struct audio_metadata * meta_finite ;
152+
153+ if (pcm_contin == NULL || pcm_finite == NULL ) {
154+ LOG_ERR ("Error in input parameter" );
155+ return - ENXIO ;
156+ }
157+
158+ if (pcm_finite -> len == 0 ) {
159+ LOG_ERR ("Finite buffer size error" );
160+ return - EPERM ;
161+ }
162+
163+ meta_contin = net_buf_user_data (pcm_contin );
164+ if (meta_contin == NULL ) {
165+ LOG_ERR ("No metadata" );
166+ return - ENXIO ;
167+ }
168+
169+ meta_finite = net_buf_user_data (pcm_finite );
170+ if (meta_finite == NULL ) {
171+ LOG_ERR ("No metadata" );
172+ return - ENXIO ;
173+ }
174+
175+ if ((meta_contin -> sample_rate_hz != meta_finite -> sample_rate_hz ) ||
176+ (meta_contin -> bits_per_sample != meta_finite -> bits_per_sample ) ||
177+ (meta_contin -> carried_bits_per_sample != meta_finite -> carried_bits_per_sample ) ||
178+ audio_metadata_num_ch_get (meta_finite ) > 1 ) {
179+ LOG_ERR ("Sample/Carrier/Finite locations mismatch" );
180+ return - EINVAL ;
181+ }
182+
183+ return contin_array_buf_create (pcm_contin , (void const * const )pcm_finite -> data ,
184+ meta_finite -> bytes_per_location , locations , _finite_pos );
185+ }
0 commit comments