ref: 28e1bab1f15ab3c2daff639b3962985fbd4bc240
dir: /src/pt2_pat2smp.c/
// for finding memory leaks in debug mode with Visual Studio #if defined _DEBUG && defined _MSC_VER #include <crtdbg.h> #endif #include <stdint.h> #include <stdbool.h> #include "pt2_header.h" #include "pt2_config.h" #include "pt2_helpers.h" #include "pt2_visuals.h" #include "pt2_mouse.h" #include "pt2_audio.h" #include "pt2_sampler.h" #include "pt2_textout.h" #include "pt2_rcfilter.h" #include "pt2_pat2smp.h" #include "pt2_downsample2x.h" bool intMusic(void); // pt2_replayer.c void storeTempVariables(void); // pt2_replayer.c void doPat2Smp(void) { moduleSample_t *s; ui.pat2SmpDialogShown = false; if (editor.sampleZero) { statusNotSampleZero(); return; } editor.dPat2SmpBuf = (double *)malloc(config.maxSampleLength * sizeof (double)); if (editor.dPat2SmpBuf == NULL) { statusOutOfMemory(); return; } const int8_t oldRow = editor.songPlaying ? 0 : song->currRow; editor.isSMPRendering = true; // this must be set before restartSong() storeTempVariables(); restartSong(); song->row = oldRow; song->currRow = song->row; editor.blockMarkFlag = false; pointerSetMode(POINTER_MODE_MSG2, NO_CARRY); setStatusMessage("RENDERING...", NO_CARRY); modSetTempo(song->currBPM, true); editor.pat2SmpPos = 0; int64_t tickSampleCounter64 = 0; clearMixerDownsamplerStates(); editor.smpRenderingDone = false; while (!editor.smpRenderingDone && editor.songPlaying) { if (tickSampleCounter64 <= 0) // new replayer tick { if (!intMusic()) editor.smpRenderingDone = true; // this tick is the last tick tickSampleCounter64 += audio.samplesPerTick64; } int32_t remainingTick = (tickSampleCounter64 + UINT32_MAX) >> 32; // ceil (rounded upwards) outputAudio(NULL, remainingTick); tickSampleCounter64 -= (int64_t)remainingTick << 32; } editor.isSMPRendering = false; clearMixerDownsamplerStates(); resetSong(); int32_t renderLength = editor.pat2SmpPos; s = &song->samples[editor.currSample]; // set back old row song->currRow = song->row = oldRow; // normalize and quantize to 8-bit double dAmp = 1.0; const double dPeak = getDoublePeak(editor.dPat2SmpBuf, renderLength); if (dPeak > 0.0) dAmp = INT8_MAX / dPeak; int8_t *smpPtr = &song->sampleData[s->offset]; for (int32_t i = 0; i < renderLength; i++) { const int32_t smp = (const int32_t)round(editor.dPat2SmpBuf[i] * dAmp); assert(smp >= -128 && smp <= 127); // shouldn't happen according to dAmp smpPtr[i] = (int8_t)smp; } free(editor.dPat2SmpBuf); // clear the rest of the sample (if not full) if (renderLength < config.maxSampleLength) memset(&song->sampleData[s->offset+renderLength], 0, config.maxSampleLength - renderLength); if (editor.pat2SmpHQ) { strcpy(s->text, "pat2smp(a-3 ftune:+4)"); s->fineTune = 4; } else { strcpy(s->text, "pat2smp(e-3 ftune: 0)"); s->fineTune = 0; } s->length = renderLength; s->volume = 64; s->loopStart = 0; s->loopLength = 2; editor.samplePos = 0; fixSampleBeep(s); updateCurrSample(); pointerSetMode(POINTER_MODE_IDLE, DO_CARRY); displayMsg("ROWS RENDERED!"); setMsgPointer(); }