Mercurial > hg > dmlib
changeset 55:e0e470c3fc8e
Initial round of cleaning up the player code a bit.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 01 Oct 2012 06:28:29 +0300 |
parents | 65cdb4de6fd8 |
children | 8725853609db |
files | jssplr.c jssplr.h testpl.c |
diffstat | 3 files changed, 372 insertions(+), 434 deletions(-) [+] |
line wrap: on
line diff
--- a/jssplr.c Mon Oct 01 04:18:15 2012 +0300 +++ b/jssplr.c Mon Oct 01 06:28:29 2012 +0300 @@ -90,7 +90,7 @@ static void jmpCSetPitch(JSSPlayer *mp, int channel, int value) { assert(mp != NULL); - assert(mp->pDevice != NULL); + assert(mp->device != NULL); if (value > 0) { @@ -98,90 +98,54 @@ { // Frequency = 8363*1712 / Period //fprintf(stderr, "jmpCSetPitch::AMIGA(%d, %d)\n", channel, value); - jvmSetFreq(mp->pDevice, channel, 14317456.0f / (double) value); + jvmSetFreq(mp->device, channel, 14317456.0f / (double) value); } else { // Frequency = Frequency = 8363*2^((6*12*16*4 - Period) / (12*16*4)) //fprintf(stderr, "jmpCSetPitch::Linear(%d, %d)\n", channel, value); - jvmSetFreq(mp->pDevice, channel, + jvmSetFreq(mp->device, channel, 8363.0f * pow(2.0f, (4608.0f - (double) value) / 768.0f)); } } } -static void jmpCSetInstrument(JSSPlayer * mp, int channel) +static void jmpCSetVolume(JSSPlayer * mp, JSSPlayerChannel *chn, int channel, int volume) { - JSSInstrument *instr; assert(mp != NULL); - assert(mp->pDevice != NULL); - - instr = mp->iCInstrument[channel]; + assert(mp->device != NULL); - if (instr) - { - jvmSetSample(mp->pDevice, channel, - instr->data, instr->size, - instr->loopS, instr->loopE, - instr->flags); - } + if (volume < mpMinVol) volume = mpMinVol; else + if (volume > mpMaxVol) volume = mpMaxVol; + +//fprintf(stderr, "chn %d: vol=%d, fad=%d, env=%d\n", channel, volume, chn->iCFadeOutVol, chn->iCVolEnv); + + jvmSetVolume(mp->device, channel, + (chn->iCFadeOutVol * chn->iCVolEnv * volume) / (16 * 65536)); } -static void jmpCSetVolume(JSSPlayer * mp, int channel, int volume) +static void jmpCSetPanning(JSSPlayer * mp, JSSPlayerChannel *chn, int channel, int panning) { assert(mp != NULL); - assert(mp->pDevice != NULL); - if (volume < 0) volume = 0; else - if (volume > 64) volume = 64; - -//fprintf(stderr, "chn %d: vol=%d, fad=%d, env=%d\n", channel, volume, mp->iCFadeOutVol[channel], mp->iCVolEnv[channel]); + assert(mp->device != NULL); - jvmSetVolume(mp->pDevice, channel, - (mp->iCFadeOutVol[channel] * mp->iCVolEnv[channel] * volume) / (16 * 65536)); -} - - -static void jmpCSetPanning(JSSPlayer * mp, int channel, int panning) -{ - assert(mp != NULL); - assert(mp->pDevice != NULL); - - jvmSetPan(mp->pDevice, channel, - panning + (((mp->iCPanEnv[channel] - 32) * (128 - abs(panning - 128))) / 32)); + jvmSetPan(mp->device, channel, + panning + (((chn->iCPanEnv - 32) * (128 - abs(panning - 128))) / 32)); } static void jmpCSetPosition(JSSPlayer * mp, int channel, int value) { assert(mp != NULL); - assert(mp->pDevice != NULL); + assert(mp->device != NULL); - jvmSetPos(mp->pDevice, channel, value); + jvmSetPos(mp->device, channel, value); } -static void jmpCPlay(JSSPlayer * mp, int channel) -{ - assert(mp != NULL); - assert(mp->pDevice != NULL); - - jvmPlay(mp->pDevice, channel); -} - - -static void jmpCStop(JSSPlayer * mp, int channel) -{ - assert(mp != NULL); - assert(mp->pDevice != NULL); - - jvmStop(mp->pDevice, channel); -} - - - -static int jmpFindEnvPoint(JSSEnvelope * env, int pos) +static int jmpFindEnvPoint(JSSEnvelope * env, const int pos) { int i; @@ -241,9 +205,9 @@ } -static void jmpProcessExtInstrument(JSSPlayer * mp, int channel) +static void jmpProcessExtInstrument(JSSPlayer * mp, JSSPlayerChannel *chn, int channel) { - JSSExtInstrument *inst = mp->iCExtInstrument[channel]; + JSSExtInstrument *inst = chn->iCExtInstrument; // Get the instrument for envelope data if (!inst) return; @@ -257,21 +221,22 @@ if (inst->volumeEnv.flags & jenvfUsed) { // Process the instrument volume fadeout - if (mp->iCKeyOff[channel] && (mp->iCFadeOutVol[channel] > 0) && (inst->fadeOut > 0)) + if (chn->iCKeyOff && chn->iCFadeOutVol > 0 && inst->fadeOut > 0) { - int tmp = (mp->iCFadeOutVol[channel] - inst->fadeOut); + int tmp = chn->iCFadeOutVol - inst->fadeOut; if (tmp < 0) tmp = 0; - mp->iCFadeOutVol[channel] = tmp; + chn->iCFadeOutVol = tmp; JMPSETNDFLAGS(cdfNewVolume); } - if (mp->iCVolEnv_Exec[channel]) + if (chn->iCVolEnv_Exec) { // Execute the volume envelope - jmpExecEnvelope(&(inst->volumeEnv), mp->iCKeyOff[channel], - &(mp->iCVolEnv_Frames[channel]), &(mp->iCVolEnv_Exec[channel]), - &(mp->iCVolEnv[channel])); + jmpExecEnvelope(&(inst->volumeEnv), + chn->iCKeyOff, + &(chn->iCVolEnv_Frames), &(chn->iCVolEnv_Exec), + &(chn->iCVolEnv)); JMPSETNDFLAGS(cdfNewVolume); } @@ -279,10 +244,10 @@ else { // If the envelope is not used, set max volume - if (mp->iCVolEnv[channel] != mpMaxVol) + if (chn->iCVolEnv != mpMaxVol) { - mp->iCVolEnv[channel] = mpMaxVol; - mp->iCFadeOutVol[channel] = mpMaxFadeoutVol; + chn->iCVolEnv = mpMaxVol; + chn->iCFadeOutVol = mpMaxFadeoutVol; JMPSETNDFLAGS(cdfNewVolume); } } @@ -290,12 +255,12 @@ // Process the panning envelope if (inst->panningEnv.flags & jenvfUsed) { - if (mp->iCPanEnv_Exec[channel]) + if (chn->iCPanEnv_Exec) { // Execute the panning envelope - jmpExecEnvelope(&(inst->panningEnv), mp->iCKeyOff[channel], - &(mp->iCPanEnv_Frames[channel]), &(mp->iCPanEnv_Exec[channel]), - &(mp->iCPanEnv[channel])); + jmpExecEnvelope(&(inst->panningEnv), chn->iCKeyOff, + &(chn->iCPanEnv_Frames), &(chn->iCPanEnv_Exec), + &(chn->iCPanEnv)); JMPSETNDFLAGS(cdfNewPanPos); } @@ -303,9 +268,9 @@ else { // If the envelope is not used, set center panning - if (mp->iCPanEnv[channel] != mpPanCenter) + if (chn->iCPanEnv != mpPanCenter) { - mp->iCPanEnv[channel] = mpPanCenter; + chn->iCPanEnv = mpPanCenter; JMPSETNDFLAGS(cdfNewPanPos); } } @@ -339,7 +304,7 @@ JSSERROR(DMERR_MALLOC, NULL, "Could not allocate memory for player structure.\n"); // Set variables - mp->pDevice = pDevice; + mp->device = pDevice; #ifdef JSS_SUP_THREADS mp->mutex = dmCreateMutex(); #endif @@ -371,17 +336,27 @@ /* Reset the envelopes for given channel. */ -static void jmpResetEnvelopes(JSSPlayer * mp, int channel) +static void jmpResetEnvelopes(JSSPlayerChannel *chn) { - assert(mp != NULL); - - mp->iCPanEnv_Frames[channel] = mp->iCVolEnv_Frames[channel] = 0; - mp->iCPanEnv_Exec[channel] = mp->iCVolEnv_Exec[channel] = TRUE; + chn->iCPanEnv_Frames = chn->iCVolEnv_Frames = 0; + chn->iCPanEnv_Exec = chn->iCVolEnv_Exec = TRUE; } /* Clear module player structure */ +void jmpClearChannel(JSSPlayerChannel *chn) +{ + memset(chn, 0, sizeof(JSSPlayerChannel)); + + chn->iCNote = jsetNotSet; + chn->iCInstrumentN = jsetNotSet; + chn->iCExtInstrumentN = jsetNotSet; + chn->iCPanning = mpPanCenter; + chn->iCPanEnv = mpPanCenter; +} + + void jmpClearPlayer(JSSPlayer * mp) { int i; @@ -389,72 +364,16 @@ JSS_LOCK(mp); // Initialize general variables - mp->iPatternDelay = 0; - mp->newRowSet = FALSE; - mp->newOrderSet = FALSE; - mp->iTick = jsetNotSet; - mp->iRow = 0; - mp->iLastPatLoopRow = 0; + mp->patternDelay = 0; + mp->newRowSet = FALSE; + mp->newOrderSet = FALSE; + mp->tick = jsetNotSet; + mp->row = 0; + mp->lastPatLoopRow = 0; // Initialize channel data - memset(&(mp->iPatLoopRow), 0, sizeof(mp->iPatLoopRow)); - memset(&(mp->iPatLoopCount), 0, sizeof(mp->iPatLoopCount)); - - memset(&mp->iLastPortaParam, 0, sizeof(mp->iLastPortaParam)); - memset(&mp->iLastPortaToNoteParam, 0, sizeof(mp->iLastPortaToNoteParam)); - memset(&mp->iLastPortaToNotePitch, 0, sizeof(mp->iLastPortaToNotePitch)); - - memset(&mp->iVibratoPos, 0, sizeof(mp->iVibratoPos)); - memset(&mp->iVibratoSpeed, 0, sizeof(mp->iVibratoSpeed)); - memset(&mp->iVibratoDepth, 0, sizeof(mp->iVibratoDepth)); - memset(&mp->iVibratoWC, 0, sizeof(mp->iVibratoWC)); - - memset(&mp->iTremoloPos, 0, sizeof(mp->iTremoloPos)); - memset(&mp->iTremoloSpeed, 0, sizeof(mp->iTremoloSpeed)); - memset(&mp->iTremoloDepth, 0, sizeof(mp->iTremoloDepth)); - memset(&mp->iTremoloWC, 0, sizeof(mp->iTremoloWC)); - - memset(&mp->iLastTremorParam, 0, sizeof(mp->iLastTremorParam)); - memset(&mp->iTremorCount, 0, sizeof(mp->iTremorCount)); - memset(&mp->iLastSampleOffset, 0, sizeof(mp->iLastSampleOffset)); - memset(&mp->iLastRetrigParam, 0, sizeof(mp->iLastRetrigParam)); - memset(&mp->iLastVolSlideParam, 0, sizeof(mp->iLastVolSlideParam)); - - memset(&mp->iRetrigNDFlags, 0, sizeof(mp->iRetrigNDFlags)); - memset(&mp->iSaveNDFlags, 0, sizeof(mp->iSaveNDFlags)); - - memset(&mp->iCNewDataFlags, 0, sizeof(mp->iCNewDataFlags)); - memset(&mp->iCPitch, 0, sizeof(mp->iCPitch)); - memset(&mp->iCPosition, 0, sizeof(mp->iCPosition)); - memset(&mp->iCVolume, 0, sizeof(mp->iCVolume)); - memset(&mp->iCFadeOutVol, 0, sizeof(mp->iCFadeOutVol)); - memset(&mp->iCVolEnv, 0, sizeof(mp->iCVolEnv)); - - memset(&mp->iCAutoVib_Frames, 0, sizeof(mp->iCAutoVib_Frames)); - memset(&mp->iCPanEnv_Frames, 0, sizeof(mp->iCPanEnv_Frames)); - memset(&mp->iCVolEnv_Frames, 0, sizeof(mp->iCVolEnv_Frames)); - - memset(&mp->iCLastFineVolumeslideUpParam, 0, sizeof(mp->iCLastFineVolumeslideUpParam)); - memset(&mp->iCLastFineVolumeslideDownParam, 0, sizeof(mp->iCLastFineVolumeslideDownParam)); - memset(&mp->iCLastExtraFinePortamentoUpParam, 0, sizeof(mp->iCLastExtraFinePortamentoUpParam)); - memset(&mp->iCLastExtraFinePortamentoDownParam, 0, sizeof(mp->iCLastExtraFinePortamentoDownParam)); - memset(&mp->iCLastFinePortamentoUpParam, 0, sizeof(mp->iCLastFinePortamentoUpParam)); - memset(&mp->iCLastFinePortamentoDownParam, 0, sizeof(mp->iCLastFinePortamentoDownParam)); - - memset(&mp->iCPanEnv_Exec, 0, sizeof(mp->iCPanEnv_Exec)); - memset(&mp->iCVolEnv_Exec, 0, sizeof(mp->iCVolEnv_Exec)); - memset(&mp->iCKeyOff, 0, sizeof(mp->iCKeyOff)); - for (i = 0; i < jsetNChannels; i++) - { - mp->iCNote[i] = jsetNotSet; - mp->iCInstrument[i] = NULL; - mp->iCInstrumentN[i] = jsetNotSet; - mp->iCExtInstrument[i] = NULL; - mp->iCExtInstrumentN[i] = jsetNotSet; - mp->iCPanning[i] = mpPanCenter; - mp->iCPanEnv[i] = mpPanCenter; - } + jmpClearChannel(&mp->channels[i]); JSS_UNLOCK(mp); } @@ -462,7 +381,7 @@ /* Set module */ -void jmpSetModule(JSSPlayer * mp, JSSModule * pModule) +void jmpSetModule(JSSPlayer * mp, JSSModule * module) { assert(mp != NULL); JSS_LOCK(mp); @@ -470,7 +389,7 @@ jmpStop(mp); jmpClearPlayer(mp); - mp->pModule = pModule; + mp->module = module; JSS_UNLOCK(mp); } @@ -485,8 +404,7 @@ if (mp->isPlaying) { - // Remove callback - jvmRemoveCallback(mp->pDevice); + jvmRemoveCallback(mp->device); mp->isPlaying = FALSE; } @@ -503,7 +421,7 @@ if (!mp->isPlaying) { - int result = jvmSetCallback(mp->pDevice, jmpExec, (void *) mp); + int result = jvmSetCallback(mp->device, jmpExec, (void *) mp); if (result != DMERR_OK) JSSERROR(result,, "Could not initialize callback for player.\n"); @@ -524,25 +442,25 @@ int pattern; pattern = jsetOrderEnd; - mp->iOrder = jsetNotSet; + mp->order = jsetNotSet; orderOK = FALSE; while (!orderOK) { - if (order < 0 || order >= mp->pModule->norders) + if (order < 0 || order >= mp->module->norders) { jmpStop(mp); orderOK = TRUE; } else { - pattern = mp->pModule->orderList[order]; + pattern = mp->module->orderList[order]; if (pattern == jsetOrderSkip) { order++; } else - if (pattern >= mp->pModule->npatterns || pattern == jsetOrderEnd) + if (pattern >= mp->module->npatterns || pattern == jsetOrderEnd) { jmpStop(mp); orderOK = TRUE; @@ -551,9 +469,9 @@ { // All OK orderOK = TRUE; - mp->pPattern = mp->pModule->patterns[pattern]; - mp->iPattern = pattern; - mp->iOrder = order; + mp->pattern = mp->module->patterns[pattern]; + mp->npattern = pattern; + mp->order = order; } } } @@ -566,10 +484,10 @@ { assert(mp != NULL); JSS_LOCK(mp); - assert(mp->pDevice != NULL); + assert(mp->device != NULL); - mp->iTempo = tempo; - jvmSetCallbackFreq(mp->pDevice, (tempo * 2) / 5); + mp->tempo = tempo; + jvmSetCallbackFreq(mp->device, (tempo * 2) / 5); JSS_UNLOCK(mp); } @@ -579,13 +497,13 @@ int i; assert(mp != NULL); JSS_LOCK(mp); - assert(mp->pDevice != NULL); - assert(mp->pModule != NULL); + assert(mp->device != NULL); + assert(mp->module != NULL); - for (i = 0; i < mp->pModule->nchannels; i++) + for (i = 0; i < mp->module->nchannels; i++) { - jvmStop(mp->pDevice, i); - jvmClear(mp->pDevice, i); + jvmStop(mp->device, i); + jvmClear(mp->device, i); } JSS_UNLOCK(mp); @@ -594,21 +512,20 @@ /* Starts playing module from a given ORDER. */ -int jmpPlayOrder(JSSPlayer * mp, int iStartOrder) +int jmpPlayOrder(JSSPlayer * mp, int order) { int result; assert(mp != NULL); JSS_LOCK(mp); - assert(mp->pModule != NULL); + assert(mp->module != NULL); // Stop if already playing jmpStop(mp); - jmpClearChannels(mp); // Check starting order - if (iStartOrder < 0 || iStartOrder >= mp->pModule->norders) + if (order < 0 || order >= mp->module->norders) { JSS_UNLOCK(mp); JSSERROR(DMERR_INVALID_ARGS, DMERR_INVALID_ARGS, "Invalid playing startorder given.\n"); @@ -617,20 +534,20 @@ // Initialize playing jmpClearPlayer(mp); - jmpSetNewOrder(mp, iStartOrder); + jmpSetNewOrder(mp, order); - if (mp->iOrder == jsetNotSet) + if (mp->order == jsetNotSet) { JSS_UNLOCK(mp); JSSERROR(DMERR_NOT_SUPPORTED, DMERR_NOT_SUPPORTED, - "Could not start playing from given order #%i\n", iStartOrder); + "Could not start playing from given order #%i\n", order); } - mp->iSpeed = mp->pModule->defSpeed; - jmpSetTempo(mp, mp->pModule->defTempo); + mp->speed = mp->module->defSpeed; + jmpSetTempo(mp, mp->module->defTempo); // Set callback - result = jvmSetCallback(mp->pDevice, jmpExec, (void *) mp); + result = jvmSetCallback(mp->device, jmpExec, (void *) mp); if (result != DMERR_OK) { JSS_UNLOCK(mp); @@ -651,7 +568,7 @@ int result; assert(mp != NULL); JSS_LOCK(mp); - assert(mp->pModule != NULL); + assert(mp->module != NULL); // Stop if already playing jmpStop(mp); @@ -660,12 +577,12 @@ // Initialize playing jmpClearPlayer(mp); - mp->iPattern = pattern; - mp->iSpeed = mp->pModule->defSpeed; - jmpSetTempo(mp, mp->pModule->defTempo); + mp->npattern = pattern; + mp->speed = mp->module->defSpeed; + jmpSetTempo(mp, mp->module->defTempo); // Set callback - result = jvmSetCallback(mp->pDevice, jmpExec, (void *) mp); + result = jvmSetCallback(mp->device, jmpExec, (void *) mp); if (result != DMERR_OK) { JSS_UNLOCK(mp); @@ -681,45 +598,43 @@ /* Set volume for given module channel. */ -static void jmpSetVolume(JSSPlayer * mp, int channel, int value) +static void jmpSetVolume(JSSPlayerChannel * chn, int channel, int volume) { // Check values - if (value < mpMinVol) - value = mpMinVol; - else if (value > mpMaxVol) - value = mpMaxVol; + if (volume < mpMinVol) volume = mpMinVol; else + if (volume > mpMaxVol) volume = mpMaxVol; // Set the volume - mp->iCVolume[channel] = value; + chn->iCVolume = volume; JMPSETNDFLAGS(cdfNewVolume); } -#define jmpChangeVolume(Q, Z, X) jmpSetVolume(Q, Z, mp->iCVolume[channel] + (X)) +#define jmpChangeVolume(Q, Z, X) jmpSetVolume(Q, Z, chn->iCVolume + (X)) /* Change the pitch of given channel by ADelta. */ -static void jmpChangePitch(JSSPlayer * mp, int channel, int delta) +static void jmpChangePitch(JSSPlayerChannel *chn, int channel, int delta) { int value; // Calculate new pitch and check it - value = (mp->iCPitch[channel] + delta); + value = chn->iCPitch + delta; if (value < 0) value = 0; // Set the new pitch - mp->iCPitch[channel] = value; + chn->iCPitch = value; JMPSETNDFLAGS(cdfNewPitch); } /* Do a note portamento (pitch slide) effect for given module channel. */ -static void jmpDoPortamento(JSSPlayer * mp, int channel) +static void jmpDoPortamento(JSSPlayerChannel * chn, int channel) { // Check for zero parameter - if (mp->iLastPortaToNoteParam[channel] == 0) + if (chn->iLastPortaToNoteParam == 0) { JMPSETNDFLAGS(cdfNewPitch); return; @@ -728,21 +643,21 @@ /* Slide the pitch of channel to the destination value * with speed of iLastPortaToNoteParam[] * 4 and stop when it equals. */ - if (mp->iCPitch[channel] != mp->iLastPortaToNotePitch[channel]) + if (chn->iCPitch != chn->iLastPortaToNotePitch) { - if (mp->iCPitch[channel] < mp->iLastPortaToNotePitch[channel]) + if (chn->iCPitch < chn->iLastPortaToNotePitch) { // Increase pitch UP - jmpChangePitch(mp, channel, mp->iLastPortaToNoteParam[channel] * 4); - if (mp->iCPitch[channel] > mp->iLastPortaToNotePitch[channel]) - mp->iCPitch[channel] = mp->iLastPortaToNotePitch[channel]; + jmpChangePitch(chn, channel, chn->iLastPortaToNoteParam * 4); + if (chn->iCPitch > chn->iLastPortaToNotePitch) + chn->iCPitch = chn->iLastPortaToNotePitch; } else { // Decrease pitch DOWN - jmpChangePitch(mp, channel, -(mp->iLastPortaToNoteParam[channel] * 4)); - if (mp->iCPitch[channel] < mp->iLastPortaToNotePitch[channel]) - mp->iCPitch[channel] = mp->iLastPortaToNotePitch[channel]; + jmpChangePitch(chn, channel, -(chn->iLastPortaToNoteParam * 4)); + if (chn->iCPitch < chn->iLastPortaToNotePitch) + chn->iCPitch = chn->iLastPortaToNotePitch; } } } @@ -750,19 +665,19 @@ /* Do a tremolo effect for given module channel. */ -static void jmpDoTremolo(JSSPlayer * mp, int channel) +static void jmpDoTremolo(JSSPlayer * mp, JSSPlayerChannel *chn, int channel) { int delta, pos, depth; // Check settings - if (mp->iTremoloDepth[channel] == 0 || mp->iTremoloSpeed[channel] == 0) + if (chn->iTremoloDepth == 0 || chn->iTremoloSpeed == 0) return; // Get position of tremolo waveform - pos = mp->iTremoloPos[channel] & 255; - depth = mp->iTremoloDepth[channel]; + pos = chn->iTremoloPos & 255; + depth = chn->iTremoloDepth; - switch (mp->iTremoloWC[channel] & 3) + switch (chn->iTremoloWC & 3) { case 0: // Sine-wave delta = (jmpSineTable[pos] * depth) / 2048; @@ -781,30 +696,30 @@ } // Set the new volume - jmpCSetVolume(mp, channel, mp->iCVolume[channel] + delta); + jmpCSetVolume(mp, chn, channel, chn->iCVolume + delta); // Advance tremolo waveform position - mp->iTremoloPos[channel] += mp->iTremoloSpeed[channel]; - if (mp->iTremoloPos[channel] > 255) - mp->iTremoloPos[channel] = 0; + chn->iTremoloPos += chn->iTremoloSpeed; + if (chn->iTremoloPos > 255) + chn->iTremoloPos = 0; } /* Do a vibrato effect for given module channel. */ -static void jmpDoVibrato(JSSPlayer * mp, int channel) +static void jmpDoVibrato(JSSPlayer * mp, JSSPlayerChannel *chn, int channel) { int delta, pos, depth; // Check settings - if (mp->iVibratoDepth[channel] == 0 || mp->iVibratoSpeed[channel] == 0) + if (chn->iVibratoDepth == 0 || chn->iVibratoSpeed == 0) return; // Get position of vibrato waveform - pos = mp->iVibratoPos[channel] & 255; - depth = mp->iVibratoDepth[channel]; + pos = chn->iVibratoPos & 255; + depth = chn->iVibratoDepth; - switch (mp->iVibratoWC[channel] & 3) + switch (chn->iVibratoWC & 3) { case 0: // Sine-wave delta = (jmpSineTable[pos] * depth) / 2048; @@ -823,27 +738,27 @@ } // Set the new frequency - jmpCSetPitch(mp, channel, mp->iCPitch[channel] + delta); + jmpCSetPitch(mp, channel, chn->iCPitch + delta); // Advance vibrato waveform position - mp->iVibratoPos[channel] += mp->iVibratoSpeed[channel]; - if (mp->iVibratoPos[channel] > 255) - mp->iVibratoPos[channel] = 0; + chn->iVibratoPos += chn->iVibratoSpeed; + if (chn->iVibratoPos > 255) + chn->iVibratoPos = 0; } /* Do a volume slide effect for given module channel. */ -static void jmpDoVolumeSlide(JSSPlayer * mp, int channel, int param) +static void jmpDoVolumeSlide(JSSPlayerChannel * chn, int channel, int param) { int paramX, paramY; JMPMAKEPARAM(param, paramX, paramY) if (paramY == 0) - jmpChangeVolume(mp, channel, paramX); + jmpChangeVolume(chn, channel, paramX); if (paramX == 0) - jmpChangeVolume(mp, channel, -paramY); + jmpChangeVolume(chn, channel, -paramY); } @@ -854,47 +769,48 @@ * here is included also a slightly kludgy implementation of the * FT2 patloop bug. */ -static void jmpDoPatternLoop(JSSPlayer * mp, int channel, int paramY) +static void jmpDoPatternLoop(JSSPlayer * mp, JSSPlayerChannel *chn, int channel, int paramY) { // Check what we need to do if (paramY > 0) { // SBx/E6x loops 'x' times - if (mp->iPatLoopCount[channel] == 1) - mp->iPatLoopCount[channel] = 0; + if (chn->iPatLoopCount == 1) + chn->iPatLoopCount = 0; else { // Check if we need to set the count - if (mp->iPatLoopCount[channel] == 0) - mp->iPatLoopCount[channel] = (paramY + 1); + if (chn->iPatLoopCount == 0) + chn->iPatLoopCount = (paramY + 1); // Loop to specified row - mp->iPatLoopCount[channel]--; - mp->iNewRow = mp->iPatLoopRow[channel]; + chn->iPatLoopCount--; + mp->newRow = chn->iPatLoopRow; mp->newRowSet = TRUE; } } else { // SB0/E60 sets the loop start point - mp->iPatLoopRow[channel] = mp->iRow; + chn->iPatLoopRow = mp->row; // This is here because of the infamous FT2 patloop bug - mp->iLastPatLoopRow = mp->iRow; + mp->lastPatLoopRow = mp->row; } } /* Do arpeggio effect */ -static void jmpDoArpeggio(JSSPlayer * mp, int channel, int paramY, int paramX) +static void jmpDoArpeggio(JSSPlayer * mp, JSSPlayerChannel *chn, int channel, int paramY, int paramX) { - JSSInstrument *tempInst = mp->iCInstrument[channel]; + JSSInstrument *tempInst = chn->iCInstrument; + if (tempInst) { - int tmp = mp->iCNote[channel]; + int tmp = chn->iCNote; if (tmp == jsetNotSet || tmp == jsetNoteOff) return; - switch (mp->iTick & 3) + switch (mp->tick & 3) { case 1: tmp += paramX; @@ -913,6 +829,7 @@ */ static void jmpProcessRowEffect(JSSPlayer * mp, int channel, JSSNote * currNote) { + JSSPlayerChannel *chn = &(mp->channels[channel]); int param, paramX, paramY; char effect; @@ -923,7 +840,7 @@ switch (effect) { case '0': // 0xy = Arpeggio - jmpDoArpeggio(mp, channel, paramX, paramY); + jmpDoArpeggio(mp, chn, channel, paramX, paramY); break; case 'W': // Used widely in demo-music as MIDAS Sound System sync-command @@ -934,46 +851,46 @@ case '1': case '2': // 1xy = Portamento Up, 2xy = Portamento Down : IMPL.VERIFIED if (param) - mp->iLastPortaParam[channel] = param; + chn->iLastPortaParam = param; break; case '3': // 3xy = Porta To Note if (param) - mp->iLastPortaToNoteParam[channel] = param; + chn->iLastPortaToNoteParam = param; if (currNote->note != jsetNotSet && currNote->note != jsetNoteOff) { - mp->iLastPortaToNotePitch[channel] = mp->iCPitch[channel]; - mp->iCPitch[channel] = mp->iCOldPitch[channel]; + chn->iLastPortaToNotePitch = chn->iCPitch; + chn->iCPitch = chn->iCOldPitch; JMPUNSETNDFLAGS(cdfNewPitch | cdfNewInstr | cdfNewPanPos); } break; case '4': // 4xy = Vibrato : IMPL.VERIFIED if (paramX) - mp->iVibratoSpeed[channel] = paramX; + chn->iVibratoSpeed = paramX; if (paramY) - mp->iVibratoDepth[channel] = paramY; + chn->iVibratoDepth = paramY; - if ((mp->iVibratoWC[channel] & 4) == 0) - mp->iVibratoPos[channel] = 0; + if ((chn->iVibratoWC & 4) == 0) + chn->iVibratoPos = 0; break; case '5': // 5xy = Portamento + Volume Slide case '6': // 6xy = Vibrato + Volume slide if (param) - mp->iLastVolSlideParam[channel] = param; + chn->iLastVolSlideParam = param; break; case '7': // 7xy = Tremolo if (paramX) - mp->iTremoloSpeed[channel] = paramX; + chn->iTremoloSpeed = paramX; if (paramY) - mp->iTremoloDepth[channel] = paramY; + chn->iTremoloDepth = paramY; - if ((mp->iTremoloWC[channel] & 4) == 0) - mp->iTremoloPos[channel] = 0; + if ((chn->iTremoloWC & 4) == 0) + chn->iTremoloPos = 0; break; case '8': // 8xx = Set Panning @@ -981,40 +898,40 @@ break; case '9': // 9xx = Set Sample Offset : IMPL.VERIFIED - if (mp->iCNewDataFlags[channel] & cdfNewPitch) + if (chn->iCNewDataFlags & cdfNewPitch) { - mp->iCPosition[channel] = param * 0x100; + chn->iCPosition = param * 0x100; JMPSETNDFLAGS(cdfNewPos); } break; case 'A': // Axy = Volume Slide : IMPL.VERIFIED if (param) - mp->iLastVolSlideParam[channel] = param; + chn->iLastVolSlideParam = param; break; case 'B': // Bxx = Pattern Jump : IMPL.VERIFIED - mp->iNewOrder = param; + mp->newOrder = param; mp->newOrderSet = TRUE; mp->jumpFlag = TRUE; - mp->iLastPatLoopRow = 0; + mp->lastPatLoopRow = 0; break; case 'C': // Cxx = Set Volume : IMPL.VERIFIED - jmpSetVolume(mp, channel, param); + jmpSetVolume(chn, channel, param); break; case 'D': // Dxx = Pattern Break : IMPL.VERIFIED // Compute the new row - mp->iNewRow = (paramX * 10) + paramY; - if (mp->iNewRow >= mp->pPattern->nrows) - mp->iNewRow = 0; + mp->newRow = (paramX * 10) + paramY; + if (mp->newRow >= mp->pattern->nrows) + mp->newRow = 0; mp->newRowSet = TRUE; // Now we do some tricky tests if (!mp->breakFlag && !mp->jumpFlag) { - mp->iNewOrder = mp->iOrder + 1; + mp->newOrder = mp->order + 1; mp->newOrderSet = TRUE; } @@ -1029,23 +946,23 @@ case 0x01: // E1x - Fine Portamento Up if (paramY) - mp->iCLastFinePortamentoUpParam[channel] = paramY; + chn->iCLastFinePortamentoUpParam = paramY; - jmpChangePitch(mp, channel, -(mp->iCLastFinePortamentoUpParam[channel] * 4)); + jmpChangePitch(chn, channel, -(chn->iCLastFinePortamentoUpParam * 4)); break; case 0x02: // E2x - Fine Portamento Down if (paramY) - mp->iCLastFinePortamentoDownParam[channel] = paramY; + chn->iCLastFinePortamentoDownParam = paramY; - jmpChangePitch(mp, channel, (mp->iCLastFinePortamentoDownParam[channel] * 4)); + jmpChangePitch(chn, channel, (chn->iCLastFinePortamentoDownParam * 4)); break; case 0x03: // E3x - Glissando Control (NOT SUPPORTED) break; case 0x04: // E4x - Set Vibrato waveform - mp->iVibratoWC[channel] = paramY; + chn->iVibratoWC = paramY; break; case 0x05: // E5x - Set Finetune @@ -1053,15 +970,15 @@ break; case 0x06: // E6x - Set Pattern Loop - jmpDoPatternLoop(mp, channel, paramY); + jmpDoPatternLoop(mp, chn, channel, paramY); break; case 0x07: // E7x - Set Tremolo waveform - mp->iTremoloWC[channel] = paramY; + chn->iTremoloWC = paramY; break; case 0x08: // E8x - Set Pan Position - mp->iCPanning[channel] = (paramY * 16); + chn->iCPanning = (paramY * 16); JMPSETNDFLAGS(cdfNewPanPos); break; @@ -1071,15 +988,15 @@ case 0x0a: // EAx - Fine Volumeslide Up if (paramY) - mp->iCLastFineVolumeslideUpParam[channel] = paramY; + chn->iCLastFineVolumeslideUpParam = paramY; - jmpChangeVolume(mp, channel, mp->iCLastFineVolumeslideUpParam[channel]); + jmpChangeVolume(chn, channel, chn->iCLastFineVolumeslideUpParam); break; case 0x0b: // EBx - Fine Volumeslide Down if (paramY) - mp->iCLastFineVolumeslideDownParam[channel] = paramY; - jmpChangeVolume(mp, channel, -(mp->iCLastFineVolumeslideDownParam[channel])); + chn->iCLastFineVolumeslideDownParam = paramY; + jmpChangeVolume(chn, channel, -(chn->iCLastFineVolumeslideDownParam)); break; case 0x0c: // ECx - Set Note Cut (NOT PROCESSED IN TICK0) @@ -1089,14 +1006,14 @@ if (paramY > 0) { // Save the ND-flags, then clear - mp->iSaveNDFlags[channel] = mp->iCNewDataFlags[channel]; - mp->iCNewDataFlags[channel] = 0; + chn->iSaveNDFlags = chn->iCNewDataFlags; + chn->iCNewDataFlags = 0; // TODO .. does this only affect NOTE or also instrument? } break; case 0x0e: // EEx - Set Pattern Delay : IMPL.VERIFIED - mp->iPatternDelay = paramY; + mp->patternDelay = paramY; break; case 0x0f: // EFx - Invert Loop (NOT SUPPORTED) @@ -1112,14 +1029,14 @@ if (param > 0) { if (param < 0x20) - mp->iSpeed = param; + mp->speed = param; else jmpSetTempo(mp, param); } break; case 'G': // Gxx = Global Volume - mp->iGlobalVol = param; + mp->globalVol = param; JMPSETNDFLAGS(cdfNewGlobalVol); break; @@ -1129,15 +1046,15 @@ break; case 'K': // Kxx = Key-off (Same as key-off note) - mp->iCKeyOff[channel] = TRUE; + chn->iCKeyOff = TRUE; break; case 'L': // Lxx = Set Envelope Position JMPDEBUG("Set Envelope Position used, NOT verified with FT2"); - mp->iCPanEnv_Frames[channel] = param; - mp->iCVolEnv_Frames[channel] = param; - mp->iCPanEnv_Exec[channel] = TRUE; - mp->iCVolEnv_Exec[channel] = TRUE; + chn->iCPanEnv_Frames = param; + chn->iCVolEnv_Frames = param; + chn->iCPanEnv_Exec = TRUE; + chn->iCVolEnv_Exec = TRUE; break; case 'R': // Rxy = Multi Retrig note @@ -1146,7 +1063,7 @@ case 'T': // Txy = Tremor if (param) - mp->iLastTremorParam[channel] = param; + chn->iLastTremorParam = param; break; case 'X': // Xxy = Extra Fine Portamento @@ -1154,16 +1071,16 @@ { case 0x01: // X1y - Extra Fine Portamento Up if (paramY) - mp->iCLastExtraFinePortamentoUpParam[param] = paramY; + chn->iCLastExtraFinePortamentoUpParam = paramY; - jmpChangePitch(mp, channel, -(mp->iCLastExtraFinePortamentoUpParam[param])); + jmpChangePitch(chn, channel, - chn->iCLastExtraFinePortamentoUpParam); break; case 0x02: // X2y - Extra Fine Portamento Down if (paramY) - mp->iCLastExtraFinePortamentoDownParam[param] = paramY; + chn->iCLastExtraFinePortamentoDownParam = paramY; - jmpChangePitch(mp, channel, mp->iCLastExtraFinePortamentoUpParam[param]); + jmpChangePitch(chn, channel, chn->iCLastExtraFinePortamentoUpParam); break; default: @@ -1186,32 +1103,34 @@ JSSInstrument *inst = NULL; BOOL newNote = FALSE; int tmp, paramX, paramY; + JSSPlayerChannel *chn = &(mp->channels[channel]); - JMPGETNOTE(currNote, mp->iRow, channel); + JMPGETNOTE(currNote, mp->row, channel); // Check for a new note/keyoff here if (currNote->note == jsetNoteOff) - mp->iCKeyOff[channel] = TRUE; + chn->iCKeyOff = TRUE; else if (currNote->note >= 0 && currNote->note <= 96) { // New note was set newNote = TRUE; - mp->iCNote[channel] = currNote->note; + chn->iCNote = currNote->note; } // Check for new instrument - if (currNote->instrument != jsetNotSet) { + if (currNote->instrument != jsetNotSet) + { /* Envelopes and ext.instrument fadeout are initialized always if * new instrument is set, even if the instrument does not exist. */ - jmpResetEnvelopes(mp, channel); - mp->iCKeyOff[channel] = FALSE; - mp->iCFadeOutVol[channel] = mpMaxFadeoutVol; + jmpResetEnvelopes(chn); + chn->iCKeyOff = FALSE; + chn->iCFadeOutVol = mpMaxFadeoutVol; // We save the instrument number here for later use - if (currNote->instrument >= 0 && currNote->instrument < mp->pModule->nextInstruments) - mp->iCExtInstrumentN[channel] = currNote->instrument; + if (currNote->instrument >= 0 && currNote->instrument < mp->module->nextInstruments) + chn->iCExtInstrumentN = currNote->instrument; } /* ONLY if newNote was SET NOW and ExtInstrument HAS BEEN set, we can @@ -1219,16 +1138,16 @@ */ if (newNote) { - if (mp->iCExtInstrumentN[channel] != jsetNotSet) - extInst = mp->pModule->extInstruments[mp->iCExtInstrumentN[channel]]; + if (chn->iCExtInstrumentN != jsetNotSet) + extInst = mp->module->extInstruments[chn->iCExtInstrumentN]; else extInst = NULL; if (extInst) { // Set instrument - int note = mp->iCNote[channel]; - mp->iCExtInstrument[channel] = extInst; + int note = chn->iCNote; + chn->iCExtInstrument = extInst; // We set new Instrument ONLY if NEW NOTE has been set if (note != jsetNotSet) @@ -1236,14 +1155,14 @@ // Get instrument number tmp = extInst->sNumForNotes[note]; - if (tmp >= 0 && tmp < mp->pModule->ninstruments) { + if (tmp >= 0 && tmp < mp->module->ninstruments) { // Set the new instrument - inst = mp->pModule->instruments[tmp]; - mp->iCInstrumentN[channel] = tmp; - mp->iCInstrument[channel] = inst; - mp->iCVolume[channel] = inst->volume; - mp->iCPanning[channel] = inst->EPanning; - mp->iCPosition[channel] = 0; + inst = mp->module->instruments[tmp]; + chn->iCInstrumentN = tmp; + chn->iCInstrument = inst; + chn->iCVolume = inst->volume; + chn->iCPanning = inst->EPanning; + chn->iCPosition = 0; // Set NDFlags JMPSETNDFLAGS(cdfNewInstr | cdfNewPos | cdfNewPanPos | cdfNewVolume); @@ -1255,17 +1174,17 @@ if (inst) { // Save old pitch for later use - mp->iCOldPitch[channel] = mp->iCPitch[channel]; + chn->iCOldPitch = chn->iCPitch; // Compute new pitch - tmp = (mp->iCNote[channel] + inst->ERelNote); -//fprintf(stderr, "HEH: %d + %d = %d\n", mp->iCNote[channel], inst->ERelNote, tmp); + tmp = (chn->iCNote + inst->ERelNote); +//fprintf(stderr, "HEH: %d + %d = %d\n", chn->iCNote, inst->ERelNote, tmp); if (tmp < 0) tmp = 0; else if (tmp > 119) tmp = 119; - mp->iCPitch[channel] = jmpGetPeriodFromNote(mp, tmp, inst->EFineTune); + chn->iCPitch = jmpGetPeriodFromNote(mp, tmp, inst->EFineTune); JMPSETNDFLAGS(cdfNewPitch); } @@ -1279,33 +1198,33 @@ case 0x02: case 0x03: case 0x04: - jmpSetVolume(mp, channel, currNote->volume); + jmpSetVolume(chn, channel, currNote->volume); break; case 0x07: // Dx = Fine Volumeslide Down : IMPL.VERIFIED - jmpChangeVolume(mp, channel, -paramY); + jmpChangeVolume(chn, channel, -paramY); break; case 0x08: // Ux = Fine Volumeslide Up : IMPL.VERIFIED - jmpChangeVolume(mp, channel, paramY); + jmpChangeVolume(chn, channel, paramY); break; case 0x09: // Sx = Set vibrato speed : IMPL.VERIFIED - mp->iVibratoSpeed[channel] = paramY; + chn->iVibratoSpeed = paramY; break; case 0x0a: // Vx = Vibrato : IMPL.VERIFIED if (paramY) - mp->iVibratoDepth[channel] = paramY; + chn->iVibratoDepth = paramY; break; case 0x0e: // Mx = Porta To Note : IMPL.VERIFIED if (paramY) - mp->iLastPortaToNoteParam[channel] = paramY; + chn->iLastPortaToNoteParam = paramY; if (currNote->note != jsetNotSet && currNote->note != jsetNoteOff) { - mp->iLastPortaToNotePitch[channel] = mp->iCPitch[channel]; - mp->iCPitch[channel] = mp->iCOldPitch[channel]; + chn->iLastPortaToNotePitch = chn->iCPitch; + chn->iCPitch = chn->iCOldPitch; JMPUNSETNDFLAGS(cdfNewPitch | cdfNewInstr | cdfNewPanPos); } break; @@ -1319,30 +1238,31 @@ static void jmpProcessEffects(JSSPlayer * mp, int channel) { + JSSPlayerChannel *chn = &(mp->channels[channel]); JSSNote *currNote; int param, paramX, paramY, tmp; char effect; // Process the volume column effects - JMPGETNOTE(currNote, mp->iRow, channel); + JMPGETNOTE(currNote, mp->row, channel); JMPMAKEPARAM(currNote->volume, paramX, paramY); switch (paramX) { case 0x05: // -x = Volumeslide Down : IMPL.VERIFIED - jmpChangeVolume(mp, channel, -paramY); + jmpChangeVolume(chn, channel, -paramY); break; case 0x06: // +x = Volumeslide Down : IMPL.VERIFIED - jmpChangeVolume(mp, channel, paramY); + jmpChangeVolume(chn, channel, paramY); break; case 0x0a: // Vx = Vibrato : IMPL.VERIFIED - jmpDoVibrato(mp, channel); + jmpDoVibrato(mp, chn, channel); break; case 0x0e: // Mx = Porta To Note : IMPL.VERIFIED - jmpDoPortamento(mp, channel); + jmpDoPortamento(chn, channel); break; } @@ -1357,71 +1277,71 @@ switch (effect) { case '0': // 0xy = Arpeggio - jmpDoArpeggio(mp, channel, paramX, paramY); + jmpDoArpeggio(mp, chn, channel, paramX, paramY); break; case '1': // 1xy = Portamento Up - if (mp->iLastPortaParam[channel] > 0) - jmpChangePitch(mp, channel, -(mp->iLastPortaParam[channel] * 4)); + if (chn->iLastPortaParam > 0) + jmpChangePitch(chn, channel, -(chn->iLastPortaParam * 4)); break; case '2': // 2xy = Portamento Down - if (mp->iLastPortaParam[channel] > 0) - jmpChangePitch(mp, channel, (mp->iLastPortaParam[channel] * 4)); + if (chn->iLastPortaParam > 0) + jmpChangePitch(chn, channel, (chn->iLastPortaParam * 4)); break; case '3': // 3xy = Porta To Note - jmpDoPortamento(mp, channel); + jmpDoPortamento(chn, channel); break; case '4': // 4xy = Vibrato - jmpDoVibrato(mp, channel); + jmpDoVibrato(mp, chn, channel); break; case '5': // 5xy = Portamento + Volume Slide - jmpDoPortamento(mp, channel); - jmpDoVolumeSlide(mp, channel, mp->iLastVolSlideParam[channel]); + jmpDoPortamento(chn, channel); + jmpDoVolumeSlide(chn, channel, chn->iLastVolSlideParam); break; case '6': // 6xy = Vibrato + Volume Slide - jmpDoVibrato(mp, channel); - jmpDoVolumeSlide(mp, channel, mp->iLastVolSlideParam[channel]); + jmpDoVibrato(mp, chn, channel); + jmpDoVolumeSlide(chn, channel, chn->iLastVolSlideParam); break; case '7': // 7xy = Tremolo - jmpDoTremolo(mp, channel); + jmpDoTremolo(mp, chn, channel); break; case 'A': // Axy = Volume slide - jmpDoVolumeSlide(mp, channel, mp->iLastVolSlideParam[channel]); + jmpDoVolumeSlide(chn, channel, chn->iLastVolSlideParam); break; case 'E': // Exy = Special Effects switch (paramX) { case 0x0c: // ECx - Set Note Cut - if (mp->iTick == paramY) - jmpSetVolume(mp, channel, jsetMinVol); + if (mp->tick == paramY) + jmpSetVolume(chn, channel, jsetMinVol); break; case 0x0d: // EDx - Set Note Delay - if (mp->iTick == paramY) - mp->iCNewDataFlags[channel] = mp->iSaveNDFlags[channel]; + if (mp->tick == paramY) + chn->iCNewDataFlags = chn->iSaveNDFlags; break; } break; case 'T': // Txy = Tremor - JMPMAKEPARAM(mp->iLastTremorParam[channel], paramX, paramY) + JMPMAKEPARAM(chn->iLastTremorParam, paramX, paramY) paramX++; paramY++; - tmp = (mp->iTremorCount[channel] % (paramX + paramY)); + tmp = (chn->iTremorCount % (paramX + paramY)); if (tmp < paramX) - jmpCSetVolume(mp, channel, mp->iCVolume[channel]); + jmpCSetVolume(mp, chn, channel, chn->iCVolume); else - jmpCSetVolume(mp, channel, jsetMinVol); + jmpCSetVolume(mp, chn, channel, jsetMinVol); - mp->iTremorCount[channel] = (tmp + 1); + chn->iTremorCount = (tmp + 1); break; } } @@ -1443,8 +1363,8 @@ JSS_LOCK(mp); dev = (JSSMixer *) pDEV; - assert(mp->pDevice == dev); - assert(mp->pModule != NULL); + assert(mp->device == dev); + assert(mp->module != NULL); // Check if we are playing if (!mp->isPlaying) @@ -1453,64 +1373,66 @@ // Clear channel new data flags mp->jumpFlag = FALSE; mp->breakFlag = FALSE; - memset(mp->iCNewDataFlags, 0, sizeof(mp->iCNewDataFlags)); -//fprintf(stderr, "1: iTick=%d, iOrder=%d, iPattern=%d, iRow=%d\n", mp->iTick, mp->iOrder, mp->iPattern, mp->iRow); + for (channel = 0; channel < jsetNChannels; channel++) + mp->channels[channel].iCNewDataFlags = 0; + +//fprintf(stderr, "1: tick=%d, order=%d, iPattern=%d, row=%d\n", mp->tick, mp->order, mp->npattern, mp->row); // Check for init-tick - if (mp->iTick < 0) + if (mp->tick < 0) { // Initialize pattern - if (mp->iOrder != jsetNotSet) - jmpSetNewOrder(mp, mp->iOrder); + if (mp->order != jsetNotSet) + jmpSetNewOrder(mp, mp->order); - mp->iNewRow = 0; + mp->newRow = 0; mp->newRowSet = TRUE; - mp->iTick = mp->iSpeed; + mp->tick = mp->speed; } -//fprintf(stderr, "2: iTick=%d, iOrder=%d, iPattern=%d, iRow=%d\n", mp->iTick, mp->iOrder, mp->iPattern, mp->iRow); +//fprintf(stderr, "2: tick=%d, order=%d, iPattern=%d, row=%d\n", mp->tick, mp->order, mp->npattern, mp->row); // Check if we are playing if (!mp->isPlaying) goto out; - assert(mp->pPattern); + assert(mp->pattern); // Update the tick - mp->iTick++; - if (mp->iTick >= mp->iSpeed) + mp->tick++; + if (mp->tick >= mp->speed) { // Re-init tick counter - mp->iTick = 0; + mp->tick = 0; // Check pattern delay - if (mp->iPatternDelay > 0) - mp->iPatternDelay--; + if (mp->patternDelay > 0) + mp->patternDelay--; else { // New pattern row if (mp->newRowSet) { - mp->iRow = mp->iNewRow; + mp->row = mp->newRow; mp->newRowSet = FALSE; } else - mp->iRow++; + mp->row++; // Check for end of pattern - if (mp->iRow >= mp->pPattern->nrows) + if (mp->row >= mp->pattern->nrows) { // Go to next order - if (mp->iOrder != jsetNotSet) - jmpSetNewOrder(mp, mp->iOrder + 1); + if (mp->order != jsetNotSet) + jmpSetNewOrder(mp, mp->order + 1); else mp->isPlaying = FALSE; // Check for FT2 quirks if (JMPGETMODFLAGS(mp, jmdfFT2Replay)) - mp->iRow = mp->iLastPatLoopRow; + mp->row = mp->lastPatLoopRow; else - mp->iRow = 0; + mp->row = 0; } if (!mp->isPlaying) @@ -1519,28 +1441,28 @@ // Check current order if (mp->newOrderSet) { - jmpSetNewOrder(mp, mp->iNewOrder); + jmpSetNewOrder(mp, mp->newOrder); mp->newOrderSet = FALSE; } -//fprintf(stderr, "3: iTick=%d, iOrder=%d, iPattern=%d, iRow=%d\n", mp->iTick, mp->iOrder, mp->iPattern, mp->iRow); +//fprintf(stderr, "3: tick=%d, order=%d, iPattern=%d, row=%d\n", mp->tick, mp->order, mp->npattern, mp->row); if (!mp->isPlaying) goto out; // TICK #0: Process new row - for (channel = 0; channel < mp->pModule->nchannels; channel++) + for (channel = 0; channel < mp->module->nchannels; channel++) jmpProcessNewRow(mp, channel); - } // iPatternDelay - } // iTick + } // patternDelay + } // tick else { // Implement FT2's pattern delay-effect: don't update effects while on patdelay if (!JMPGETMODFLAGS(mp, jmdfFT2Replay) || - (JMPGETMODFLAGS(mp, jmdfFT2Replay) && mp->iPatternDelay <= 0)) + (JMPGETMODFLAGS(mp, jmdfFT2Replay) && mp->patternDelay <= 0)) { // TICK n: Process the effects - for (channel = 0; channel < mp->pModule->nchannels; channel++) + for (channel = 0; channel < mp->module->nchannels; channel++) jmpProcessEffects(mp, channel); } } @@ -1550,41 +1472,52 @@ goto out; // Update player data to audio device/mixer - for (channel = 0; channel < mp->pModule->nchannels; channel++) + for (channel = 0; channel < mp->module->nchannels; channel++) { + JSSPlayerChannel *chn = &mp->channels[channel]; + // Process extended instruments - jmpProcessExtInstrument(mp, channel); + jmpProcessExtInstrument(mp, chn, channel); // Check NDFlags and update channel data - flags = mp->iCNewDataFlags[channel]; + flags = chn->iCNewDataFlags; if (flags) { // Check if we stop? if (flags & cdfStop) - jmpCStop(mp, channel); + { + jvmStop(mp->device, channel); + } else { // No, handle other flags if (flags & cdfNewInstr) { - jmpCSetInstrument(mp, channel); - jmpCPlay(mp, channel); + JSSInstrument *instr = chn->iCInstrument; + if (instr != NULL) + { + jvmSetSample(mp->device, channel, + instr->data, instr->size, + instr->loopS, instr->loopE, + instr->flags); + } + jvmPlay(mp->device, channel); } if (flags & cdfNewPitch) - jmpCSetPitch(mp, channel, mp->iCPitch[channel]); + jmpCSetPitch(mp, channel, chn->iCPitch); if (flags & cdfNewPos) - jmpCSetPosition(mp, channel, mp->iCPosition[channel]); + jmpCSetPosition(mp, channel, chn->iCPosition); if (flags & cdfNewVolume) - jmpCSetVolume(mp, channel, mp->iCVolume[channel]); + jmpCSetVolume(mp, chn, channel, chn->iCVolume); if (flags & cdfNewPanPos) - jmpCSetPanning(mp, channel, mp->iCPanning[channel]); + jmpCSetPanning(mp, chn, channel, chn->iCPanning); if (flags & cdfNewGlobalVol) - jvmSetGlobalVol(mp->pDevice, mp->iGlobalVol); + jvmSetGlobalVol(mp->device, mp->globalVol); } } }
--- a/jssplr.h Mon Oct 01 04:18:15 2012 +0300 +++ b/jssplr.h Mon Oct 01 06:28:29 2012 +0300 @@ -29,40 +29,11 @@ #define cdfStop (0x80) // Stop channel playing -// Typedefs for channel structures -typedef int JDInt[jsetNChannels]; -typedef BOOL JDBool[jsetNChannels]; -typedef JSSInstrument * JDInst[jsetNChannels]; -typedef JSSExtInstrument * JDEInst[jsetNChannels]; - - -// Struct holding all player related information +// Player channel structure typedef struct { - // General variables - int iTempo, // Current values - iSpeed, - iTick, - iOrder, - iPattern, - iRow, - iGlobalVol, - iOptions; // Playing option flags - BOOL isPlaying; // Are we playing? - - int iNewOrder, // NEW order number - iNewRow; // NEW row number - BOOL newOrderSet, // TRUE if new order has been set - newRowSet; // TRUE if new row has been set - - // Parameters for effects, etc - BOOL jumpFlag, // Pattern jump flag - breakFlag; // Pattern break flag - int iPatternDelay, // Pattern delay tick-counter - iLastPatLoopRow; // Latest set pattern loop row (any channel) - - JDInt iPatLoopRow, // Pattern loop start row for each channel - iPatLoopCount, // Pattern loop count for each channel + int iPatLoopRow, // Pattern loop start row + iPatLoopCount, // Pattern loop count iLastPortaParam, // Last portamento effect parameter iLastPortaToNoteParam, // Last porta-to-note parameter @@ -89,17 +60,18 @@ iSaveNDFlags; // For notedelay-effect // Current channel data - JDInst iCInstrument; // Instruments - JDEInst iCExtInstrument; // ExtInstruments - JDInt iCInstrumentN, + JSSInstrument *iCInstrument; // Instrument + JSSExtInstrument *iCExtInstrument; // ExtInstrument + int iCInstrumentN, iCExtInstrumentN, + iCNote, // Current note + iCPitch, // Pitch (NOT actual frequency!) + iCOldPitch, + iCPosition, // Sample position + iCVolume, // Volume + iCPanning, // Panning position + iCNewDataFlags, // New data flags - iCNote, // Current notes - iCPitch, // Pitches (NOT actual frequencies!) - iCOldPitch, - iCPosition, // Sample positions - iCVolume, // Volumes - iCPanning, // Panning positions iCFadeOutVol, @@ -117,14 +89,47 @@ iCLastFinePortamentoUpParam, iCLastFinePortamentoDownParam; - JDBool iCPanEnv_Exec, + BOOL iCPanEnv_Exec, iCVolEnv_Exec, iCKeyOff; +} JSSPlayerChannel; + + +// Struct holding all player related information +typedef struct +{ + // General variables + int tempo, // Current values + speed, + tick, + order, + npattern, + row, + globalVol, + options; // Playing option flags + BOOL isPlaying; // Are we playing? + + int newOrder, // NEW order number + newRow; // NEW row number + BOOL newOrderSet, // TRUE if new order has been set + newRowSet; // TRUE if new row has been set + + int patternDelay, // Pattern delay tick-counter + lastPatLoopRow; // Latest set pattern loop row (any channel) + + + // All channels for this player +// int nchannels; + JSSPlayerChannel channels[jsetNChannels]; + + // Parameters for effects, etc + BOOL jumpFlag, // Pattern jump flag + breakFlag; // Pattern break flag // Module and sounddevice specific - JSSModule *pModule; // Current module in this player - JSSPattern *pPattern; // Current pattern - JSSMixer *pDevice; // Pointer to mixing device structure + JSSModule *module; // Current module in this player + JSSPattern *pattern; // Current pattern + JSSMixer *device; // Pointer to mixing device structure #ifdef JSS_SUP_THREADS DMMutex *mutex; @@ -148,11 +153,11 @@ /* Helper macros */ #define JMPMAKEPARAM(AIVAL, AVALX, AVALY) { AVALX = (((AIVAL) >> 4) & 0x0f); AVALY = ((AIVAL) & 0x0f); } -#define JMPSETNDFLAGS(IVAL) mp->iCNewDataFlags[channel] |= IVAL -#define JMPUNSETNDFLAGS(IVAL) mp->iCNewDataFlags[channel] &= (~(IVAL)) -#define JMPGETNOTE(MNOTE, MROW, MCHAN) assert(mp); assert(mp->pPattern); assert((MROW) >= 0); assert((MROW) < mp->pPattern->nrows); MNOTE = &mp->pPattern->data[(mp->pPattern->nchannels * MROW) + (MCHAN)] +#define JMPSETNDFLAGS(IVAL) chn->iCNewDataFlags |= IVAL +#define JMPUNSETNDFLAGS(IVAL) chn->iCNewDataFlags &= (~(IVAL)) +#define JMPGETNOTE(MNOTE, MROW, MCHAN) assert(mp); assert(mp->pattern); assert((MROW) >= 0); assert((MROW) < mp->pattern->nrows); MNOTE = &mp->pattern->data[(mp->pattern->nchannels * MROW) + (MCHAN)] #define JMPGETEFFECT(MEFF, MIEFF) if ((MIEFF >= 0) && (MIEFF < jmpNMODEffectTable)) MEFF = jmpMODEffectTable[MIEFF]; else MEFF = 0 -#define JMPGETMODFLAGS(Q, Z) ((Q->pModule->defFlags & (Z)) == (Z)) +#define JMPGETMODFLAGS(Q, Z) ((Q->module->defFlags & (Z)) == (Z)) /* Debugging macros
--- a/testpl.c Mon Oct 01 04:18:15 2012 +0300 +++ b/testpl.c Mon Oct 01 06:28:29 2012 +0300 @@ -247,11 +247,11 @@ SDL_PauseAudio(0); while (p->isPlaying) { - int r = p->iRow; - while (r == p->iRow && p->isPlaying) + int r = p->row; + while (r == p->row && p->isPlaying) SDL_Delay(50); - printRow(stdout, p->pPattern, p->iRow); + printRow(stdout, p->pattern, p->row); printf("\n"); }