remove boilerplate, modify example waves.txt, rewrite parser.

This commit is contained in:
Maksymilian Wilczyński committed 2025-04-06 20:02:17 +02:00
1 parent 9bc043a159
commit f91c95aa98
2 files changed
+88 -52

No files matched your search

+82 -47
View File
@@ -61,68 +61,122 @@ bool loadWaveParams(const std::string& filename, std::vector<Wave>& waves, int&
std::string line;
bool inCommentBlock = false;
while (std::getline(file, line)) {
// Remove C-style comments
// Handle multiline /* comments */
if (inCommentBlock) {
size_t endComment = line.find("*/");
if (endComment != std::string::npos) {
size_t end = line.find("*/");
if (end != std::string::npos) {
inCommentBlock = false;
line = line.substr(endComment + 2); // Remaining part of the line after the comment
line = line.substr(end + 2);
}
else {
continue; // Skip entire line if still in a comment block
continue;
}
}
size_t startComment = line.find("/*");
while (startComment != std::string::npos) {
size_t endComment = line.find("*/", startComment + 2);
if (endComment != std::string::npos) {
line.erase(startComment, endComment - startComment + 2); // Remove the comment
startComment = line.find("/*"); // Look for another comment
while (true) {
size_t start = line.find("/*");
if (start != std::string::npos) {
size_t end = line.find("*/", start + 2);
if (end != std::string::npos) {
line.erase(start, end - start + 2); // Remove /* ... */
}
else {
line = line.substr(0, start); // Cut off everything after /*
inCommentBlock = true;
line = line.substr(0, startComment); // Remove everything after /* till end of line
break;
}
}
else {
break;
}
}
// Strip whitespace
// Trim leading whitespace
line.erase(0, line.find_first_not_of(" \t\r\n"));
if (line.empty() || line[0] == '#') continue;
// Check if the line defines the total duration
if (line.find("TOTAL_DURATION") != std::string::npos) {
size_t startPos = line.find("(") + 1;
size_t endPos = line.find(")");
totalDuration = std::stoi(line.substr(startPos, endPos - startPos));
// Handle TOTAL_DURATION
if (line.rfind("TOTAL_DURATION", 0) == 0) {
std::istringstream durationStream(line);
std::string keyword;
durationStream >> keyword >> totalDuration;
continue;
}
// Initialize variables for waveform properties
std::istringstream ss(line);
std::string waveType;
int start_ms, duration_ms, frequency;
ss >> waveType;
if (waveType.empty()) continue;
Wave wave;
wave.type = SINE;
if (waveType == "SINE") wave.type = SINE;
else if (waveType == "SAWTOOTH") wave.type = SAWTOOTH;
else if (waveType == "SQUARE") wave.type = SQUARE;
else if (waveType == "TRIANGLE") wave.type = TRIANGLE;
else if (waveType == "NOISE") wave.type = NOISE;
else if (waveType == "DPCM") wave.type = DPCM;
else {
std::cout << "Unknown waveform type: " << waveType << std::endl;
continue;
}
int start_ms, duration_ms;
ss >> start_ms >> duration_ms;
wave.start_ms = start_ms;
wave.duration_ms = duration_ms;
if (wave.type == DPCM) {
std::string token;
while (ss >> token && token == "/*") {
while (ss >> token && token != "*/");
}
if (token.empty()) {
std::cout << "Missing sample path for DPCM at " << start_ms << "ms\n";
continue;
}
// Optional volume
if (!(ss >> wave.volume)) {
wave.volume = 1.0;
}
wave.samplePath = token;
wave.frequency = 0;
wave.dutyCycle = 0.5;
wave.sweepDepth = 0.0;
wave.sweepRate = 0.0;
wave.attack = 0.01;
wave.decay = 0.2;
if (!loadWavFile(wave.samplePath, wave.sampleData)) {
std::cout << "Failed to load sample: " << wave.samplePath << std::endl;
}
waves.push_back(wave);
continue;
}
// Standard wave parameters
double volume = 1.0;
double duty = 0.5;
double sweepDepth = 0.0, sweepRate = 0.0;
double attack = 0.01, decay = 0.2;
int frequency;
// Read the basic wave parameters
ss >> waveType >> start_ms >> duration_ms >> frequency >> volume;
// Set default values if optional parameters are missing
ss >> frequency;
ss >> volume;
if (!(ss >> duty)) duty = 0.5;
if (!(ss >> sweepDepth)) sweepDepth = 0.0;
if (!(ss >> sweepRate)) sweepRate = 0.0;
if (!(ss >> attack)) attack = 0.01;
if (!(ss >> decay)) decay = 0.2;
// Create a new Wave object and set its properties
Wave wave;
wave.start_ms = start_ms;
wave.duration_ms = duration_ms;
wave.frequency = frequency;
wave.volume = volume;
wave.dutyCycle = duty;
@@ -131,25 +185,6 @@ bool loadWaveParams(const std::string& filename, std::vector<Wave>& waves, int&
wave.attack = attack;
wave.decay = decay;
// Determine wave type and set corresponding enum
if (waveType == "SINE") wave.type = SINE;
else if (waveType == "SAWTOOTH") wave.type = SAWTOOTH;
else if (waveType == "SQUARE") wave.type = SQUARE;
else if (waveType == "TRIANGLE") wave.type = TRIANGLE;
else if (waveType == "NOISE") wave.type = NOISE;
else if (waveType == "DPCM") {
wave.type = DPCM;
ss >> wave.samplePath; // Read sample file path for DPCM waves
if (!loadWavFile(wave.samplePath, wave.sampleData)) {
std::cout << "Failed to load sample: " << wave.samplePath << std::endl;
}
}
else {
std::cout << "Unknown waveform type: " << waveType << std::endl;
continue; // Skip unknown waveform types
}
// Add the wave to the vector
waves.push_back(wave);
}
+6 -5
View File
@@ -1,6 +1,7 @@
TOTAL_DURATION(3000) // 3 seconds total
TOTAL_DURATION 4500 // extended to fit all waves cleanly
SINE 0 1000 440 1.0 0 3 5 0.05 0.3 // sine with slow vibrato and long decay
SQUARE 500 1000 330 0.7 0.25 6 4 0.01 0.2 // square with duty cycle and sweep
NOISE 1500 400 0 0.8 0 0 0 0.02 0.1 // noise burst
DPCM 2000 800 /* boilerplate */ 0 0 0 0 0 0 1.0 snare.wav
SINE 0 500 440 1.0 0 3 5 0.05 0.3 // sine with slow vibrato and long decay
TRIANGLE 1000 500 550 0.9 0.5 2 3 0.02 0.25 // triangle with sweep
SQUARE 2000 500 330 0.7 0.25 6 4 0.01 0.2 // square with duty cycle and sweep
NOISE 3000 300 0 0.8 0 0 0 0.02 0.1 // noise burst
DPCM 3900 500 snare.wav 1.0 // dpcm sample 1.0 volume