import esp audio lib
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
AudioFileSourceFunction
|
||||
Audio ouptut generator which can generate WAV file data from function
|
||||
|
||||
Copyright (C) 2021 Hideaki Tai
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _AUDIOFILESOURCEFUNCTION_H
|
||||
#define _AUDIOFILESOURCEFUNCTION_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
#include "AudioFileSource.h"
|
||||
|
||||
class AudioFileSourceFunction : public AudioFileSource {
|
||||
union WavHeader {
|
||||
struct {
|
||||
// RIFF chunk
|
||||
struct {
|
||||
char chunk_id[4]; // "RIFF"
|
||||
uint32_t chunk_size; // 4 + (8 + sizeof(format_chunk)(16)) + (8 + sizeof(data_chunk))
|
||||
char format[4]; // "WAVE"
|
||||
} riff;
|
||||
// format chunk
|
||||
struct {
|
||||
char chunk_id[4]; // "fmt "
|
||||
uint32_t chunk_size; // 16
|
||||
uint16_t format_tag; // 1: PCM
|
||||
uint16_t channels; // 1: MONO, 2: STEREO
|
||||
uint32_t sample_per_sec; // 8000, 11025, 22050, 44100, 48000
|
||||
uint32_t avg_bytes_per_sec; // sample_per_sec * channels * bits_per_sample / 8
|
||||
uint16_t block_align; // channels * bits_per_sample / 8
|
||||
uint16_t bits_per_sample; // 8, 16, 32
|
||||
} format;
|
||||
// data chunk
|
||||
struct {
|
||||
char chunk_id[4]; // "data"
|
||||
uint32_t chunk_size; // num_samples * channels * bytes_per_sample
|
||||
// audio data follows here...
|
||||
} data;
|
||||
};
|
||||
uint8_t bytes[44];
|
||||
} wav_header;
|
||||
|
||||
union Uint8AndInt8 {
|
||||
int8_t i;
|
||||
uint8_t u;
|
||||
};
|
||||
|
||||
union Uint8AndInt16 {
|
||||
int16_t i;
|
||||
uint8_t u[2];
|
||||
};
|
||||
|
||||
union Uint8AndInt32 {
|
||||
int32_t i;
|
||||
uint8_t u[4];
|
||||
};
|
||||
|
||||
using callback_t = std::function<float(float)>;
|
||||
std::vector<callback_t> funcs;
|
||||
uint32_t pos;
|
||||
uint32_t size;
|
||||
bool is_ready;
|
||||
bool is_unique;
|
||||
|
||||
public:
|
||||
AudioFileSourceFunction(float sec, uint16_t channels = 1, uint32_t sample_per_sec = 8000, uint16_t bits_per_sample = 16);
|
||||
virtual ~AudioFileSourceFunction() override;
|
||||
|
||||
template <typename F, typename... Fs>
|
||||
bool addAudioGenerators(const F& f, Fs&&... fs) {
|
||||
funcs.emplace_back(f);
|
||||
return addAudioGenerators(std::forward<Fs>(fs)...);
|
||||
}
|
||||
bool addAudioGenerators() {
|
||||
funcs.shrink_to_fit();
|
||||
if (funcs.size() == 1) {
|
||||
is_ready = true;
|
||||
is_unique = true;
|
||||
return true;
|
||||
} else if (funcs.size() == wav_header.format.channels) {
|
||||
is_ready = true;
|
||||
is_unique = false;
|
||||
return true;
|
||||
} else {
|
||||
is_ready = false;
|
||||
is_unique = false;
|
||||
funcs.clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
virtual uint32_t read(void* data, uint32_t len) override;
|
||||
virtual bool seek(int32_t pos, int dir) override;
|
||||
|
||||
virtual bool close() override;
|
||||
virtual bool isOpen() override;
|
||||
|
||||
virtual uint32_t getSize() override;
|
||||
virtual uint32_t getPos() override;
|
||||
};
|
||||
|
||||
#endif // _AUDIOFILESOURCEFUNCTION_H
|
||||
Reference in New Issue
Block a user