/* 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 . */ #ifndef _AUDIOFILESOURCEFUNCTION_H #define _AUDIOFILESOURCEFUNCTION_H #include #include #include #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; std::vector 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 bool addAudioGenerators(const F& f, Fs&&... fs) { funcs.emplace_back(f); return addAudioGenerators(std::forward(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