Skip to content

Commit 7d809bd

Browse files
adopting atomics for relevant examples
1 parent 8381196 commit 7d809bd

34 files changed

+436
-339
lines changed

examples/include/_common.h

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,7 @@
3030
extern "C" {
3131
#endif /* __cplusplus */
3232

33-
#if defined(_MSC_VER)
34-
#if _MSC_VER >= 1936 && defined(__STDC_VERSION__) && __STDC_VERSION__ < 201112L
35-
#pragma message("WARNING: The MSVC C compiler only has \"experimental\" Atomic support") /* although, seems to be fine... */
36-
#define STD_ATOMICS_SUPPORTED ( 1 )
37-
#else
38-
#pragma message("WARNING: Atomics require C11 and are not supported by the MSVC C compiler pre _MSC_VER=1936")
39-
#define STD_ATOMICS_SUPPORTED ( 0 )
40-
#endif
41-
#else
42-
#define STD_ATOMICS_SUPPORTED ( 1 )
33+
#ifndef __STDC_NO_ATOMICS__
4334
#include <stdatomic.h>
4435
#endif
4536

@@ -251,22 +242,30 @@ typedef enum {
251242
/** Maximum number of spherical harmonic components/signals supported */
252243
#define MAX_NUM_SH_SIGNALS ( MAX_NUM_CHANNELS )
253244

254-
#if STD_ATOMICS_SUPPORTED
255-
typedef _Atomic(float) _Atomic_FLOAT32;
256-
typedef _Atomic(int) _Atomic_INT32;
257-
258-
typedef _Atomic(CH_ORDER) _Atomic_CH_ORDER;
259-
typedef _Atomic(NORM_TYPES) _Atomic_NORM_TYPES;
260-
typedef _Atomic(CODEC_STATUS) _Atomic_CODEC_STATUS;
261-
typedef _Atomic(PROC_STATUS) _Atomic_PROC_STATUS;
245+
#ifndef __STDC_NO_ATOMICS__
246+
typedef _Atomic(CH_ORDER) _Atomic_CH_ORDER;
247+
typedef _Atomic(NORM_TYPES) _Atomic_NORM_TYPES;
248+
typedef _Atomic(SH_ORDERS) _Atomic_SH_ORDERS;
249+
typedef _Atomic(MIC_PRESETS) _Atomic_MIC_PRESETS;
250+
typedef _Atomic(LOUDSPEAKER_ARRAY_PRESETS) _Atomic_LOUDSPEAKER_ARRAY_PRESETS;
251+
typedef _Atomic(SOURCE_CONFIG_PRESETS) _Atomic_SOURCE_CONFIG_PRESETS;
252+
typedef _Atomic(STATIC_BEAM_TYPES) _Atomic_STATIC_BEAM_TYPES;
253+
typedef _Atomic(HFOV_OPTIONS) _Atomic_HFOV_OPTIONS;
254+
typedef _Atomic(ASPECT_RATIO_OPTIONS) _Atomic_ASPECT_RATIO_OPTIONS;
255+
typedef _Atomic(CODEC_STATUS) _Atomic_CODEC_STATUS;
256+
typedef _Atomic(PROC_STATUS) _Atomic_PROC_STATUS;
262257
#else
263-
typedef float _Atomic_FLOAT32;
264-
typedef int _Atomic_INT32;
265-
266-
typedef CH_ORDER _Atomic_CH_ORDER;
267-
typedef NORM_TYPES _Atomic_NORM_TYPES;
268-
typedef CODEC_STATUS _Atomic_CODEC_STATUS;
269-
typedef PROC_STATUS _Atomic_PROC_STATUS;
258+
typedef CH_ORDER _Atomic_CH_ORDER;
259+
typedef NORM_TYPES _Atomic_NORM_TYPES;
260+
typedef SH_ORDERS _Atomic_SH_ORDERS;
261+
typedef MIC_PRESETS _Atomic_MIC_PRESETS;
262+
typedef LOUDSPEAKER_ARRAY_PRESETS _Atomic_LOUDSPEAKER_ARRAY_PRESETS;
263+
typedef SOURCE_CONFIG_PRESETS _Atomic_SOURCE_CONFIG_PRESETS;
264+
typedef STATIC_BEAM_TYPES _Atomic_STATIC_BEAM_TYPES;
265+
typedef HFOV_OPTIONS _Atomic_HFOV_OPTIONS;
266+
typedef ASPECT_RATIO_OPTIONS _Atomic_ASPECT_RATIO_OPTIONS;
267+
typedef CODEC_STATUS _Atomic_CODEC_STATUS;
268+
typedef PROC_STATUS _Atomic_PROC_STATUS;
270269
#endif
271270

272271

examples/src/ambi_bin/ambi_bin_internal.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,12 @@ extern "C" {
7777
# error "AMBI_BIN_FRAME_SIZE must be an integer multiple of HOP_SIZE"
7878
#endif
7979

80-
#if STD_ATOMICS_SUPPORTED
80+
#ifndef __STDC_NO_ATOMICS__
8181
typedef _Atomic(AMBI_BIN_PREPROC) _Atomic_AMBI_BIN_PREPROC;
82+
typedef _Atomic(AMBI_BIN_DECODING_METHODS) _Atomic_AMBI_BIN_DECODING_METHODS;
8283
#else
8384
typedef AMBI_BIN_PREPROC _Atomic_AMBI_BIN_PREPROC;
85+
typedef AMBI_BIN_DECODING_METHODS _Atomic_AMBI_BIN_DECODING_METHODS;
8486
#endif
8587

8688

@@ -149,7 +151,7 @@ typedef struct _ambi_bin
149151
_Atomic_INT32 enableMaxRE; /**< 0: disabled, 1: enabled */
150152
_Atomic_INT32 enableDiffuseMatching; /**< 0: disabled, 1: enabled */
151153
_Atomic_INT32 enableTruncationEQ; /**< 0: disabled, 1: enabled */
152-
AMBI_BIN_DECODING_METHODS method; /**< current decoding method (see #AMBI_BIN_DECODING_METHODS) */
154+
_Atomic_AMBI_BIN_DECODING_METHODS method; /**< current decoding method (see #AMBI_BIN_DECODING_METHODS) */
153155
_Atomic_INT32 useDefaultHRIRsFLAG; /**< 1: use default HRIRs in database, 0: use those from SOFA file */
154156
_Atomic_AMBI_BIN_PREPROC preProc; /**< HRIR pre-processing strategy */
155157
_Atomic_CH_ORDER chOrdering; /**< Ambisonic channel order convention (see #CH_ORDER) */

examples/src/ambi_dec/ambi_dec.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,8 @@ void ambi_dec_init
177177

178178
/* define frequency vector */
179179
pData->fs = sampleRate;
180-
afSTFT_getCentreFreqs(pData->hSTFT, (float)sampleRate, HYBRID_BANDS, pData->freqVector);
180+
if (pData->codecStatus == CODEC_STATUS_INITIALISED)
181+
afSTFT_getCentreFreqs(pData->hSTFT, (float)pData->fs, HYBRID_BANDS, pData->freqVector);
181182
}
182183

183184
void ambi_dec_initCodec
@@ -190,6 +191,7 @@ void ambi_dec_initCodec
190191
int i, ch, d, j, n, ng, nGrid_dirs, masterOrder, nSH_order, max_nSH, nLoudspeakers;
191192
float* grid_dirs_deg, *Y, *M_dec_tmp, *g, *a, *e, *a_n, *hrtf_vbap_gtable;;
192193
float a_avg[MAX_SH_ORDER], e_avg[MAX_SH_ORDER], azi_incl[2], sum_elev;
194+
float loudpkrs_dirs_deg_local[MAX_NUM_LOUDSPEAKERS][2];
193195
#ifdef SAF_ENABLE_SOFA_READER_MODULE
194196
SAF_SOFA_ERROR_CODES error;
195197
saf_sofa_container sofa;
@@ -226,15 +228,22 @@ void ambi_dec_initCodec
226228
afSTFT_channelChange(pData->hSTFT, max_nSH, nLoudspeakers);
227229
afSTFT_clearBuffers(pData->hSTFT);
228230
}
231+
afSTFT_getCentreFreqs(pData->hSTFT, (float)pData->fs, HYBRID_BANDS, pData->freqVector);
229232
pData->binauraliseLS = pData->new_binauraliseLS;
230233
pData->nLoudpkrs = nLoudspeakers;
231234

235+
/* Grab local copy */
236+
for(ch=0; ch < nLoudspeakers; ch++){
237+
loudpkrs_dirs_deg_local[ch][0] = pData->loudpkrs_dirs_deg[ch][0];
238+
loudpkrs_dirs_deg_local[ch][1] = pData->loudpkrs_dirs_deg[ch][1];
239+
}
240+
232241
/* Quick and dirty check to find loudspeaker dimensionality */
233242
strcpy(pData->progressBarText,"Computing decoder");
234243
pData->progressBar0_1 = 0.2f;
235244
sum_elev = 0.0f;
236245
for(ch=0; ch < nLoudspeakers; ch++)
237-
sum_elev += fabsf(pData->loudpkrs_dirs_deg[ch][1]);
246+
sum_elev += fabsf(loudpkrs_dirs_deg_local[ch][1]);
238247
if( (((sum_elev < 5.0f) && (sum_elev > -5.0f))) || (nLoudspeakers < 4) )
239248
pData->loudpkrs_nDims = 2;
240249
else
@@ -243,10 +252,10 @@ void ambi_dec_initCodec
243252
/* add virtual loudspeakers for 2D case if using AllRAD, so that the triangulation cannot fail. */
244253
if (pData->loudpkrs_nDims == 2 && (pData->dec_method[0]==DECODING_METHOD_ALLRAD || pData->dec_method[1]==DECODING_METHOD_ALLRAD)){
245254
assert(nLoudspeakers<=MAX_NUM_LOUDSPEAKERS-2);
246-
pData->loudpkrs_dirs_deg[nLoudspeakers][0] = 0.0f;
247-
pData->loudpkrs_dirs_deg[nLoudspeakers][1] = -90.0f;
248-
pData->loudpkrs_dirs_deg[nLoudspeakers+1][0] = 0.0f;
249-
pData->loudpkrs_dirs_deg[nLoudspeakers+1][1] = 90.0f;
255+
loudpkrs_dirs_deg_local[nLoudspeakers][0] = 0.0f;
256+
loudpkrs_dirs_deg_local[nLoudspeakers][1] = -90.0f;
257+
loudpkrs_dirs_deg_local[nLoudspeakers+1][0] = 0.0f;
258+
loudpkrs_dirs_deg_local[nLoudspeakers+1][1] = 90.0f;
250259
nLoudspeakers += 2;
251260
}
252261

@@ -261,16 +270,16 @@ void ambi_dec_initCodec
261270
M_dec_tmp = malloc1d(nLoudspeakers * max_nSH * sizeof(float));
262271
switch(pData->dec_method[d]){
263272
case DECODING_METHOD_SAD:
264-
getLoudspeakerDecoderMtx((float*)pData->loudpkrs_dirs_deg, nLoudspeakers, LOUDSPEAKER_DECODER_SAD, masterOrder, 0, M_dec_tmp);
273+
getLoudspeakerDecoderMtx((float*)loudpkrs_dirs_deg_local, nLoudspeakers, LOUDSPEAKER_DECODER_SAD, masterOrder, 0, M_dec_tmp);
265274
break;
266275
case DECODING_METHOD_MMD:
267-
getLoudspeakerDecoderMtx((float*)pData->loudpkrs_dirs_deg, nLoudspeakers, LOUDSPEAKER_DECODER_MMD, masterOrder, 0, M_dec_tmp);
276+
getLoudspeakerDecoderMtx((float*)loudpkrs_dirs_deg_local, nLoudspeakers, LOUDSPEAKER_DECODER_MMD, masterOrder, 0, M_dec_tmp);
268277
break;
269278
case DECODING_METHOD_EPAD:
270-
getLoudspeakerDecoderMtx((float*)pData->loudpkrs_dirs_deg, nLoudspeakers, LOUDSPEAKER_DECODER_EPAD, masterOrder, 0, M_dec_tmp);
279+
getLoudspeakerDecoderMtx((float*)loudpkrs_dirs_deg_local, nLoudspeakers, LOUDSPEAKER_DECODER_EPAD, masterOrder, 0, M_dec_tmp);
271280
break;
272281
case DECODING_METHOD_ALLRAD:
273-
getLoudspeakerDecoderMtx((float*)pData->loudpkrs_dirs_deg, nLoudspeakers, LOUDSPEAKER_DECODER_ALLRAD, masterOrder, 0, M_dec_tmp);
282+
getLoudspeakerDecoderMtx((float*)loudpkrs_dirs_deg_local, nLoudspeakers, LOUDSPEAKER_DECODER_ALLRAD, masterOrder, 0, M_dec_tmp);
274283
break;
275284
}
276285

@@ -880,7 +889,7 @@ void ambi_dec_getDecOrderHandle
880889
{
881890
ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
882891
(*pX_vector) = &pData->freqVector[0];
883-
(*pY_values) = &pData->orderPerBand[0];
892+
(*pY_values) = (int*)&pData->orderPerBand[0];
884893
(*pNpoints) = HYBRID_BANDS;
885894
}
886895

examples/src/ambi_dec/ambi_dec_internal.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ void ambi_dec_interpHRTFs
117117
void loadLoudspeakerArrayPreset
118118
(
119119
LOUDSPEAKER_ARRAY_PRESETS preset,
120-
float dirs_deg[MAX_NUM_LOUDSPEAKERS][2],
121-
int* newNCH,
120+
_Atomic_FLOAT32 dirs_deg[MAX_NUM_LOUDSPEAKERS][2],
121+
_Atomic_INT32* newNCH,
122122
int* nDims
123123
)
124124
{
@@ -311,7 +311,7 @@ void loadLoudspeakerArrayPreset
311311
* (Fails if using 2D setups are not on the horizontal plane ) */
312312
sum_elev = 0.0f;
313313
for(i=0; i<nCH; i++)
314-
sum_elev += fabsf(dirs_deg[i][1]);
314+
sum_elev += fabsf((float)dirs_deg[i][1]);
315315
if(sum_elev < 0.01f)
316316
(*nDims) = 2;
317317
else

examples/src/ambi_dec/ambi_dec_internal.h

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@ extern "C" {
7777
# error "AMBI_DEC_FRAME_SIZE must be an integer multiple of HOP_SIZE"
7878
#endif
7979

80+
#ifndef __STDC_NO_ATOMICS__
81+
typedef _Atomic(AMBI_DEC_DECODING_METHODS) _Atomic_AMBI_DEC_DECODING_METHODS;
82+
typedef _Atomic(AMBI_DEC_DIFFUSE_FIELD_EQ_APPROACH) _Atomic_AMBI_DEC_DIFFUSE_FIELD_EQ_APPROACH;
83+
#else
84+
typedef AMBI_DEC_DECODING_METHODS _Atomic_AMBI_DEC_DECODING_METHODS;
85+
typedef AMBI_DEC_DIFFUSE_FIELD_EQ_APPROACH _Atomic_AMBI_DEC_DIFFUSE_FIELD_EQ_APPROACH;
86+
#endif
87+
8088
/* ========================================================================== */
8189
/* Structures */
8290
/* ========================================================================== */
@@ -98,9 +106,9 @@ typedef struct _ambi_dec_codecPars
98106
char* sofa_filepath; /**< absolute/relevative file path for a sofa file */
99107
float* hrirs; /**< time domain HRIRs; N_hrir_dirs x 2 x hrir_len */
100108
float* hrir_dirs_deg; /**< directions of the HRIRs in degrees [azi elev]; N_hrir_dirs x 2 */
101-
int N_hrir_dirs; /**< number of HRIR directions in the current sofa file */
102-
int hrir_len; /**< length of the HRIRs, this can be truncated, see "saf_sofa_reader.h" */
103-
int hrir_fs; /**< sampling rate of the HRIRs, should ideally match the host sampling rate, although not required */
109+
_Atomic_INT32 N_hrir_dirs; /**< number of HRIR directions in the current sofa file */
110+
_Atomic_INT32 hrir_len; /**< length of the HRIRs, this can be truncated, see "saf_sofa_reader.h" */
111+
_Atomic_INT32 hrir_fs; /**< sampling rate of the HRIRs, should ideally match the host sampling rate, although not required */
104112

105113
/* vbap gain table for panning the HRIRs */
106114
int hrtf_vbapTableRes[2]; /**< [azi elev] step sizes in degrees */
@@ -134,40 +142,40 @@ typedef struct _ambi_dec
134142
float_complex*** binframeTF; /**< Output binaural signals in the time-frequency domain; #HYBRID_BANDS x #NUM_EARS x #TIME_SLOTS */
135143
void* hSTFT; /**< afSTFT handle */
136144
int afSTFTdelay; /**< for host delay compensation */
137-
int fs; /**< host sampling rate */
145+
_Atomic_INT32 fs; /**< host sampling rate */
138146
float freqVector[HYBRID_BANDS]; /**< frequency vector for time-frequency transform, in Hz */
139147

140148
/* our codec configuration */
141-
CODEC_STATUS codecStatus; /**< see #CODEC_STATUS */
142-
float progressBar0_1; /**< Current (re)initialisation progress, between [0..1] */
149+
_Atomic_CODEC_STATUS codecStatus; /**< see #CODEC_STATUS */
150+
_Atomic_FLOAT32 progressBar0_1; /**< Current (re)initialisation progress, between [0..1] */
143151
char* progressBarText; /**< Current (re)initialisation step, string */
144152
ambi_dec_codecPars* pars; /**< codec parameters */
145153

146154
/* internal variables */
147-
int loudpkrs_nDims; /**< dimensionality of the current loudspeaker set-up */
148-
int new_nLoudpkrs; /**< if new_nLoudpkrs != nLoudpkrs, afSTFT is reinitialised (current value will be replaced by this after next re-init) */
149-
int new_binauraliseLS; /**< if new_binauraliseLS != binauraliseLS, ambi_dec is reinitialised (current value will be replaced by this after next re-init) */
150-
int new_masterOrder; /**< if new_masterOrder != masterOrder, ambi_dec is reinitialised (current value will be replaced by this after next re-init) */
155+
int loudpkrs_nDims; /**< dimensionality of the current loudspeaker set-up */
156+
_Atomic_INT32 new_nLoudpkrs; /**< if new_nLoudpkrs != nLoudpkrs, afSTFT is reinitialised (current value will be replaced by this after next re-init) */
157+
_Atomic_INT32 new_binauraliseLS; /**< if new_binauraliseLS != binauraliseLS, ambi_dec is reinitialised (current value will be replaced by this after next re-init) */
158+
_Atomic_INT32 new_masterOrder; /**< if new_masterOrder != masterOrder, ambi_dec is reinitialised (current value will be replaced by this after next re-init) */
151159

152160
/* flags */
153-
PROC_STATUS procStatus; /**< see #PROC_STATUS */
154-
int reinit_hrtfsFLAG; /**< 0: no init required, 1: init required */
155-
int recalc_hrtf_interpFLAG[MAX_NUM_LOUDSPEAKERS]; /**< 0: no init required, 1: init required */
161+
_Atomic_PROC_STATUS procStatus; /**< see #PROC_STATUS */
162+
_Atomic_INT32 reinit_hrtfsFLAG; /**< 0: no init required, 1: init required */
163+
_Atomic_INT32 recalc_hrtf_interpFLAG[MAX_NUM_LOUDSPEAKERS]; /**< 0: no init required, 1: init required */
156164

157165
/* user parameters */
158-
int masterOrder; /**< Current maximum/master decoding order */
159-
int orderPerBand[HYBRID_BANDS]; /**< Ambisonic decoding order per frequency band 1..SH_ORDER */
160-
AMBI_DEC_DECODING_METHODS dec_method[NUM_DECODERS]; /**< decoding methods for each decoder, see #AMBI_DEC_DECODING_METHODS enum */
161-
int rE_WEIGHT[NUM_DECODERS]; /**< 0:disabled, 1: enable max_rE weight */
162-
AMBI_DEC_DIFFUSE_FIELD_EQ_APPROACH diffEQmode[NUM_DECODERS]; /**< diffuse-field EQ approach; see #AMBI_DEC_DIFFUSE_FIELD_EQ_APPROACH enum */
163-
float transitionFreq; /**< transition frequency for the 2 decoders, in Hz */
164-
int nLoudpkrs; /**< number of loudspeakers/virtual loudspeakers */
165-
float loudpkrs_dirs_deg[MAX_NUM_LOUDSPEAKERS][NUM_DECODERS]; /**< loudspeaker directions in degrees [azi, elev] */
166-
int useDefaultHRIRsFLAG; /**< 1: use default HRIRs in database, 0: use those from SOFA file */
167-
int enableHRIRsPreProc; /**< flag to apply pre-processing to the currently loaded HRTFs */
168-
int binauraliseLS; /**< 1: convolve loudspeaker signals with HRTFs, 0: output loudspeaker signals */
169-
CH_ORDER chOrdering; /**< Ambisonic channel order convention (see #CH_ORDER) */
170-
NORM_TYPES norm; /**< Ambisonic normalisation convention (see #NORM_TYPES) */
166+
_Atomic_INT32 masterOrder; /**< Current maximum/master decoding order */
167+
_Atomic_INT32 orderPerBand[HYBRID_BANDS]; /**< Ambisonic decoding order per frequency band 1..SH_ORDER */
168+
_Atomic_AMBI_DEC_DECODING_METHODS dec_method[NUM_DECODERS]; /**< decoding methods for each decoder, see #AMBI_DEC_DECODING_METHODS enum */
169+
_Atomic_INT32 rE_WEIGHT[NUM_DECODERS]; /**< 0:disabled, 1: enable max_rE weight */
170+
_Atomic_AMBI_DEC_DIFFUSE_FIELD_EQ_APPROACH diffEQmode[NUM_DECODERS]; /**< diffuse-field EQ approach; see #AMBI_DEC_DIFFUSE_FIELD_EQ_APPROACH enum */
171+
_Atomic_FLOAT32 transitionFreq; /**< transition frequency for the 2 decoders, in Hz */
172+
_Atomic_INT32 nLoudpkrs; /**< number of loudspeakers/virtual loudspeakers */
173+
_Atomic_FLOAT32 loudpkrs_dirs_deg[MAX_NUM_LOUDSPEAKERS][2]; /**< loudspeaker directions in degrees [azi, elev] */
174+
_Atomic_INT32 useDefaultHRIRsFLAG; /**< 1: use default HRIRs in database, 0: use those from SOFA file */
175+
_Atomic_INT32 enableHRIRsPreProc; /**< flag to apply pre-processing to the currently loaded HRTFs */
176+
_Atomic_INT32 binauraliseLS; /**< 1: convolve loudspeaker signals with HRTFs, 0: output loudspeaker signals */
177+
_Atomic_CH_ORDER chOrdering; /**< Ambisonic channel order convention (see #CH_ORDER) */
178+
_Atomic_NORM_TYPES norm; /**< Ambisonic normalisation convention (see #NORM_TYPES) */
171179

172180
} ambi_dec_data;
173181

@@ -216,8 +224,8 @@ void ambi_dec_interpHRTFs(void* const hAmbi,
216224
* @param[out] nDims (&) number of dimensions (2 or 3)
217225
*/
218226
void loadLoudspeakerArrayPreset(LOUDSPEAKER_ARRAY_PRESETS preset,
219-
float dirs_deg[MAX_NUM_LOUDSPEAKERS][2],
220-
int* nCH,
227+
_Atomic_FLOAT32 dirs_deg[MAX_NUM_LOUDSPEAKERS][2],
228+
_Atomic_INT32* nCH,
221229
int* nDims);
222230

223231

examples/src/ambi_drc/ambi_drc_internal.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ void ambi_drc_initTFT
101101
pData->nSH = pData->new_nSH;
102102
}
103103

104-
void ambi_drc_setInputOrder(SH_ORDERS inOrder, int* nSH)
104+
void ambi_drc_setInputOrder(SH_ORDERS inOrder, _Atomic_INT32* nSH)
105105
{
106106
switch(inOrder){
107107
case SH_ORDER_FIRST:

0 commit comments

Comments
 (0)