From 4c823e1980d53d52e758785eda62dd3f5c93925a Mon Sep 17 00:00:00 2001 From: Luis Michaelis Date: Fri, 3 May 2024 16:47:15 +0200 Subject: [PATCH] refactor: more cleanup --- src/Common.c | 21 ++---- src/Composer.c | 2 +- src/Synth.c | 17 ++--- src/_Internal.h | 1 - src/util/Tsf.c | 179 ++++++++++++++++++++++++++---------------------- 5 files changed, 110 insertions(+), 110 deletions(-) diff --git a/src/Common.c b/src/Common.c index d647460..6651be1 100644 --- a/src/Common.c +++ b/src/Common.c @@ -7,6 +7,7 @@ enum { DmInt_TICKS_PER_QUARTER_NOTE = 768, + DmInt_SECONDS_PER_MINUTE = 60, }; size_t max_usize(size_t a, size_t b) { @@ -37,18 +38,6 @@ int32_t clamp_s32(int32_t val, int32_t min, int32_t max) { return val; } -float clamp_f32(float val, float min, float max) { - if (val < min) { - return min; - } - - if (val > max) { - return max; - } - - return val; -} - int32_t Dm_randRange(int32_t range) { uint32_t rnd = Dm_rand() % range; return range - (int32_t) (rnd / 2); @@ -97,10 +86,10 @@ uint32_t Dm_getMeasureLength(DmTimeSignature sig) { } double Dm_getTicksPerSample(DmTimeSignature time_signature, double beats_per_minute, uint32_t sample_rate) { - uint32_t pulses_per_beat = Dm_getBeatLength(time_signature); // unit: music-time per beat - double beats_per_second = beats_per_minute / 60; // unit: 1 per second - double pulses_per_second = pulses_per_beat * beats_per_second; // unit: music-time per second - double pulses_per_sample = pulses_per_second / sample_rate; // unit: music-time per sample + uint32_t pulses_per_beat = Dm_getBeatLength(time_signature); // unit: music-time per beat + double beats_per_second = beats_per_minute / DmInt_SECONDS_PER_MINUTE; // unit: 1 per second + double pulses_per_second = pulses_per_beat * beats_per_second; // unit: music-time per second + double pulses_per_sample = pulses_per_second / sample_rate; // unit: music-time per sample return pulses_per_sample; } diff --git a/src/Composer.c b/src/Composer.c index 45709f8..404fbec 100644 --- a/src/Composer.c +++ b/src/Composer.c @@ -57,7 +57,7 @@ DmResult Dm_composeTransition(DmStyle* sty, } if (embellishment == DmEmbellishment_END_AND_INTRO) { - // Complex "extro" plus "intro" transitoon + // Complex "extro" plus "intro" transition msg.type = DmMessage_COMMAND; msg.command.command = DmCommand_END; msg.command.groove_level = 1; diff --git a/src/Synth.c b/src/Synth.c index e5f34be..a1bde22 100644 --- a/src/Synth.c +++ b/src/Synth.c @@ -64,7 +64,6 @@ static DmSynthFont* DmSynth_getFont(DmSynth* slf, DmInstrument* ins) { } static DmResult DmSynth_updateFonts(DmSynth* slf, DmBand* band) { - DmResult rv = DmResult_SUCCESS; for (size_t i = 0; i < band->instruments_len; ++i) { DmInstrument* ins = &band->instruments[i]; if (ins->dls == NULL) { @@ -78,12 +77,13 @@ static DmResult DmSynth_updateFonts(DmSynth* slf, DmBand* band) { DmSynthFont new_fnt; new_fnt.dls = ins->dls; + DmResult rv = DmResult_SUCCESS; rv = DmSynth_createTsfForDls(ins->dls, &new_fnt.syn); if (rv != DmResult_SUCCESS) { continue; } - tsf_set_output(new_fnt.syn, TSF_STEREO_INTERLEAVED, slf->rate, 0); + tsf_set_output(new_fnt.syn, TSF_STEREO_INTERLEAVED, (int) slf->rate, 0); tsf_set_volume(new_fnt.syn, slf->volume); rv = DmSynthFontArray_add(&slf->fonts, new_fnt); @@ -145,7 +145,7 @@ static DmResult DmSynth_assignInstrumentChannels(DmSynth* slf, DmBand* band) { DmSynthFont* fnt = DmSynth_getFont(slf, ins); chan->font = fnt; - chan->channel = ins->channel; + chan->channel = (int) ins->channel; if (fnt == NULL) { continue; @@ -155,18 +155,18 @@ static DmResult DmSynth_assignInstrumentChannels(DmSynth* slf, DmBand* band) { uint32_t patch = ins->patch & 0xFFU; tsf_set_volume(fnt->syn, slf->volume); - tsf_channel_set_bank_preset(fnt->syn, ins->channel, bank, patch); + tsf_channel_set_bank_preset(fnt->syn, (int) ins->channel, (int) bank, (int) patch); // Update the instrument's properties if (ins->options & DmInstrument_VALID_PAN) { float pan = (float) ins->pan / (float) DmInt_MIDI_MAX; - tsf_channel_set_pan(fnt->syn, ins->channel, pan); + tsf_channel_set_pan(fnt->syn, (int) ins->channel, pan); chan->reset_pan = pan; } if (ins->options & DmInstrument_VALID_VOLUME) { float vol = (float) ins->volume / DmInt_MIDI_MAX; - tsf_channel_set_volume(fnt->syn, ins->channel, vol); + tsf_channel_set_volume(fnt->syn, (int) ins->channel, vol); chan->reset_volume = vol; } @@ -178,10 +178,7 @@ static DmResult DmSynth_assignInstrumentChannels(DmSynth* slf, DmBand* band) { return DmResult_SUCCESS; } -// TODO(lmichaelis): Technically, we should change as little as possible to accommodate the new band. -// For example: if only the pan of an instrument changes, we should also only update that -// instead of reloading the entire instrument list and re-creating all TSFs. -// See also: https://documentation.help/DirectMusic/usingbands.htm +// See https://documentation.help/DirectMusic/usingbands.htm void DmSynth_sendBandUpdate(DmSynth* slf, DmBand* band) { if (slf == NULL || band == NULL) { return; diff --git a/src/_Internal.h b/src/_Internal.h index 717781f..0445f91 100644 --- a/src/_Internal.h +++ b/src/_Internal.h @@ -566,7 +566,6 @@ DMINT int32_t max_s32(int32_t a, int32_t b); DMINT uint8_t min_u8(uint8_t a, uint8_t b); DMINT float lerp(float x, float start, float end); DMINT int32_t clamp_s32(int32_t val, int32_t min, int32_t max); -DMINT float clamp_f32(float val, float min, float max); DMINT int32_t Dm_randRange(int32_t range); DMINT DmCommandType Dm_embellishmentToCommand(DmEmbellishmentType embellishment); DMINT bool DmGuid_equals(DmGuid const* a, DmGuid const* b); diff --git a/src/util/Tsf.c b/src/util/Tsf.c index bb6da65..315a4fb 100644 --- a/src/util/Tsf.c +++ b/src/util/Tsf.c @@ -189,7 +189,7 @@ static DmResult Dm_createHydraSamplesForDls(DmDls* dls, float** pcm, int32_t* pc return DmResult_SUCCESS; } -static DmResult Dm_createHydra(DmDls* dls, struct tsf_hydra* res) { +static DmResult Dm_createHydraSkeleton(DmDls* dls, struct tsf_hydra* res) { // 1. Count the number of presets required and allocate them // -> We need one for each instrument res->phdrNum = dls->instrument_count + 1; // One for the sentinel @@ -262,25 +262,17 @@ static DmResult Dm_createHydra(DmDls* dls, struct tsf_hydra* res) { return ok ? DmResult_SUCCESS : DmResult_MEMORY_EXHAUSTED; } -DmResult DmSynth_createTsfForDls(DmDls* dls, tsf** out) { - if (dls == NULL) { - return DmResult_INVALID_ARGUMENT; - } - - // Initialize the hydra by allocation all required memory - struct tsf_hydra hydra; - - DmResult rv = Dm_createHydra(dls, &hydra); +// We export this function for the tools. +static DmResult Dm_createHydra(DmDls* dls, struct tsf_hydra* hydra, float** pcm, int32_t* pcm_len) { + DmResult rv = Dm_createHydraSkeleton(dls, hydra); if (rv != DmResult_SUCCESS) { return rv; } // Decode all PCM and create the sample headers. - float* pcm = NULL; - int32_t pcm_len = 0; struct tsf_hydra_shdr* default_shdrs = NULL; int32_t default_shdrs_len = 0; - rv = Dm_createHydraSamplesForDls(dls, &pcm, &pcm_len, &default_shdrs, &default_shdrs_len); + rv = Dm_createHydraSamplesForDls(dls, pcm, pcm_len, &default_shdrs, &default_shdrs_len); if (rv != DmResult_SUCCESS) { return rv; } @@ -301,37 +293,37 @@ DmResult DmSynth_createTsfForDls(DmDls* dls, tsf** out) { bank = 999; } - strncpy(hydra.phdrs[i].presetName, ins->info.inam, 19); - hydra.phdrs[i].bank = bank; - hydra.phdrs[i].preset = ins->patch; - hydra.phdrs[i].genre = 0; - hydra.phdrs[i].morphology = 0; - hydra.phdrs[i].library = 0; - hydra.phdrs[i].presetBagNdx = i; + strncpy(hydra->phdrs[i].presetName, ins->info.inam, 19); + hydra->phdrs[i].bank = bank; + hydra->phdrs[i].preset = ins->patch; + hydra->phdrs[i].genre = 0; + hydra->phdrs[i].morphology = 0; + hydra->phdrs[i].library = 0; + hydra->phdrs[i].presetBagNdx = i; - hydra.pbags[i].genNdx = pgen_ndx; - hydra.pbags[i].modNdx = pmod_ndx; + hydra->pbags[i].genNdx = pgen_ndx; + hydra->pbags[i].modNdx = pmod_ndx; - hydra.pgens[pgen_ndx].genOper = kInstrument; - hydra.pgens[pgen_ndx].genAmount.wordAmount = i; + hydra->pgens[pgen_ndx].genOper = kInstrument; + hydra->pgens[pgen_ndx].genAmount.wordAmount = i; pgen_ndx++; - strncpy(hydra.insts[i].instName, ins->info.inam, 19); - hydra.insts[i].instBagNdx = ibag_ndx; + strncpy(hydra->insts[i].instName, ins->info.inam, 19); + hydra->insts[i].instBagNdx = ibag_ndx; for (size_t r = 0; r < ins->region_count; ++r) { DmDlsRegion* reg = &ins->regions[r]; - hydra.ibags[ibag_ndx].instGenNdx = igen_ndx; - hydra.ibags[ibag_ndx].instModNdx = imod_ndx; + hydra->ibags[ibag_ndx].instGenNdx = igen_ndx; + hydra->ibags[ibag_ndx].instModNdx = imod_ndx; ibag_ndx++; - hydra.igens[igen_ndx].genOper = kKeyRange; - hydra.igens[igen_ndx].genAmount.range.hi = (tsf_u8) reg->range_high; - hydra.igens[igen_ndx].genAmount.range.lo = (tsf_u8) reg->range_low; + hydra->igens[igen_ndx].genOper = kKeyRange; + hydra->igens[igen_ndx].genAmount.range.hi = (tsf_u8) reg->range_high; + hydra->igens[igen_ndx].genAmount.range.lo = (tsf_u8) reg->range_low; igen_ndx++; - hydra.igens[igen_ndx].genOper = kVelRange; + hydra->igens[igen_ndx].genOper = kVelRange; uint8_t vel_hi = reg->velocity_high; uint8_t vel_lo = reg->velocity_low; @@ -340,37 +332,37 @@ DmResult DmSynth_createTsfForDls(DmDls* dls, tsf** out) { vel_lo = 0; } - hydra.igens[igen_ndx].genAmount.range.hi = vel_hi; - hydra.igens[igen_ndx].genAmount.range.lo = vel_lo; + hydra->igens[igen_ndx].genAmount.range.hi = vel_hi; + hydra->igens[igen_ndx].genAmount.range.lo = vel_lo; igen_ndx++; - hydra.igens[igen_ndx].genOper = kAttackVolEnv; - hydra.igens[igen_ndx].genAmount.shortAmount = sf2SecondsToTimeCents(0.1); + hydra->igens[igen_ndx].genOper = kAttackVolEnv; + hydra->igens[igen_ndx].genAmount.shortAmount = sf2SecondsToTimeCents(0.1); igen_ndx++; - hydra.igens[igen_ndx].genOper = kInitialAttenuation; - hydra.igens[igen_ndx].genAmount.shortAmount = (tsf_s16) reg->sample.attenuation; + hydra->igens[igen_ndx].genOper = kInitialAttenuation; + hydra->igens[igen_ndx].genAmount.shortAmount = (tsf_s16) reg->sample.attenuation; igen_ndx++; // Articulators for (size_t a = 0; a < ins->articulator_count; ++a) { - igen_ndx += DmSynth_insertGeneratorArticulators(hydra.igens + igen_ndx, &ins->articulators[a]); + igen_ndx += DmSynth_insertGeneratorArticulators(hydra->igens + igen_ndx, &ins->articulators[a]); } for (size_t a = 0; a < reg->articulator_count; ++a) { - igen_ndx += DmSynth_insertGeneratorArticulators(hydra.igens + igen_ndx, ®->articulators[a]); + igen_ndx += DmSynth_insertGeneratorArticulators(hydra->igens + igen_ndx, ®->articulators[a]); } - hydra.igens[igen_ndx].genOper = kSampleModes; - hydra.igens[igen_ndx].genAmount.wordAmount = reg->sample.looping == true ? 1 : 0; + hydra->igens[igen_ndx].genOper = kSampleModes; + hydra->igens[igen_ndx].genAmount.wordAmount = reg->sample.looping == true ? 1 : 0; igen_ndx++; - hydra.igens[igen_ndx].genOper = kSampleID; - hydra.igens[igen_ndx].genAmount.wordAmount = shdr_ndx; + hydra->igens[igen_ndx].genOper = kSampleID; + hydra->igens[igen_ndx].genAmount.wordAmount = shdr_ndx; igen_ndx++; // Additional sample configuration. - struct tsf_hydra_shdr* hdr = &hydra.shdrs[shdr_ndx]; + struct tsf_hydra_shdr* hdr = &hydra->shdrs[shdr_ndx]; *hdr = default_shdrs[reg->link_table_index]; shdr_ndx++; @@ -394,40 +386,72 @@ DmResult DmSynth_createTsfForDls(DmDls* dls, tsf** out) { } // Populate the sentinel values of the hydra - strncpy(hydra.phdrs[hydra.phdrNum - 1].presetName, "EOP", 19); - hydra.phdrs[hydra.phdrNum - 1].bank = 0; - hydra.phdrs[hydra.phdrNum - 1].preset = 0; - hydra.phdrs[hydra.phdrNum - 1].genre = 0; - hydra.phdrs[hydra.phdrNum - 1].morphology = 0; - hydra.phdrs[hydra.phdrNum - 1].library = 0; - hydra.phdrs[hydra.phdrNum - 1].presetBagNdx = hydra.pbagNum - 1; + strncpy(hydra->phdrs[hydra->phdrNum - 1].presetName, "EOP", 19); + hydra->phdrs[hydra->phdrNum - 1].bank = 0; + hydra->phdrs[hydra->phdrNum - 1].preset = 0; + hydra->phdrs[hydra->phdrNum - 1].genre = 0; + hydra->phdrs[hydra->phdrNum - 1].morphology = 0; + hydra->phdrs[hydra->phdrNum - 1].library = 0; + hydra->phdrs[hydra->phdrNum - 1].presetBagNdx = hydra->pbagNum - 1; + + hydra->pbags[hydra->pbagNum - 1].genNdx = hydra->pgenNum - 1; + hydra->pbags[hydra->pbagNum - 1].modNdx = hydra->pmodNum - 1; + + hydra->pgens[hydra->pgenNum - 1].genOper = 0; + hydra->pgens[hydra->pgenNum - 1].genAmount.shortAmount = 0; - hydra.pbags[hydra.pbagNum - 1].genNdx = hydra.pgenNum - 1; - hydra.pbags[hydra.pbagNum - 1].modNdx = hydra.pmodNum - 1; + hydra->pmods[hydra->pmodNum - 1].modSrcOper = 0; + hydra->pmods[hydra->pmodNum - 1].modDestOper = 0; + hydra->pmods[hydra->pmodNum - 1].modTransOper = 0; + hydra->pmods[hydra->pmodNum - 1].modAmount = 0; + hydra->pmods[hydra->pmodNum - 1].modAmtSrcOper = 0; - hydra.pgens[hydra.pgenNum - 1].genOper = 0; - hydra.pgens[hydra.pgenNum - 1].genAmount.shortAmount = 0; + strncpy(hydra->insts[hydra->instNum - 1].instName, "EOI", 19); + hydra->insts[hydra->instNum - 1].instBagNdx = hydra->ibagNum - 1; - hydra.pmods[hydra.pmodNum - 1].modSrcOper = 0; - hydra.pmods[hydra.pmodNum - 1].modDestOper = 0; - hydra.pmods[hydra.pmodNum - 1].modTransOper = 0; - hydra.pmods[hydra.pmodNum - 1].modAmount = 0; - hydra.pmods[hydra.pmodNum - 1].modAmtSrcOper = 0; + hydra->ibags[hydra->ibagNum - 1].instGenNdx = hydra->igenNum - 1; + hydra->ibags[hydra->ibagNum - 1].instModNdx = hydra->imodNum - 1; - strncpy(hydra.insts[hydra.instNum - 1].instName, "EOI", 19); - hydra.insts[hydra.instNum - 1].instBagNdx = hydra.ibagNum - 1; + hydra->igens[hydra->igenNum - 1].genOper = 0; + hydra->igens[hydra->igenNum - 1].genAmount.shortAmount = 0; - hydra.ibags[hydra.ibagNum - 1].instGenNdx = hydra.igenNum - 1; - hydra.ibags[hydra.ibagNum - 1].instModNdx = hydra.imodNum - 1; + hydra->imods[hydra->imodNum - 1].modSrcOper = 0; + hydra->imods[hydra->imodNum - 1].modDestOper = 0; + hydra->imods[hydra->imodNum - 1].modTransOper = 0; + hydra->imods[hydra->imodNum - 1].modAmount = 0; + hydra->imods[hydra->imodNum - 1].modAmtSrcOper = 0; - hydra.igens[hydra.igenNum - 1].genOper = 0; - hydra.igens[hydra.igenNum - 1].genAmount.shortAmount = 0; + Dm_free(default_shdrs); + return DmResult_SUCCESS; +} - hydra.imods[hydra.imodNum - 1].modSrcOper = 0; - hydra.imods[hydra.imodNum - 1].modDestOper = 0; - hydra.imods[hydra.imodNum - 1].modTransOper = 0; - hydra.imods[hydra.imodNum - 1].modAmount = 0; - hydra.imods[hydra.imodNum - 1].modAmtSrcOper = 0; +// We export this function for the tools. +static void Dm_freeHydra(struct tsf_hydra* hydra) { + Dm_free(hydra->phdrs); + Dm_free(hydra->pbags); + Dm_free(hydra->pgens); + Dm_free(hydra->pmods); + Dm_free(hydra->insts); + Dm_free(hydra->ibags); + Dm_free(hydra->igens); + Dm_free(hydra->imods); + Dm_free(hydra->shdrs); +} + +DmResult DmSynth_createTsfForDls(DmDls* dls, tsf** out) { + if (dls == NULL) { + return DmResult_INVALID_ARGUMENT; + } + + // Initialize the hydra by allocation all required memory + struct tsf_hydra hydra; + float* pcm = NULL; + int32_t pcm_len = 0; + + DmResult rv = Dm_createHydra(dls, &hydra, &pcm, &pcm_len); + if (rv != DmResult_SUCCESS) { + return rv; + } // Finally, create the tsf tsf* res = *out = Dm_alloc(sizeof(tsf)); @@ -443,16 +467,7 @@ DmResult DmSynth_createTsfForDls(DmDls* dls, tsf** out) { res->fontSamples = pcm; // Lastly, free up all the hydra stuff - Dm_free(default_shdrs); - Dm_free(hydra.phdrs); - Dm_free(hydra.pbags); - Dm_free(hydra.pgens); - Dm_free(hydra.pmods); - Dm_free(hydra.insts); - Dm_free(hydra.ibags); - Dm_free(hydra.igens); - Dm_free(hydra.imods); - Dm_free(hydra.shdrs); + Dm_freeHydra(&hydra); return DmResult_SUCCESS; }