-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathFileUpsampler.cpp
More file actions
111 lines (86 loc) · 3.05 KB
/
FileUpsampler.cpp
File metadata and controls
111 lines (86 loc) · 3.05 KB
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
/*
File Upsampler
This program takes a file with a digital audio stream and produces a file with the same stream having a doubled sampling frequency
Copyright © 2018 Lev Minkovsky
This software is licensed under the MIT License (MIT).
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "FileUpsampler.h"
#include <chrono>
#include <iostream>
#include "libsndfile\include\sndfile.h"
using std::cout;
const size_t TABLE_WIDTH = 3200; //width of a filter table
const double ALPHA = 9; //parameter of a Kaiser function
int main(int argc, char ** argv)
{
//create an appropriate Keiser window filter
static CFilter<TABLE_WIDTH> KEISER_FILTER{ ALPHA };
if (argc != 3)
{
cout << "Usage: SrDoubler <input file> <output file>\n";
return 0;
}
using SRDoublerType = SRDoubler<double, 2, TABLE_WIDTH>;
using SampleFrame = SRDoublerType::SampleFrame;
using FrameSpan = SRDoublerType::FrameSpan;
using FrameVector = SRDoublerType::FrameVector;
//open input file
SF_INFO info_in{ 0 };
SNDFILE * in = sf_open(argv[1], SFM_READ, &info_in);
if (!in)
{
cout << "Failure to open an input file\n";
return -1;
}
if (info_in.channels != 2)
{
sf_close(in);
cout << "SRDoubler can process only stereo files\n";
return -1;
}
std::vector<SampleFrame> input{ static_cast<size_t>(info_in.frames) };
sf_count_t rc = sf_readf_double(in, &input[0][0], info_in.frames);
if (rc != info_in.frames)
{
sf_close(in);
cout << "Failure to read all the expected audio data\n";
return -1;
}
cout << info_in.frames << " audio frames read\n";
FrameSpan sine_wave_span{ input };
SRDoublerType doubler{ sine_wave_span ,KEISER_FILTER };
cout << "About to start upsampling...\n";
using namespace std::chrono;
steady_clock clock;
auto t0 = clock.now();
//upsample the input
FrameVector upsampled_signal = doubler.Run();
auto t1 = clock.now();
auto time_diff = t1 - t0;
using milliseconds_type = duration<double, std::milli>;
cout << "Upsampling took " << duration_cast<milliseconds_type>(time_diff).count() << " milliseconds\n";
//save the upsampled signal into an output file
SF_INFO info_out{ info_in };
info_out.samplerate *= 2;
SNDFILE * out = sf_open(argv[2], SFM_WRITE, &info_out);
info_out.frames = info_in.frames * 2;
rc = sf_writef_double(out, &upsampled_signal[0][0], info_out.frames);
sf_close(out);
if (rc != info_out.frames)
{
cout << "Failure to save upsampled data\n";
return -1;
}
else
{
cout << info_out.frames << " audio frames written\n";
}
return 0;
}