Sound Byte Libs 0.5.1-121-g3358a44
C++ firmware library for audio applications on 32-bit ARM Cortex-M processors
Loading...
Searching...
No Matches
render.hpp
Go to the documentation of this file.
1// sbl/dsp/host/render.hpp — Writing a render to disk (Cross-cutting — host only)
2//
3// The two writers every host tool and golden test copied (RPT-035 Part 4):
4// a 24-bit WAV and a raw float32 file in the layout analyst reads. File
5// I/O; never included from audio code.
6
7#ifndef SBL_DSP_HOST_RENDER_HPP_
8#define SBL_DSP_HOST_RENDER_HPP_
9
10#include <cstdint>
11#include <cstdio>
12
13namespace sbl::dsp::host {
14
15/// Interleaved float samples to a 24-bit PCM WAV, clamped to ±1.
16inline bool write_wav(const char* path, const float* data, int samples, int sample_rate, int channels) {
17 FILE* f = fopen(path, "wb");
18 if (!f) return false;
19
20 const int bytes_per_sample = 3;
21 const int data_size = samples * channels * bytes_per_sample;
22 const int fmt_chunk_size = 16;
23
24 fwrite("RIFF", 1, 4, f);
25 const uint32_t file_size = 36 + static_cast<uint32_t>(data_size);
26 fwrite(&file_size, 4, 1, f);
27 fwrite("WAVE", 1, 4, f);
28
29 fwrite("fmt ", 1, 4, f);
30 fwrite(&fmt_chunk_size, 4, 1, f);
31 const uint16_t audio_format = 1; // PCM
32 fwrite(&audio_format, 2, 1, f);
33 const uint16_t num_channels = static_cast<uint16_t>(channels);
34 fwrite(&num_channels, 2, 1, f);
35 const uint32_t sr = static_cast<uint32_t>(sample_rate);
36 fwrite(&sr, 4, 1, f);
37 const uint32_t byte_rate = sr * num_channels * bytes_per_sample;
38 fwrite(&byte_rate, 4, 1, f);
39 const uint16_t block_align = static_cast<uint16_t>(num_channels * bytes_per_sample);
40 fwrite(&block_align, 2, 1, f);
41 const uint16_t bits_per_sample = 24;
42 fwrite(&bits_per_sample, 2, 1, f);
43
44 fwrite("data", 1, 4, f);
45 const uint32_t ds = static_cast<uint32_t>(data_size);
46 fwrite(&ds, 4, 1, f);
47
48 constexpr float SCALE = 8388607.0f;
49 for (int i = 0; i < samples * channels; ++i) {
50 float clamped = data[i];
51 if (clamped > 1.0f) clamped = 1.0f;
52 if (clamped < -1.0f) clamped = -1.0f;
53 const int32_t s = static_cast<int32_t>(clamped * SCALE);
54 const uint8_t bytes[3] = {
55 static_cast<uint8_t>(s & 0xFF),
56 static_cast<uint8_t>((s >> 8) & 0xFF),
57 static_cast<uint8_t>((s >> 16) & 0xFF),
58 };
59 fwrite(bytes, 1, 3, f);
60 }
61
62 fclose(f);
63 return true;
64}
65
66/// Raw float32, native endianness: what `analyst measure` reads.
67inline bool write_float_bin(const char* path, const float* data, int samples) {
68 FILE* f = fopen(path, "wb");
69 if (!f) return false;
70 fwrite(data, sizeof(float), static_cast<size_t>(samples), f);
71 fclose(f);
72 return true;
73}
74
75} // namespace sbl::dsp::host
76
77#endif // SBL_DSP_HOST_RENDER_HPP_
Host-only file I/O.
Definition render.hpp:13
bool write_float_bin(const char *path, const float *data, int samples)
Raw float32, native endianness: what analyst measure reads.
Definition render.hpp:67
bool write_wav(const char *path, const float *data, int samples, int sample_rate, int channels)
Interleaved float samples to a 24-bit PCM WAV, clamped to ±1.
Definition render.hpp:16