Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Written by Ilari.
- * Purpose: fix crackling sounds in Dolphin wav dumps.
- * Usage: "gapfix infile.wav outfile wav"
- * Note: compile with 44-byte wav header in mind (that Dolphin uses).
- */
- #include <iostream>
- #include <cstdint>
- #include <fstream>
- #define BLOCKSAMPLES 8
- const double factor = 1000;
- const unsigned HEADERSIZE = 44; // Adjust this!
- const unsigned blocktype_nonzero = 0;
- const unsigned blocktype_zero = 1;
- const unsigned blocktype_gap = 2;
- const unsigned blocktype_eof = 3;
- const unsigned blocktype_sof = 4;
- struct sample
- {
- sample() { l = 0; r = 0; }
- void read(char* buf)
- {
- l = ((unsigned char*)buf)[0] | ((unsigned short)((unsigned char*)buf)[1] << 8);
- r = ((unsigned char*)buf)[2] | ((unsigned short)((unsigned char*)buf)[3] << 8);
- }
- void write(char* buf)
- {
- buf[0] = l;
- buf[1] = l >> 8;
- buf[2] = r;
- buf[3] = r >> 8;
- }
- bool iszero() { return (l == 0 && r == 0); }
- private:
- short l, r;
- };
- struct block
- {
- unsigned type;
- sample samples[BLOCKSAMPLES];
- };
- block readblock(std::istream& s)
- {
- block b;
- char buffer[4 * BLOCKSAMPLES];
- s.read(buffer, 4 * BLOCKSAMPLES);
- if(!s) {
- b.type = blocktype_eof;
- return b;
- }
- bool nz = false;
- for(unsigned i = 0; i < BLOCKSAMPLES; i++) {
- b.samples[i].read(buffer + 4 * i);
- nz = nz || !b.samples[i].iszero();
- }
- b.type = nz ? blocktype_nonzero : blocktype_zero;
- return b;
- }
- struct block_filter
- {
- block_filter(std::istream& _s)
- : s(_s)
- {
- r[0].type = blocktype_sof;
- r[1] = readblock(s);
- r[2] = readblock(s);
- ptr = 1;
- }
- block get()
- {
- block b = r[ptr];
- //If zero block is surrounded by nonzero blocks, it becomes gap block.
- unsigned ptrp = ptr - 1;
- unsigned ptrn = ptr + 1;
- if(ptrp > 2) ptrp = 2;
- if(ptrn > 2) ptrn = 0;
- if(r[ptrp].type == blocktype_nonzero && r[ptr].type == blocktype_zero && r[ptrn].type ==
- blocktype_nonzero)
- b.type = blocktype_gap;
- ptr = ptrn;
- r[ptrp] = readblock(s);
- return b;
- }
- private:
- std::istream& s;
- block r[3];
- unsigned ptr;
- };
- int main(int argc, char** argv)
- {
- char header[HEADERSIZE];
- std::ifstream in(argv[1], std::ios::binary);
- std::ofstream out(argv[2], std::ios::binary);
- in.read(header, HEADERSIZE);
- out.write(header, HEADERSIZE);
- block_filter bf(in);
- uint64_t lag = 0;
- uint64_t maxlag = 0;
- uint64_t bytes = 0;
- double counter = 0;
- uint64_t gaps = 0;
- while(true) {
- block b = bf.get();
- if(b.type == blocktype_eof)
- break;
- else if(b.type == blocktype_gap) {
- gaps++;
- lag += BLOCKSAMPLES;
- if(lag > maxlag)
- maxlag = lag;
- } else {
- char buffer2[8 * BLOCKSAMPLES];
- size_t buf2use = 0;
- //Block to process.
- for(unsigned i = 0; i < BLOCKSAMPLES; i++) {
- double increment = lag / factor;
- counter += increment;
- if(counter > 1 && lag) {
- b.samples[i].write(buffer2 + buf2use);
- b.samples[i].write(buffer2 + buf2use + 4);
- buf2use += 8;
- counter--;
- lag--;
- } else {
- b.samples[i].write(buffer2 + buf2use);
- buf2use += 4;
- }
- }
- out.write(buffer2, buf2use);
- }
- bytes += 4 * BLOCKSAMPLES;
- if(bytes % 1048576 == 0) {
- std::cout << (bytes >> 20) << "MB lag=" << lag << "(" << maxlag << ")\n"
- << std::flush;
- }
- }
- char buffer3[4] = {0};
- for(uint64_t i = 0; i < lag; i++)
- out.write(buffer3, 4);
- std::cout << (bytes >> 20) << "MB lag=" << lag << "(" << maxlag << ")\n" << std::flush;
- std::cout << std::endl << "Found " << gaps << " gaps." << std::endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement