1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
/**
* Copyright (c) 2015-2022, Martin Roth (mhroth@gmail.com)
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _TINY_WAV_
#define _TINY_WAV_
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
// http://soundfile.sapp.org/doc/WaveFormat/
typedef struct TinyWavHeader {
uint32_t ChunkID;
uint32_t ChunkSize;
uint32_t Format;
uint32_t Subchunk1ID;
uint32_t Subchunk1Size;
uint16_t AudioFormat;
uint16_t NumChannels;
uint32_t SampleRate;
uint32_t ByteRate;
uint16_t BlockAlign;
uint16_t BitsPerSample;
uint32_t Subchunk2ID;
uint32_t Subchunk2Size;
} TinyWavHeader;
typedef enum TinyWavChannelFormat {
TW_INTERLEAVED, // channel buffer is interleaved e.g. [LRLRLRLR]
TW_INLINE, // channel buffer is inlined e.g. [LLLLRRRR]
TW_SPLIT // channel buffer is split e.g. [[LLLL],[RRRR]]
} TinyWavChannelFormat;
typedef enum TinyWavSampleFormat {
TW_INT16 = 2, // two byte signed integer
TW_FLOAT32 = 4 // four byte IEEE float
} TinyWavSampleFormat;
typedef struct TinyWav {
FILE *f;
TinyWavHeader h;
int16_t numChannels;
int32_t numFramesInHeader; ///< number of samples per channel declared in wav header (only populated when reading)
uint32_t totalFramesReadWritten; ///< total numSamples per channel which have been read or written
TinyWavChannelFormat chanFmt;
TinyWavSampleFormat sampFmt;
} TinyWav;
/**
* Open a file for writing.
*
* @param numChannels The number of channels to write.
* @param samplerate The sample rate of the audio.
* @param sampFmt The sample format (e.g. 16-bit integer or 32-bit float) to be used in the file.
* @param chanFmt The channel format (how the channel data is layed out in memory)
* @param path The path of the file to write to. The file will be overwritten.
*
* @return The error code. Zero if no error.
*/
int tinywav_open_write(TinyWav *tw,
int16_t numChannels, int32_t samplerate,
TinyWavSampleFormat sampFmt, TinyWavChannelFormat chanFmt,
const char *path);
/**
* Open a file for reading.
*
* @param path The path of the file to read.
* @param chanFmt The channel format (how the channel data is layed out in memory) when read.
*
* @return The error code. Zero if no error.
*/
int tinywav_open_read(TinyWav *tw, const char *path, TinyWavChannelFormat chanFmt);
/**
* Read sample data from the file.
*
* @param tw The TinyWav structure which has already been prepared.
* @param data A pointer to the data structure to read to. This data is expected to have the
* correct memory layout to match the specifications given in tinywav_open_read().
* @param len The number of frames to read.
*
* @return The number of frames (samples per channel) read from file.
*/
int tinywav_read_f(TinyWav *tw, void *data, int len);
/** Stop reading the file. The Tinywav struct is now invalid. */
void tinywav_close_read(TinyWav *tw);
/**
* Write sample data to file.
*
* @param tw The TinyWav structure which has already been prepared.
* @param f A pointer to the sample data to write.
* @param len The number of frames to write.
*
* @return The number of frames (samples per channel) written to file.
*/
int tinywav_write_f(TinyWav *tw, void *f, int len);
/** Stop writing to the file. The Tinywav struct is now invalid. */
void tinywav_close_write(TinyWav *tw);
/** Returns true if the Tinywav struct is available to write or write. False otherwise. */
bool tinywav_isOpen(TinyWav *tw);
#ifdef __cplusplus
}
#endif
#endif // _TINY_WAV_
|