Last active
February 2, 2019 17:15
-
-
Save autch/1e7b2e47cb4d2f6d9794a20b1376bc06 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <fstream> | |
| #include <string> | |
| #include <algorithm> | |
| #include <iterator> | |
| int main(int ac, char** av) | |
| { | |
| if(ac < 2) { | |
| std::cerr << "Usage: " << *av << " *.ogg..." << std::endl; | |
| return 1; | |
| } | |
| for(char** p = av + 1; *p; p++) { | |
| std::string filename(*p); | |
| if(filename.rfind(".out.ogg") != filename.npos) | |
| continue; | |
| std::string out_filename(filename); | |
| out_filename.replace(out_filename.find_last_of('.'), out_filename.npos, ".out.ogg"); | |
| std::cout << filename << " => " << out_filename << " "; | |
| { | |
| std::fstream inf(filename, std::ios::in | std::ios::binary); | |
| std::fstream outf(out_filename, std::ios::out | std::ios::binary); | |
| std::istreambuf_iterator<char> inf_iter(inf), eof; | |
| std::ostreambuf_iterator<char> outf_iter(outf); | |
| std::transform(inf_iter, eof, outf_iter, | |
| [](uint8_t i) -> uint8_t { return (((i & 0x0f) << 4) | (i & 0xf0) >> 4) ^ 0x0f; }); | |
| } | |
| std::cout << std::endl; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python | |
| import glob | |
| import os.path | |
| BUFFER_SIZE = (1 << 16) | |
| for filename in glob.glob('*.ogg'): | |
| if '.out.ogg' in filename: | |
| continue | |
| with open(filename, 'rb') as inf: | |
| out_filename = os.path.splitext(filename)[0] + '.out.ogg' | |
| print(filename, "=>", out_filename) | |
| with open(out_filename, 'wb') as outf: | |
| while True: | |
| buffer = inf.read(BUFFER_SIZE) | |
| out_buf = bytes(map(lambda b: (((b & 0x0f) << 4) | (b & 0xf0) >> 4) ^ 0x0f, buffer)) | |
| outf.write(out_buf) | |
| if len(buffer) < BUFFER_SIZE: | |
| break |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <fstream> | |
| #include <string> | |
| #include <iterator> | |
| #include <algorithm> | |
| #include <vector> | |
| #include <deque> | |
| #include <thread> | |
| #include <condition_variable> | |
| template <typename T, typename MT = std::mutex> | |
| class tsqueue | |
| { | |
| private: | |
| std::deque<T> queue; | |
| MT mut; | |
| std::condition_variable cv; | |
| public: | |
| tsqueue() : queue(), mut(), cv() {} | |
| T pop() | |
| { | |
| std::unique_lock<MT> lock(mut); | |
| cv.wait(lock, [this]() { return !queue.empty(); }); | |
| T last = queue.back(); | |
| queue.pop_back(); | |
| return last; | |
| } | |
| void push(T item) | |
| { | |
| { | |
| std::lock_guard<MT> lock(mut); | |
| queue.push_front(item); | |
| } | |
| cv.notify_one(); | |
| } | |
| }; | |
| void thread_func(int n, tsqueue<std::string> &q) | |
| { | |
| std::string filename; | |
| while ((filename = q.pop()).length() > 0) | |
| { | |
| std::string out_filename(filename); | |
| out_filename.replace(out_filename.find_last_of('.'), out_filename.npos, ".out.ogg"); | |
| std::cout << filename << " => " << out_filename << " " << std::endl; | |
| { | |
| std::ifstream inf(filename, std::ios::binary); | |
| std::ofstream outf(out_filename, std::ios::binary); | |
| std::istreambuf_iterator<char> inf_iter(inf), eof; | |
| std::ostreambuf_iterator<char> outf_iter(outf); | |
| std::transform(inf_iter, eof, outf_iter, | |
| [](uint8_t i) -> uint8_t { return (((i & 0x0f) << 4) | (i & 0xf0) >> 4) ^ 0x0f; }); | |
| } | |
| } | |
| } | |
| int main(int ac, char **av) | |
| { | |
| if (ac < 2) | |
| { | |
| std::cerr << "Usage: " << *av << " *.ogg..." << std::endl; | |
| return 1; | |
| } | |
| tsqueue<std::string> queue; | |
| std::vector<std::thread> threads; | |
| int ncpus = std::thread::hardware_concurrency(); | |
| for (int i = 0; i < ncpus; i++) | |
| { | |
| threads.emplace_back(thread_func, i, std::ref(queue)); | |
| } | |
| std::cout << "Running " << ncpus << " threads in parallel" << std::endl; | |
| for (char **p = av + 1; *p; p++) | |
| { | |
| std::string filename(*p); | |
| if (filename.rfind(".out.ogg") != filename.npos) | |
| continue; | |
| queue.push(filename); | |
| } | |
| for (int i = 0; i < ncpus; i++) | |
| queue.push(""); | |
| for (int i = 0; i < ncpus; i++) | |
| threads[i].join(); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment