34template <
size_t workspace_
bytes>
63 auto res =
Open(name);
67 for(
size_t i = 0; i < kMaxAudioChannels; i++)
69 current_sample_[i] = 0.f;
70 previous_sample_[i] = 0.f;
73 playback_speed_ = 1.f;
85 auto sta = f_open(&file_, name, (FA_OPEN_EXISTING | FA_READ));
95 daisy::FileReader reader(&file_);
97 if(!parser.
parse(reader))
99 const auto& info = parser.
info();
100 file_info_.
channels = info.numChannels;
102 auto bd = info.bitsPerSample;
109 frame_bytes_ = (file_info_.
channels) * (bd / 8);
110 if(frame_bytes_ == 0)
114 if(f_lseek(&file_, file_info_.
data_start) != FR_OK)
118 std::fill(buff_raw_, buff_raw_ + kRxSizeSamples, 0);
123 bytes_to_read -= (bytes_to_read % frame_bytes_);
124 if(bytes_to_read > 0)
126 if(f_read(&file_, (
void*)buff_raw_, bytes_to_read, &bytes_read)
132 if(bytes_read != bytes_to_read)
140 size_t samps_to_write = bytes_read /
sizeof(int16_t);
143 samps_to_write -= (samps_to_write % file_info_.
channels);
144 for(
size_t i = 0; i < samps_to_write; i++)
146 if(!buff_fifo_.
PushBack(buff_raw_[i]))
151 pending_read_req_ =
false;
152 pending_seek_req_ =
false;
180 while(!request_fifo_.
IsEmpty())
182 auto req = request_fifo_.
PopFront();
185 case IoRequest::Type::Read:
187 size_t bytes_requested = req.data *
sizeof(int16_t);
189 bytes_requested -= (bytes_requested % frame_bytes_);
190 if(bytes_requested == 0)
192 pending_read_req_ =
false;
196 UINT total_bytes_read = 0;
199 std::fill(buff_raw_, buff_raw_ + kRxSizeSamples, 0);
203 = std::min(bytes_requested, bytes_left_in_chunk_);
205 first_span -= (first_span % frame_bytes_);
214 if(bytes_read != first_span)
216 total_bytes_read += bytes_read;
217 bytes_left_in_chunk_ -= bytes_read;
221 if(total_bytes_read < bytes_requested && looping_)
223 if(f_lseek(&file_, file_info_.
data_start) != FR_OK)
226 size_t remaining_bytes
227 = bytes_requested - total_bytes_read;
229 remaining_bytes -= (remaining_bytes % frame_bytes_);
230 if(remaining_bytes > 0)
232 UINT bytes_read2 = 0;
234 = ((
char*)(buff_raw_) + total_bytes_read);
236 size_t span2 = std::min(remaining_bytes,
239 span2 -= (span2 % frame_bytes_);
248 if(bytes_read2 != span2)
250 total_bytes_read += bytes_read2;
262 size_t samps_to_write = total_bytes_read /
sizeof(int16_t);
265 -= (samps_to_write % file_info_.
channels);
267 for(
size_t i = 0; i < samps_to_write; i++)
269 if(!buff_fifo_.
PushBack(buff_raw_[i]))
271 pending_read_req_ =
false;
275 pending_read_req_ =
false;
278 case IoRequest::Type::Seek:
280 size_t dest_bytes = req.data *
sizeof(int16_t);
284 dest_bytes -= (dest_bytes % frame_bytes_);
286 if(f_lseek(&file_, file_info_.
data_start + dest_bytes)
292 pending_seek_req_ =
false;
327 auto channels = file_info_.
channels;
329 for(
size_t i = 0; i < num_channels; i++)
332 if(!buff_fifo_.
IsEmpty() && playing_)
334 size_t ch_out = std::min(channels, num_channels);
335 for(
size_t i = 0; i < ch_out; i++)
338 = previous_sample_[i]
339 + pos_acc_ * (current_sample_[i] - previous_sample_[i]);
342 pos_acc_ += playback_speed_;
343 while(pos_acc_ >= 1.f)
347 for(
size_t i = 0; i < channels; i++)
349 previous_sample_[i] = current_sample_[i];
355 if(position_ >= (file_info_.
length > 0 ? file_info_.
length : 1))
365 for(
size_t i = 0; i < kMaxAudioChannels; i++)
366 previous_sample_[i] = current_sample_[i];
371 bool requested_new_samps =
false;
372 if(buff_fifo_.
GetNumElements() < kRxFifoThreshold && !pending_read_req_)
374 size_t free_slots = (kRxSizeSamples - buff_fifo_.
GetNumElements());
375 size_t rx_qty = (free_slots > 1) ? (free_slots - 1) : 0;
378 rx_qty -= (rx_qty % file_info_.
channels);
383 IoRequest(IoRequest::Type::Read, rx_qty));
384 pending_read_req_ =
true;
385 requested_new_samps =
true;
388 if(requested_new_samps)
390 else if(buff_fifo_.
IsEmpty() && playing_)
400 request_fifo_.
Clear();
403 for(
size_t i = 0; i < kMaxAudioChannels; i++)
404 current_sample_[i] = previous_sample_[i] = 0.f;
408 request_fifo_.
PushBack(IoRequest(IoRequest::Type::Seek, 0));
411 size_t req_samps = kRxSizeSamples;
413 req_samps -= (req_samps % file_info_.
channels);
415 request_fifo_.
PushBack(IoRequest(IoRequest::Type::Read, req_samps));
417 pending_read_req_ =
true;
418 pending_seek_req_ =
true;
439 return static_cast<float>(position_) /
static_cast<float>(duration);
461 playback_speed_ = speed;
470 playback_speed_ = std::pow(2.f, semitones / 12.f);
495 IoRequest(Type t,
size_t val)
501 IoRequest() : type(Type::Unknown), data(0) {}
507 static const constexpr size_t kRxSizeSamples
508 = (workspace_bytes /
sizeof(int16_t));
511 static const constexpr size_t kRxFifoThreshold = ((kRxSizeSamples / 4) * 3);
514 static const constexpr size_t kMaxAudioChannels = 8;
529 int16_t buff_raw_[kRxSizeSamples];
537 bool looping_, playing_;
538 float playback_speed_;
541 float current_sample_[kMaxAudioChannels];
544 float previous_sample_[kMaxAudioChannels];
550 bool pending_read_req_;
551 bool pending_seek_req_;
553 size_t bytes_left_in_chunk_;
bool PushBack(const T &elementToAdd)
Definition FIFO.h:49
T PopFront()
Definition FIFO.h:101
size_t GetNumElements() const
Definition FIFO.h:171
void Clear()
Definition FIFO.h:45
bool IsEmpty() const
Definition FIFO.h:165
Definition WavParser.h:64
uint32_t dataSize() const
Definition WavParser.h:134
const WavFormatInfo & info() const
Definition WavParser.h:132
uint32_t dataOffset() const
Definition WavParser.h:133
bool parse(IReader &r)
Definition WavParser.h:79
Definition WavPlayer.h:36
size_t GetChannels() const
Definition WavPlayer.h:430
void SetPlaybackSpeedRatio(const float speed)
Definition WavPlayer.h:457
WavPlayer()
Definition WavPlayer.h:38
Result Open(const char *name)
Definition WavPlayer.h:81
uint32_t GetPosition() const
Definition WavPlayer.h:433
bool GetPlaying() const
Definition WavPlayer.h:451
Result Stream(float *samples, size_t num_channels)
Definition WavPlayer.h:325
~WavPlayer()
Definition WavPlayer.h:39
void Restart()
Definition WavPlayer.h:397
void SetLooping(bool state)
Definition WavPlayer.h:445
size_t GetDurationInSamples() const
Definition WavPlayer.h:424
void SetPlaybackSpeedSemitones(const float semitones)
Definition WavPlayer.h:468
bool GetLooping() const
Definition WavPlayer.h:448
Result Prepare()
Definition WavPlayer.h:178
Result Close()
Definition WavPlayer.h:162
Result
Definition WavPlayer.h:43
void SetPlaying(bool state)
Definition WavPlayer.h:450
float GetNormalizedPosition() const
Definition WavPlayer.h:436
Result Init(const char *name)
Definition WavPlayer.h:60
FORCE_INLINE float s162f(int16_t x)
Definition daisy_core.h:120
Hardware defines and helpers for daisy field platform.
Definition index.h:2
Definition WavPlayer.h:54
size_t length
Definition WavPlayer.h:55
size_t data_size_bytes
Definition WavPlayer.h:56
size_t channels
Definition WavPlayer.h:55
size_t data_start
Definition WavPlayer.h:55
size_t samplerate
Definition WavPlayer.h:55