-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathIO.cpp
executable file
·119 lines (95 loc) · 3.08 KB
/
IO.cpp
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
#include <StftPitchShift/IO.h>
#include <dr_libs/dr_wav.h>
using namespace stftpitchshift;
void IO::read(const std::string& path, std::vector<float>& data, double& samplerate, size_t& channels)
{
struct
{
drwav_uint32 channels;
drwav_uint32 samplerate;
drwav_uint64 samples;
}
wav;
float* rawdata = drwav_open_file_and_read_pcm_frames_f32(
path.c_str(), &wav.channels, &wav.samplerate, &wav.samples, nullptr);
if (rawdata == nullptr)
{
throw std::runtime_error(
"Unable to read \"" + path + "\"!");
}
if (wav.channels == 1)
{
data.assign(rawdata, rawdata + wav.samples);
}
else if (wav.channels == 2)
{
data.resize(wav.samples * wav.channels);
split(data.size(), rawdata, data.data());
}
else
{
drwav_free(rawdata, nullptr);
throw std::runtime_error(
"Unsupported number of channels " + std::to_string(wav.channels) + " in \"" + path + "\"!");
}
drwav_free(rawdata, nullptr);
samplerate = static_cast<double>(wav.samplerate);
channels = static_cast<size_t>(wav.channels);
}
void IO::read(const std::string& path, std::vector<double>& data, double& samplerate, size_t& channels)
{
std::vector<float> buffer;
read(path, buffer, samplerate, channels);
data.resize(buffer.size());
std::transform(buffer.begin(), buffer.end(), data.begin(),
[](float value) { return static_cast<double>(value); });
}
void IO::write(const std::string& path, const std::vector<float>& data, const double samplerate, const size_t channels)
{
std::vector<drwav_int32> rawdata(data.size());
if (channels == 1)
{
drwav_f32_to_s32(rawdata.data(), data.data(), data.size());
}
else if (channels == 2)
{
std::vector<float> buffer(data.size());
merge(data.size(), data.data(), buffer.data());
drwav_f32_to_s32(rawdata.data(), buffer.data(), buffer.size());
}
else
{
throw std::runtime_error(
"Unsupported number of channels " + std::to_string(channels) + " for \"" + path + "\"!");
}
drwav wav;
drwav_data_format format;
format.container = drwav_container_riff;
format.format = DR_WAVE_FORMAT_PCM;
format.bitsPerSample = sizeof(drwav_uint32) * 8;
format.channels = static_cast<drwav_uint32>(channels);
format.sampleRate = static_cast<drwav_uint32>(samplerate);
const drwav_uint64 samples = rawdata.size() / channels;
if (drwav_init_file_write(&wav, path.c_str(), &format, nullptr) != DRWAV_TRUE)
{
throw std::runtime_error(
"Unable to write \"" + path + "\"!");
}
if (drwav_write_pcm_frames(&wav, samples, rawdata.data()) != samples)
{
throw std::runtime_error(
"Unable to write \"" + path + "\"!");
}
if (drwav_uninit(&wav) != DRWAV_SUCCESS)
{
throw std::runtime_error(
"Unable to write \"" + path + "\"!");
}
}
void IO::write(const std::string& path, const std::vector<double>& data, const double samplerate, const size_t channels)
{
std::vector<float> buffer(data.size());
std::transform(data.begin(), data.end(), buffer.begin(),
[](double value) { return static_cast<float>(value); });
write(path, buffer, samplerate, channels);
}