Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/WaveEdit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ float *loadAudio(const char *filename, int *length);
std::string stringf(const char *format, ...);
/** Truncates a string if needed, inserting ellipses (...), to be no greater than `maxLen` characters */
void ellipsize(char *str, int maxLen);
/** Writes a 32-bit integer in little endian order */
size_t fwriteLE32(uint32_t x, FILE *f);
/** Writes a 16-bit integer in little endian order */
size_t fwriteLE16(uint16_t x, FILE *f);
/** Reads a 32-bit integer in little endian order */
size_t freadLE32(uint32_t *x, FILE *f);
/** Reads a 16-bit integer in little endian order */
size_t freadLE16(uint16_t *x, FILE *f);
unsigned char *base64_encode(const unsigned char *src, size_t len, size_t *out_len);
unsigned char *base64_decode(const unsigned char *src, size_t len, size_t *out_len);

Expand Down Expand Up @@ -198,6 +206,12 @@ struct Bank {
/** WAV file with BANK_LEN * WAVE_LEN samples */
void saveWAV(const char *filename);
void loadWAV(const char *filename);
/** WT file with BANK_LEN banks of WAVE_LEN samples each */
void saveWT(const char *filename);
void loadWT(const char *filename);
/** Automatic format determined according to file name */
void saveAuto(const char *filename);
void loadAuto(const char *filename);
/** Saves each wave to its own file in a directory */
void saveWaves(const char *dirname);
};
Expand Down
138 changes: 138 additions & 0 deletions src/bank.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
#include <string.h>
#include <sndfile.h>

#if defined(_WIN32)
#define strcasecmp _stricmp
#endif

void Bank::clear() {
// The lazy way
Expand Down Expand Up @@ -118,3 +121,138 @@ void Bank::saveWaves(const char *dirname) {
waves[b].saveWAV(filename);
}
}


void Bank::saveWT(const char *filename)
{
FILE *f = fopen(filename, "wb");
if (!f)
return;

fputs("vawt", f);
fwriteLE32(WAVE_LEN, f);
fwriteLE16(BANK_LEN, f);
fwriteLE16(0, f);

for (int i = 0; i < BANK_LEN; i++) {
for (int j = 0; j < WAVE_LEN; j++) {
union { uint32_t i; float f; } u;
u.f = waves[i].postSamples[j];
fwriteLE32(u.i, f);
}
}

fclose(f);
}


void Bank::loadWT(const char *filename)
{
FILE *f = fopen(filename, "rb");
if (!f)
return;

char magic[4];
memset(magic, 0, 4);
fread(magic, 4, 1, f);

if (memcmp(magic, "vawt", 4) != 0) {
fclose(f);
return;
}

uint32_t waveLen = 0;
uint16_t fileBankLen = 0;
uint16_t flags = 0;

freadLE32(&waveLen, f);
freadLE16(&fileBankLen, f);
freadLE16(&flags, f);

if (waveLen > 1024) {
fclose(f);
return;
}

uint32_t bankLen = fileBankLen;
if (bankLen > BANK_LEN)
bankLen = BANK_LEN;

clear();

std::vector<float> rawSamples(waveLen * bankLen);

if (flags & 4) {
for (uint32_t i = 0; i < waveLen * bankLen; ++i) {
int16_t sample = 0;
freadLE16((uint16_t *)&sample, f);
rawSamples[i] = sample / 32768.0f;
}
}
else {
for (uint32_t i = 0; i < waveLen * bankLen; ++i) {
union { uint32_t i; float f; } u;
u.i = 0;
freadLE32(&u.i, f);
rawSamples[i] = u.f;
}
}

for (uint32_t i = 0; i < bankLen; i++) {
const float *src = &rawSamples[waveLen * i];
float *dst = waves[i].samples;
if (waveLen == WAVE_LEN)
memcpy(dst, src, WAVE_LEN * sizeof(float));
else
resample(src, waveLen, dst, WAVE_LEN, (double)WAVE_LEN/waveLen);
waves[i].commitSamples();
}

fclose(f);
}


enum BankFileFormat {
BANK_FORMAT_WAV,
BANK_FORMAT_WT,
};


static int getFormatByFilename(const char *filename)
{
size_t len = strlen(filename);
if (len > 4 && strcasecmp(filename + len - 4, ".wav") == 0)
return BANK_FORMAT_WAV;
else if (len > 3 && strcasecmp(filename + len - 3, ".wt") == 0)
return BANK_FORMAT_WT;
else
return -1;
}


void Bank::saveAuto(const char *filename)
{
switch (getFormatByFilename(filename)) {
default:
case BANK_FORMAT_WAV:
saveWAV(filename);
break;
case BANK_FORMAT_WT:
saveWT(filename);
break;
}
}


void Bank::loadAuto(const char *filename)
{
switch (getFormatByFilename(filename)) {
default:
case BANK_FORMAT_WAV:
loadWAV(filename);
break;
case BANK_FORMAT_WT:
loadWT(filename);
break;
}
}
6 changes: 3 additions & 3 deletions src/ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ static void menuOpenBank() {
char *path = osdialog_file(OSDIALOG_OPEN, dir, NULL, NULL);
if (path) {
showCurrentBankPage();
currentBank.loadWAV(path);
currentBank.loadAuto(path);
snprintf(lastFilename, sizeof(lastFilename), "%s", path);
historyPush();
free(path);
Expand All @@ -170,7 +170,7 @@ static void menuSaveBankAs() {
char *dir = getLastDir();
char *path = osdialog_file(OSDIALOG_SAVE, dir, "Untitled.wav", NULL);
if (path) {
currentBank.saveWAV(path);
currentBank.saveAuto(path);
snprintf(lastFilename, sizeof(lastFilename), "%s", path);
free(path);
}
Expand All @@ -179,7 +179,7 @@ static void menuSaveBankAs() {

static void menuSaveBank() {
if (lastFilename[0] != '\0')
currentBank.saveWAV(lastFilename);
currentBank.saveAuto(lastFilename);
else
menuSaveBankAs();
}
Expand Down
42 changes: 42 additions & 0 deletions src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <string.h>
#include <sndfile.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>

#if defined(_WIN32)
#include <windows.h>
Expand Down Expand Up @@ -90,6 +92,46 @@ void ellipsize(char *str, int maxLen) {
}


size_t fwriteLE32(uint32_t x, FILE *f)
{
uint8_t b[4];
b[0] = x & 0xff;
b[1] = (x >> 8) & 0xff;
b[2] = (x >> 16) & 0xff;
b[3] = x >> 24;
return fwrite(b, 4, 1, f);
}


size_t fwriteLE16(uint16_t x, FILE *f)
{
uint8_t b[2];
b[0] = x & 0xff;
b[1] = x >> 8;
return fwrite(b, 2, 1, f);
}


size_t freadLE32(uint32_t *x, FILE *f)
{
uint8_t b[4];
if (fread(b, 4, 1, f) != 1)
return 0;
*x = b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
return 1;
}


size_t freadLE16(uint16_t *x, FILE *f)
{
uint8_t b[2];
if (fread(b, 2, 1, f) != 1)
return 0;
*x = b[0] | (b[1] << 8);
return 1;
}




/* This base64 implementation:
Expand Down