summaryrefslogtreecommitdiff
path: root/os2eindopdracht/main.cpp
blob: b4516526637670065a7132edb21b285407a3edb7 (plain)
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
#include <cstdio>
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <semaphore>
#include <thread>

#include "Arguments.h"
#include "SampleStream.h"
#include "SampleBlock.h"
#include "FilterWorker.h"

using std::vector;
using std::counting_semaphore;
using std::thread;
using std::ref;

#define SAMPLE_BLOCK_SIZE 1024

int main(int argc, char** argv) {
	// parse arguments
	Arguments args(argc, argv);

	// read input file to std::string
	std::fstream file_input(args.file_input, std::ios::in | std::ios::binary);
	std::stringstream file_input_content;
	file_input_content << file_input.rdbuf();
	file_input.close();

	// convert std::string to vector<int16_t>
	SampleStream input(file_input_content.str());
	// split into 1024-sample blocks
	vector<SampleBlock> input_blocks = input.split(SAMPLE_BLOCK_SIZE);

	// do the same for output stream (input stream is later used as reference but not mutated)
	SampleStream output(file_input_content.str());
	vector<SampleBlock> output_blocks = output.split(SAMPLE_BLOCK_SIZE);

	// c++20 semaphore for limiting active thread count
	counting_semaphore semaphore(args.max_threads);
	// thread array
	vector<thread> threads;
	for (size_t i = 0; i < input_blocks.size(); i++) {
		semaphore.acquire(); // wait until less than args.max_threads threads are running
		// create thread
		threads.push_back(thread([&args, &semaphore](SampleBlock& input, SampleBlock& output) {
			// apply filter to output
			FilterWorker(input, output).filter(args.bass, args.treble);
			// allow new thread to be created
			semaphore.release();
		}, ref(input_blocks[i]), ref(output_blocks[i])));
	}

	// make sure all threads are done
	for (thread& t : threads) t.join();

	// write pcm stream to output file
	std::fstream file_output(args.file_output, std::ios::out | std::ios::binary);
	std::string edited_stream = output.save();
	file_output.write(edited_stream.c_str(), edited_stream.size());
	file_output.close();

	return 0;
}