v4k-git-backup/tools/mod2wav.cc

117 lines
3.7 KiB
C++

// music module to wav writer
// - rlyeh, public domain
//
// based on modplug123 by Konstanty Bialkowski - 2010
// based on modplug play ( gurkan@linuks.mine.nu www.linuks.mine.nu - Copyright (C) 2003 Gürkan Sengün)
#define MODPLUG_STATIC
#define MODPLUG_CPP
#include "3rd_modplug.hpp"
#include <stdio.h>
#include <string.h>
#include <vector>
// Tiny WAV writer: original code by jon olick, public domain
// Floating point support + pure C version by rlyeh, public domain | wtrmrkrlyeh
#include <stdio.h>
static void tinywav(FILE *fp, short numChannels, short bitsPerSample, int sampleRateHz, const void *data, int size, int is_floating) {
short bpsamp;
int length, bpsec;
fwrite("RIFF", 1, 4, fp);
length = size + 44 - 8;
fwrite(&length, 1, 4, fp);
fwrite(is_floating ? "WAVEfmt \x10\x00\x00\x00\x03\x00" : "WAVEfmt \x10\x00\x00\x00\x01\x00", 1, 14, fp);
fwrite(&numChannels, 1, 2, fp);
fwrite(&sampleRateHz, 1, 4, fp);
bpsec = numChannels * sampleRateHz * bitsPerSample/8;
fwrite(&bpsec, 1, 4, fp);
bpsamp = numChannels * bitsPerSample/8;
fwrite(&bpsamp, 1, 2, fp);
fwrite(&bitsPerSample, 1, 2, fp);
fwrite("data", 1, 4, fp);
fwrite(&size, 1, 4, fp);
fwrite(data, 1, size, fp);
}
char *read_file(char *filename, long *size) {
FILE *f = fopen(filename, "rb");
if (f) {
fseek(f, 0L, SEEK_END);
(*size) = ftell(f);
rewind(f);
char *data = (char*)malloc(*size);
if( fread(data, *size, 1, f) == 1 ) {
fclose(f);
return data;
}
free(data);
fclose(f);
}
return NULL;
}
int main(int argc, char* argv[]) {
if(argc != 3) exit(-printf("%s\n", "mod2wav infile.mod outfile.wav"));
char *filename = argv[1];
long size; char *bin = read_file(filename, &size);
if (!bin) exit(-printf("%s\n", "cannot read input file"));
ModPlug_Settings settings;
ModPlug_GetSettings(&settings);
// settings must be set before ModPlug_Load()
settings.mResamplingMode = MODPLUG_RESAMPLE_FIR; /* RESAMP */
settings.mChannels = 2; // 1 if mono
settings.mBits = 16;
settings.mFrequency = 44100;
settings.mStereoSeparation = 128;
settings.mMaxMixChannels = 256;
#if 0
settings.mFlags=MODPLUG_ENABLE_OVERSAMPLING | \
MODPLUG_ENABLE_NOISE_REDUCTION | \
MODPLUG_ENABLE_REVERB | \
MODPLUG_ENABLE_MEGABASS | \
MODPLUG_ENABLE_SURROUND;
settings.mReverbDepth = 100; // 0 - 100 [REV--DLY--]
settings.mReverbDelay = 200; // 40 - 200 ms 00-FF
settings.mSurroundDepth = 100; // 0 - 100 [SUR--DLY--]
settings.mSurroundDelay = 40; // 5 - 40 ms
settings.mBassAmount = 100; // 0 - 100 [BAS--RNG--]
settings.mBassRange = 100; // 10 - 100 hz
#endif
ModPlug_SetSettings(&settings);
ModPlugFile *f2 = ModPlug_Load(bin, size);
if (!f2) {
// free(bin); // @leak
exit(-printf("could not load %s\n", filename));
}
std::vector<unsigned char> raw;
for( int mlen = 1; mlen > 0; ) {
enum { BUF_SIZE = 4096 };
unsigned char audio_buffer[BUF_SIZE];
mlen = ModPlug_Read(f2,audio_buffer,sizeof(audio_buffer));
if( mlen > 0 ) for( int i = 0; i < mlen; ++i ) {
raw.push_back( audio_buffer[i] );
}
}
if( raw.size() ) {
FILE *fp = fopen(argv[2], "wb");
if (!fp) exit(-printf("%s\n", "cannot open output file"));
tinywav(fp, 2, 16, 44100, raw.data(), raw.size(), false /*is_floating*/);
fclose(fp);
}
puts(ModPlug_GetName(f2));
// ModPlug_Unload(f2); // @leak
// free(bin); // @leak
return raw.size() ? 0 : -1;
}