libDaisy
Hardware Library for Daisy
Loading...
Searching...
No Matches
WavWriter.h
Go to the documentation of this file.
1#pragma once
2#pragma once
3#include "fatfs.h"
4
5namespace daisy
6{
32template <size_t transfer_size>
34{
35 public:
38
40 enum class Result
41 {
42 OK,
43 ERROR,
44 };
45
54
59 enum class BufferState
60 {
61 IDLE,
62 FLUSH0,
63 FLUSH1,
64 };
65
67 void Init(const Config &cfg)
68 {
69 cfg_ = cfg;
70 num_samps_ = 0;
71 // Prep the wav header according to config.
72 // Certain things (i.e. Size, etc. will have to wait until the finalization of the file, or be updated while streaming).
73 wavheader_.ChunkId = kWavFileChunkId;
74 wavheader_.FileFormat = kWavFileWaveId;
75 wavheader_.SubChunk1ID = kWavFileSubChunk1Id;
76 wavheader_.SubChunk1Size = 16; // for PCM
77 wavheader_.AudioFormat = WAVE_FORMAT_PCM;
78 wavheader_.NbrChannels = cfg.channels;
79 wavheader_.SampleRate = static_cast<int>(cfg.samplerate);
80 wavheader_.ByteRate = CalcByteRate();
81 wavheader_.BlockAlign = cfg_.channels * cfg_.bitspersample / 8;
82 wavheader_.BitPerSample = cfg_.bitspersample;
83 wavheader_.SubChunk2ID = kWavFileSubChunk2Id;
85 wavheader_.FileSize = CalcFileSize();
86 // This is calculated as part of the subchunk size
87 }
88
93 void Sample(const float *in)
94 {
95 for(size_t i = 0; i < cfg_.channels; i++)
96 {
97 switch(cfg_.bitspersample)
98 {
99 case 16:
100 {
101 int16_t *tp;
102 tp = (int16_t *)transfer_buff;
103 tp[wptr_ + i] = f2s16(in[i]);
104 }
105 break;
106 case 32: transfer_buff[wptr_ + i] = f2s32(in[i]); break;
107 default: break;
108 }
109 }
110 num_samps_++;
111 wptr_ += cfg_.channels;
112 size_t cap_point
113 = cfg_.bitspersample == 16 ? kTransferSamps * 2 : kTransferSamps;
114 if(wptr_ == cap_point)
115 {
116 bstate_ = BufferState::FLUSH0;
117 }
118 if(wptr_ >= cap_point * 2)
119 {
120 wptr_ = 0;
121 bstate_ = BufferState::FLUSH1;
122 }
123 }
124
126 void Write()
127 {
128 if(bstate_ != BufferState::IDLE && IsRecording())
129 {
131 unsigned int bw = 0;
132 //offset = bstate_ == BufferState::FLUSH0 ? 0 : transfer_size;
133 offset = bstate_ == BufferState::FLUSH0 ? 0 : kTransferSamps;
134 bstate_ = BufferState::IDLE;
135 f_write(&fp_, &transfer_buff[offset], transfer_size, &bw);
136 }
137 }
138
142 void SaveFile()
143 {
144 unsigned int bw = 0;
145 recording_ = false;
146 // We _should_ flush whatever's left in the transfer buff
147 // TODO: that.
148 wavheader_.FileSize = CalcFileSize();
149 f_lseek(&fp_, 0);
150 f_write(&fp_, &wavheader_, sizeof(wavheader_), &bw);
151 f_close(&fp_);
152 }
153
155 void OpenFile(const char *name)
156 {
157 if(f_open(&fp_, name, FA_WRITE | FA_CREATE_ALWAYS) == FR_OK)
158 {
159 unsigned int bw = 0;
160 if(f_write(&fp_, &wavheader_, sizeof(wavheader_), &bw) == FR_OK)
161 {
162 recording_ = true;
163 num_samps_ = 0;
164 }
165 }
166 }
167
169 inline bool IsRecording() const { return recording_; }
170
172 inline uint32_t GetLengthSamps() { return num_samps_; }
173
175 inline float GetLengthSeconds()
176 {
177 return (float)num_samps_ / (float)cfg_.samplerate;
178 }
179
180 private:
182 inline uint32_t CalcFileSize()
183 {
184 wavheader_.SubCHunk2Size
185 = num_samps_ * cfg_.channels * cfg_.bitspersample / 8;
186 return 36 + wavheader_.SubCHunk2Size;
187 }
188
190 inline uint32_t CalcByteRate()
191 {
192 return cfg_.samplerate * cfg_.channels * cfg_.bitspersample / 8;
193 }
194
195 static constexpr int kTransferSamps = transfer_size / sizeof(int32_t);
196
197 WAV_FormatTypeDef wavheader_;
198 uint32_t num_samps_, wptr_;
199 Config cfg_;
200 int32_t transfer_buff[kTransferSamps * 2];
201 BufferState bstate_;
202 bool recording_;
203 FIL fp_;
204};
205
206} // namespace daisy
Definition leddriver.h:33
Definition WavWriter.h:34
void Sample(const float *in)
Definition WavWriter.h:93
BufferState
Definition WavWriter.h:60
uint32_t GetLengthSamps()
Definition WavWriter.h:172
bool IsRecording() const
Definition WavWriter.h:169
WavWriter()
Definition WavWriter.h:36
void SaveFile()
Definition WavWriter.h:142
void OpenFile(const char *name)
Definition WavWriter.h:155
~WavWriter()
Definition WavWriter.h:37
Result
Definition WavWriter.h:41
float GetLengthSeconds()
Definition WavWriter.h:175
void Write()
Definition WavWriter.h:126
void Init(const Config &cfg)
Definition WavWriter.h:67
FORCE_INLINE int16_t f2s16(float x)
Definition daisy_core.h:128
FORCE_INLINE int32_t f2s32(float x)
Definition daisy_core.h:163
Hardware defines and helpers for daisy field platform.
Definition index.h:2
const uint32_t kWavFileChunkId
Definition wav_format.h:15
const uint32_t kWavFileSubChunk2Id
Definition wav_format.h:18
const uint32_t kWavFileWaveId
Definition wav_format.h:16
@ WAVE_FORMAT_PCM
Definition wav_format.h:30
const uint32_t kWavFileSubChunk1Id
Definition wav_format.h:17
uint32_t SubChunk1ID
Definition wav_format.h:43
uint16_t BlockAlign
Definition wav_format.h:49
uint32_t SubChunk1Size
Definition wav_format.h:44
uint32_t ByteRate
Definition wav_format.h:48
uint32_t FileFormat
Definition wav_format.h:42
uint32_t ChunkId
Definition wav_format.h:40
uint32_t SubCHunk2Size
Definition wav_format.h:52
uint16_t NbrChannels
Definition wav_format.h:46
uint16_t BitPerSample
Definition wav_format.h:50
uint32_t FileSize
Definition wav_format.h:41
uint32_t SubChunk2ID
Definition wav_format.h:51
uint16_t AudioFormat
Definition wav_format.h:45
uint32_t SampleRate
Definition wav_format.h:47
Definition WavWriter.h:49
int32_t bitspersample
Definition WavWriter.h:52
float samplerate
Definition WavWriter.h:50
int32_t channels
Definition WavWriter.h:51