circuitpython/ports/stm/common-hal/audiobusio/MEMS_Audio.h

157 lines
4.0 KiB
C

/*
* 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.
*/
#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).
* Interrupts for received data fire at half this duration / twice the frequency.
*/
#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_