Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
streaming_sample_source_file.hpp
Go to the documentation of this file.
1#pragma once
2
15
16#include <algorithm>
17#include <array>
18#include <cstdint>
19#include <limits>
20#include <memory>
21#include <string>
22#include <string_view>
23#include <vector>
24
26#include <pulp/audio/buffer.hpp>
30
31namespace pulp::audio {
32
38 std::uint32_t channels = 0;
39 std::uint64_t total_frames = 0;
40 std::uint32_t sample_rate = 0;
41 std::array<std::uint8_t, 32> content_sha256{};
42 std::uint64_t mapped_byte_size = 0;
45 bool valid = false;
46};
47
51 std::shared_ptr<MemoryMappedAudioReader> mapped,
52 bool require_ranged_read = false,
53 bool compute_content_identity = false,
54 std::uint64_t maximum_mapped_bytes = std::numeric_limits<std::uint64_t>::max()) {
55 FileFrameReader result;
56 if (!mapped || !mapped->is_open()) {
57 return result; // valid == false
58 }
59 if (mapped->size() > maximum_mapped_bytes) {
60 return result;
61 }
62
63 const auto& info = mapped->info();
64 const std::uint32_t channels = info.num_channels;
65 const std::uint64_t total = info.num_frames;
66 if (channels == 0 || total == 0) {
67 return result; // unusable file
68 }
69
70 result.channels = channels;
71 result.total_frames = total;
72 result.sample_rate = info.sample_rate;
73 if (compute_content_identity) {
74 const auto digest = runtime::sha256(mapped->data(), mapped->size());
75 if (digest.size() != result.content_sha256.size())
76 return {};
77 std::copy(digest.begin(), digest.end(), result.content_sha256.begin());
78 result.mapped_byte_size = mapped->size();
79 result.has_content_identity = true;
80 }
81 result.supports_ranged_read = mapped->supports_ranged_read();
82 if (require_ranged_read && !result.supports_ranged_read)
83 return result;
86 result.binding.read = [mapped = std::move(mapped), channels, total, require_ranged_read,
87 destinations = std::vector<float*>(channels)](
88 std::uint64_t start_frame, BufferView<float> dest,
89 std::uint64_t frames,
90 FrameReaderStopToken stop_token) mutable -> std::uint64_t {
91 constexpr std::uint64_t kStopCheckFrames = 16384;
92 if (start_frame >= total)
93 return 0;
94 const std::uint64_t n = std::min({
95 frames,
96 total - start_frame,
97 static_cast<std::uint64_t>(dest.num_samples()),
98 });
99 if (n == 0)
100 return 0;
101 const std::uint32_t use_ch =
102 std::min<std::uint32_t>(channels, static_cast<std::uint32_t>(dest.num_channels()));
103 if (use_ch == 0)
104 return 0;
105
106 std::uint64_t produced = 0;
107 while (produced < n && !stop_token.stop_requested()) {
108 const auto chunk = std::min(kStopCheckFrames, n - produced);
109 for (std::uint32_t ch = 0; ch < use_ch; ++ch) {
110 destinations[ch] = dest.channel_ptr(ch) + produced;
111 }
112 const auto read = require_ranged_read
113 ? mapped->read_frames_ranged_only(destinations.data(), use_ch,
114
115 start_frame + produced, chunk)
116 : mapped->read_frames(destinations.data(), use_ch,
117 start_frame + produced, chunk);
118 if (!read) {
119 return produced;
120 }
121 produced += chunk;
122 }
123 return produced;
124 };
125 const auto stoppable = result.binding.read;
126 result.reader = [stoppable](std::uint64_t start_frame, BufferView<float> destination,
127 std::uint64_t frames) mutable {
128 return stoppable(start_frame, destination, frames, {});
129 };
130 result.valid = true;
131 return result;
132}
133
139 std::string_view path, bool require_ranged_read = false, bool compute_content_identity = false,
140 std::uint64_t maximum_mapped_bytes = std::numeric_limits<std::uint64_t>::max(),
141 std::shared_ptr<MemoryMappedAudioReader>* retained_reader = nullptr) {
142 if (retained_reader != nullptr)
143 retained_reader->reset();
144 auto mapped = std::make_shared<MemoryMappedAudioReader>();
145 const auto mapped_limit = static_cast<std::size_t>(
146 std::min<std::uint64_t>(maximum_mapped_bytes, std::numeric_limits<std::size_t>::max()));
147 if (!mapped->open(path, mapped_limit))
148 return {};
149 auto retained = mapped;
151 std::move(mapped), require_ranged_read, compute_content_identity,
152 maximum_mapped_bytes);
153 if (result.valid && retained_reader != nullptr)
154 *retained_reader = std::move(retained);
155 return result;
156}
157
158} // namespace pulp::audio
Non-owning view over multi-channel audio sample data.
Definition buffer.hpp:30
Cooperative cancellation signal passed to a streaming frame reader.
Definition streaming_sample_source.hpp:45
Definition analyzer_provider.hpp:12
std::function< std::uint64_t(std::uint64_t start_frame, BufferView< float > dest, std::uint64_t frames)> FrameReader
Caller-supplied random-access frame reader.
Definition streaming_sample_source.hpp:73
FileFrameReader make_memory_mapped_frame_reader(std::string_view path, bool require_ranged_read=false, bool compute_content_identity=false, std::uint64_t maximum_mapped_bytes=std::numeric_limits< std::uint64_t >::max(), std::shared_ptr< MemoryMappedAudioReader > *retained_reader=nullptr)
Open and retain a mapped reader for path.
Definition streaming_sample_source_file.hpp:138
FileFrameReader make_retained_memory_mapped_frame_reader(std::shared_ptr< MemoryMappedAudioReader > mapped, bool require_ranged_read=false, bool compute_content_identity=false, std::uint64_t maximum_mapped_bytes=std::numeric_limits< std::uint64_t >::max())
Bind an existing immutable mapped snapshot.
Definition streaming_sample_source_file.hpp:50
@ Cooperative
Definition streaming_sample_source.hpp:80
@ JoinOnly
Definition streaming_sample_source.hpp:79
std::vector< uint8_t > sha256(const uint8_t *data, size_t size)
Compute SHA-256 hash.
Real-time-safe streaming sample playback primitive.
A FrameReader plus the opened file's properties, ready to feed into a StreamingSampleSourceConfig (ch...
Definition streaming_sample_source_file.hpp:35
bool supports_ranged_read
Definition streaming_sample_source_file.hpp:44
std::uint32_t sample_rate
Definition streaming_sample_source_file.hpp:40
std::uint64_t total_frames
Definition streaming_sample_source_file.hpp:39
bool has_content_identity
Definition streaming_sample_source_file.hpp:43
FrameReader reader
Definition streaming_sample_source_file.hpp:36
std::uint32_t channels
Definition streaming_sample_source_file.hpp:38
std::array< std::uint8_t, 32 > content_sha256
Definition streaming_sample_source_file.hpp:41
FrameReaderBinding binding
Definition streaming_sample_source_file.hpp:37
bool valid
Definition streaming_sample_source_file.hpp:45
std::uint64_t mapped_byte_size
Definition streaming_sample_source_file.hpp:42
Definition streaming_sample_source.hpp:89
StoppableFrameReader read
Definition streaming_sample_source.hpp:90
FrameReaderStopMode stop_mode
Definition streaming_sample_source.hpp:91