This repository was archived by the owner on Apr 16, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
124 lines (108 loc) · 5.11 KB
/
main.cpp
File metadata and controls
124 lines (108 loc) · 5.11 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
112
113
114
115
116
117
118
119
120
121
122
123
124
//
// main.cpp - the main file for this program.
// Variable Delay Line (VDL) Project
//
// Created by Alex Sedman on 12/01/2023.
//
// The purpose of this program is to provide a way to generate new mono, 16-bit, 20 second WAVs with the implementation of variable delays to create Doppler shift, using various-order interpolation techniques. It is a closed project, thus does not require as much debugging.
// Furthermore, I've chosen to use a few shortcuts here - though having a lot of void functions and duplicate code is generally bad practice, considering that this code is a quick solution to produce various WAVs, the structure here will suffice.
// v2.2 refactor
#include <iostream>
#include <chrono>
#include <string>
#include <fstream>
#include <cstdint>
#include <algorithm>
#include <cmath>
#include "commands.hpp"
#include "interpolations.hpp"
int main() {
// Classes
commands cmd;
interpolate filter;
// Variables
std::string input, outputName;
const char* filePath;
while (true) {
input = cmd.mainMenu(input);
// Quit
if (input == "-quit") {
std::cout << "\nQuitting...\n" << std::endl;
return 0; // Quits program.
}
// fopen()
filePath = input.c_str(); // Sets the file path to the user input.
FILE* wavFile = fopen(filePath, "rb"); // Attempts to open the inputted file.
// Throw fopen() error
if (!wavFile) {
std::cout << "\nERROR: File can't be read/invalid input.\n" << std::endl;
continue; // If the input is invalid (i.e. 'fopen' returns a null pointer), then this error is thrown and the loop is skipped.
}
// File read
cmd.read(wavFile);
// Throw header info error
if (wav_hdr.numChannels != 1 || wav_hdr.bitsPerSample != 16) {
std::cout << "\nERROR: File is not a WAV, or is not mono/16-bit.\n" << std::endl;
continue; // If the file is stereo, throw an error:
}
// File read successful:
std::cout << "\nFile read successful.\n" << std::endl;
/*---FUNCTION SECTION---*/
/// This part of the code will contain the different forms of delay line/sample interpolation.
/// This includes a 0 to higher order interpolation solutions as well as others.
/// It also includes solutions and simulations of doppler, inspired by the STK and SAL libraries.
/// WAVs with the various different solutions will be printed to the build folder.
/// For the sake of convenience, I have separated the various interpolation methods into separate functions. This means there may be some duplicate code here, as some methods may share very similar setups, but it makes the code more readable and simpler to implement for now.
/*---INTERPOLATION---*/
for (int method = 0; method < 9; method++) {
// Clock to measure computation cost of each method.
auto clockStart = std::chrono::high_resolution_clock::now();
switch (method) {
case 0:
filter.unfiltered();
outputName = cmd.rename(input, "-1-Unfiltered.wav");
break;
case 1:
filter.zeroOrderHold();
outputName = cmd.rename(input, "-2-ZeroOrderHold.wav");
break;
case 2:
filter.nearestNeighbour();
outputName = cmd.rename(input, "-3-NearestNeighbour.wav");
break;
case 3:
filter.linear();
outputName = cmd.rename(input, "-4-Linear.wav");
break;
case 4:
filter.quadratic();
outputName = cmd.rename(input, "-5-Quadratic.wav");
break;
case 5:
filter.cubic();
outputName = cmd.rename(input, "-6-Cubic.wav");
break;
case 6:
filter.sinc();
outputName = cmd.rename(input, "-7-Sinc.wav");
break;
case 7:
filter.anchor();
outputName = cmd.rename(input, "-0-Anchor.wav");
break;
case 8:
filter.reference();
outputName = cmd.rename(input, "-8-Reference.wav");
break;
}
auto clockEnd = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(clockEnd - clockStart);
std::cout << "Time taken to generate " << outputName << ": " << duration.count() << "μs" << std::endl;
// Write and reset
cmd.write(outputName);
cmd.reset();
}
// Output read pointer information.
std::cout << "VALUES: d = " << init.dist << "; v = " << init.vel << "; a = " << init.accel << "\n\n";
}
}