Skip to content

Commit

Permalink
Handle rounding problems with instrument buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
zzril committed Nov 18, 2024
1 parent ad32186 commit 2176352
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 22 deletions.
54 changes: 32 additions & 22 deletions src/instrument.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,19 @@

// --------

static int add_note(Instrument* instrument, Note* note, bool* done, bool* cut_off);
static int add_note(Instrument* instrument, Note* note, bool* done);
static bool is_buffer_full(Instrument* instrument);
static size_t update_granularity(Instrument* instrument, const Note* note);

// --------

static int add_note(Instrument* instrument, Note* note, bool* done, bool* cut_off) {
static int add_note(Instrument* instrument, Note* note, bool* done) {

size_t samples_to_write;
size_t remaining_buffer_space;
size_t samples_to_write;

if(instrument == NULL || note == NULL || done == NULL || cut_off == NULL) {

if(instrument == NULL || note == NULL || done == NULL) {
return ERROR_CODE_INVALID_ARGUMENT;
}

Expand All @@ -31,18 +33,20 @@ static int add_note(Instrument* instrument, Note* note, bool* done, bool* cut_of
}

*done = false;
*cut_off = false;

remaining_buffer_space = instrument->num_samples - instrument->buffer_position;
samples_to_write = Note_get_length_in_samples(note);

update_granularity(instrument, note);

if(samples_to_write > remaining_buffer_space) {
samples_to_write = remaining_buffer_space;
*cut_off = true;
}

if(samples_to_write == remaining_buffer_space) {
*done = true;
if(samples_to_write - remaining_buffer_space >= instrument->granularity / 2) {
*done = true;
return ERROR_CODE_INSTRUMENT_BUFFER_OVERFLOW;
}

samples_to_write = remaining_buffer_space;
}

if(!Note_is_rest(note)) {
Expand All @@ -51,11 +55,26 @@ static int add_note(Instrument* instrument, Note* note, bool* done, bool* cut_of

instrument->buffer_position += samples_to_write;

if(is_buffer_full(instrument)) {
*done = true;
}

return 0;
}

static bool is_buffer_full(Instrument* instrument) {
return instrument->buffer_position >= instrument->num_samples;
return instrument->buffer_position >= instrument->num_samples || instrument->num_samples - instrument->buffer_position < instrument->granularity;
}

static size_t update_granularity(Instrument* instrument, const Note* note) {

size_t note_granularity = Note_get_granularity_in_samples(note);

if(note_granularity < instrument->granularity) {
instrument->granularity = note_granularity;
}

return instrument->granularity;
}

// --------
Expand All @@ -79,6 +98,7 @@ int Instrument_init_at(Instrument* instrument, void* instrument_definition) {
void reset_buffer(Instrument* instrument) {
generate_silence(instrument->buffer, instrument->num_samples);
instrument->buffer_position = 0;
instrument->granularity = instrument->num_samples;
return;
}

Expand All @@ -100,19 +120,13 @@ int Instrument_add_notes_for_bar(Instrument* instrument, NoteProvider note_provi
int status = 0;
bool provider_done = false;
bool instrument_done = false;
bool cut_off = false;

while((status = note_provider(arg, &note, &provider_done)) == 0 && !provider_done && !instrument_done) {

int rv = add_note(instrument, &note, &instrument_done, &cut_off);

int rv = add_note(instrument, &note, &instrument_done);
if(rv != 0) {
return rv;
}

if(cut_off) {
fputs("WARNING: Instrument buffer full, cutting off note.\n", stderr);
}
}

if(status != 0) {
Expand All @@ -123,10 +137,6 @@ int Instrument_add_notes_for_bar(Instrument* instrument, NoteProvider note_provi
return ERROR_CODE_BAR_TOO_SHORT;
}

if(!is_buffer_full(instrument)) {
fputs("WARNING: Instrument buffer not completely filled, making up with silence.\n", stderr);
}

if(!provider_done) {
return ERROR_CODE_BAR_TOO_LONG;
}
Expand Down
1 change: 1 addition & 0 deletions src/instrument.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct Instrument {
float* buffer;
size_t num_samples;
size_t buffer_position;
size_t granularity;
};

// --------
Expand Down
4 changes: 4 additions & 0 deletions src/note.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,7 @@ size_t Note_get_length_in_samples(const Note* note) {
return (size_t) (Config_get_sample_frames_per_bar() * Note_get_absolute_length(note));
}

size_t Note_get_granularity_in_samples(const Note* note) {
return Note_get_length_in_samples(note);
}

1 change: 1 addition & 0 deletions src/note.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ bool Note_is_rest(const Note* note);
float Note_get_frequency(const Note* note);
float Note_get_absolute_length(const Note* note);
size_t Note_get_length_in_samples(const Note* note);
size_t Note_get_granularity_in_samples(const Note* note);

// --------
#endif
Expand Down

0 comments on commit 2176352

Please sign in to comment.