2022-11-08 17:18:54 -05:00
|
|
|
/*
|
|
|
|
* The MIT License (MIT)
|
|
|
|
*
|
|
|
|
* Copyright (c) 2022 Matthew McGowan for Blues Inc.
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
|
|
* in the Software without restriction, including without limitation the rights
|
|
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
* THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
2022-11-04 16:15:15 -04:00
|
|
|
#ifndef _MEMS_AUDIO_H_
|
|
|
|
#define _MEMS_AUDIO_H_
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief How many milliseconds of audio can fit in the audio buffer(s).
|
2023-03-18 11:17:02 -04:00
|
|
|
* Interrupts for received data fire at half this duration / twice the frequency.
|
2022-11-04 16:15:15 -04:00
|
|
|
*/
|
|
|
|
#ifndef MEMS_AUDIO_MS_BUFFER
|
|
|
|
#define MEMS_AUDIO_MS_BUFFER (1)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The number of bits per sample of the PCM output
|
|
|
|
*/
|
|
|
|
#define PCM_OUT_RESOLUTION 16
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The output frequency of PCM samples in Hz.
|
|
|
|
*/
|
|
|
|
#define PCM_OUT_SAMPLING_FREQUENCY 16000
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief type for describing error conditions.
|
|
|
|
*/
|
|
|
|
typedef int32_t mems_audio_err_t;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The datatype that holds an output PCM sample.
|
|
|
|
*/
|
|
|
|
typedef int16_t pcm_sample_t;
|
|
|
|
_Static_assert(PCM_OUT_RESOLUTION==16, "Output PCM resolution must be 16-bits");
|
|
|
|
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
MEMS_AUDIO_OK = 0,
|
|
|
|
MEMS_AUDIO_ERROR_ALREADY_INITIALIZED = -1,
|
|
|
|
MEMS_AUDIO_ERROR_NOT_INITIALIZED = -2
|
|
|
|
} mems_audio_err_enum_t;
|
|
|
|
|
|
|
|
#define IS_MEMS_AUDIO_ERROR(e) (e)
|
|
|
|
#define CHECK_MEMS_AUDIO_ERROR(e) { if (IS_MEMS_AUDIO_ERROR(e)) return e; }
|
|
|
|
#define CHECK_MEMS_AUDIO_INITIALIZED(x) { if (!x) return MEMS_AUDIO_ERROR_NOT_INITIALIZED; }
|
|
|
|
|
|
|
|
typedef struct MemsAudio_t MemsAudio;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Callback informing that PCM samples are available for processing.
|
|
|
|
*/
|
|
|
|
typedef void (*pcm_data_available_t)(MemsAudio* audio, pcm_sample_t* pcmSamples, size_t pcmLength);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief MemsAudio manages the filter, buffers and callbacks used to capture PDM audio samples and convert to PCM.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
typedef struct MemsAudio_t {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The buffer to store PCM audio samples
|
|
|
|
*/
|
|
|
|
volatile pcm_sample_t* volatile pcmOutputBuffer;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The length of the PCM buffer. SHould be at least MEMS_AUDIO_PCM_BUFFER_LENGTH
|
|
|
|
*/
|
|
|
|
volatile size_t pcmOutputBufferLength;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Optional callback for when PCM data is available.
|
|
|
|
*/
|
|
|
|
pcm_data_available_t pcm_data_available;
|
|
|
|
|
|
|
|
void* audioImpl;
|
|
|
|
void* userData;
|
|
|
|
} MemsAudio;
|
|
|
|
|
|
|
|
|
|
|
|
mems_audio_err_t mems_audio_init(MemsAudio* audio);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Uninitializes the MemsAudio instance.
|
|
|
|
*
|
|
|
|
* @param audio
|
|
|
|
* @return mems_audio_err_t
|
|
|
|
*/
|
|
|
|
mems_audio_err_t mems_audio_uninit(MemsAudio* audio);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Asynchronously records audio.
|
|
|
|
*
|
|
|
|
* @param audio
|
|
|
|
* @param pdmBuffer
|
|
|
|
* @param pdmBufferLength
|
|
|
|
* @return mems_audio_err_t
|
|
|
|
*/
|
|
|
|
mems_audio_err_t mems_audio_record(MemsAudio* audio);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Pause recording audio.
|
|
|
|
*/
|
|
|
|
mems_audio_err_t mems_audio_pause(MemsAudio* audio);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Resume recording audio.
|
|
|
|
*
|
|
|
|
* @param audio
|
|
|
|
* @return mems_audio_err_t
|
|
|
|
*/
|
|
|
|
mems_audio_err_t mems_audio_resume(MemsAudio* audio);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Stop recording audio and
|
|
|
|
*
|
|
|
|
* @param audio
|
|
|
|
* @return mems_audio_err_t
|
|
|
|
*/
|
|
|
|
mems_audio_err_t mems_audio_stop(MemsAudio* audio);
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#endif // _MEMS_AUDIO_H_
|