VAE - Virtual Audio Engine 1
Small Data Driven Audio Engine
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
tklb::wave Namespace Reference

Namespaces

namespace  _
 redirects malloc for drwav, not really needed since loading and saving wavs doesn't seem to allocate anything on the heap
 

Classes

struct  WaveOptions
 Small option struct to save wave files. More...
 

Functions

template<typename T , class Buffer = AudioBufferTpl<T>>
bool load (const char *path, Buffer &out, typename Buffer::Size length=0)
 Decode wav from memory or file path. More...
 
template<typename T , class Buffer = AudioBufferTpl<T>>
bool write (const Buffer &in, const char *path, const WaveOptions &&options={}, HeapBuffer< char > *out=nullptr)
 Write audiobuffer to file or memory. More...
 

Function Documentation

◆ load()

template<typename T , class Buffer = AudioBufferTpl<T>>
bool tklb::wave::load ( const char *  path,
Buffer &  out,
typename Buffer::Size  length = 0 
)

Decode wav from memory or file path.

Parameters
pathThe path or the wav file buffer if length is non 0
outThe buffer to store the result in
lengthThe length of the wav file buffer if not reading from file

Definition at line 37 of file TWaveFile.hpp.

37 {
38 drwav_allocation_callbacks drwaveCallbacks {
39 nullptr, // No userdata
41 nullptr, // TODO tklb test and add the realloc
43 };
44
45 using Size = typename Buffer::Size;
46 using uchar = unsigned char;
47 using ushort = unsigned short;
48
49 drwav wav;
50 if (length == 0) {
51 #ifndef TKLB_NO_STDIO
52 if (!drwav_init_file(&wav, path, &drwaveCallbacks)) {
53 return false;
54 }
55 #else
56 return false;
57 #endif
58 } else {
59 if (!drwav_init_memory(&wav, path, length, &drwaveCallbacks)) {
60 return false;
61 }
62 }
63 constexpr Size chunkSize = 128;
64 Size read = 0;
65 HeapBuffer<float> chunkBuffer;
66 chunkBuffer.resize(chunkSize * wav.channels);
67
68 out.sampleRate = wav.sampleRate;
69 out.resize(Size(wav.totalPCMFrameCount), Size(wav.channels));
70
71 while (read < wav.totalPCMFrameCount) {
72 auto got = Size(drwav_read_pcm_frames_f32(&wav, chunkSize, chunkBuffer.data()));
73 out.setFromInterleaved(chunkBuffer.data(), got, uchar(wav.channels), 0, read);
74 read += got;
75 }
76
77 if (read == 0) {
78 return false;
79 }
80
81 out.setValidSize(read);
82 drwav_uninit(&wav);
83 return true;
84 }
void * drwaveMalloc(size_t size, void *userData)
Definition: TWaveFile.cpp:6
void drwaveFree(void *ptr, void *userData)
Definition: TWaveFile.cpp:10
unsigned int Size
How the elements are addressed in the heapbuffer.
Definition: vae.hpp:33
Here is the call graph for this function:

◆ write()

template<typename T , class Buffer = AudioBufferTpl<T>>
bool tklb::wave::write ( const Buffer &  in,
const char *  path,
const WaveOptions &&  options = {},
HeapBuffer< char > *  out = nullptr 
)

Write audiobuffer to file or memory.

Definition at line 114 of file TWaveFile.hpp.

117 {},
118 HeapBuffer<char>* out = nullptr
119 ) {
120 drwav_allocation_callbacks drwaveCallbacks {
121 nullptr, // No userdata
123 nullptr, // TODO tklb test and add the realloc
125 };
126 drwav wav;
127
128 using Size = typename Buffer::Size;
129
130 drwav_data_format droptions;
131 TKLB_ASSERT(in.sampleRate != 0) // Set a samplerate
132 droptions.sampleRate = in.sampleRate;
133 droptions.channels = in.channels();
134 droptions.bitsPerSample = options.bitsPerSample;
135 droptions.format = options.format;
136 droptions.container = drwav_container(options.container);
137
138 size_t outSize = 0;
139 void* memory = nullptr;
140 if (out == nullptr) { // write to file
141 #ifndef TKLB_NO_STDIO
142 if (!drwav_init_file_write(&wav, path, &droptions, &drwaveCallbacks)) {
143 return false;
144 }
145 #else
146 return false;
147 #endif
148 } else {
149 if (!drwav_init_memory_write(&wav, &memory, &outSize, &droptions, &drwaveCallbacks)) {
150 return false;
151 }
152 }
153
154 Size written = 0;
155 constexpr Size chunkSize = 128;
156 const Size frames = in.validSize();
157
158 switch (options.format) {
159 case WaveOptions::Format::IEEE_FLOAT:
160 {
161 // TODO benchmark against aligned heapbuffer
162 auto interleaved = new float[chunkSize * in.channels()];
163 while (written < frames) {
164 auto remaining = in.putInterleaved(interleaved, chunkSize, written);
165 written += Size(drwav_write_pcm_frames(&wav, remaining, interleaved));
166 }
167 delete[] interleaved;
168 }
169 break;
170 case WaveOptions::Format::PCM:
171 {
172 // TODO benchmark against aligned heapbuffer
173 auto interleaved = new short[chunkSize * in.channels()];
174 while (written < frames) {
175 auto read = in.putInterleaved(interleaved, chunkSize, written);
176 written += Size(drwav_write_pcm_frames(&wav, read, interleaved));
177 }
178 delete[] interleaved;
179 }
180 break;
181 default:
182 TKLB_ASSERT(false) return false;
183 }
184
185 drwav_uninit(&wav);
186
187 if (out != nullptr) {
188 out->set(reinterpret_cast<char*>(memory), Size(outSize));
189 }
190
191 return true;
192 }
#define TKLB_ASSERT(condition)
Wrap assertions.
Definition: TAssert.h:18
bool set(const HeapBuffer< T, Alignment2, Allocator2, Size2 > &source)
Resizes and copies the contents of the source Buffer This will do a memory::copy,so none of the objec...