void testStopLoopedSong() { TEST_SETUP(); SIMSG_SEND(it, SIMSG_SET_LOOPS(3)); message = songit_next(&it, &cmds, &result, IT_READER_MASK_ALL); TESTEQUAL(0xAA, message); SIMSG_SEND(it, SIMSG_STOP); message = songit_next(&it, &cmds, &result, IT_READER_MASK_ALL); TESTEQUAL(SI_FINISHED, message); TEST_TEARDOWN(); }
void testChangeSongMask() { TEST_SETUP(); message = songit_next(&it, &cmds, &result, IT_READER_MASK_ALL); TESTEQUAL(0xAA, message); SIMSG_SEND(it, SIMSG_SET_PLAYMASK(0x40)); message = songit_next(&it, &cmds, &result, IT_READER_MASK_ALL); TESTEQUAL(0, message); TESTEQUAL(0, result); TEST_TEARDOWN(); }
void testMultipleDeathListeners() { TEST_SETUP(); song_iterator_add_death_listener( it, it, (void (*)(void *, void*))DeathListenerCallback); song_iterator_add_death_listener( it, it, (void (*)(void *, void*))DeathListenerCallback); for (i=0; i < SONG_CMD_COUNT; i++) { message = songit_next(&it, &cmds, &result, IT_READER_MASK_ALL); } TESTEQUAL(SI_FINISHED, message); TEST_TEARDOWN(); TESTEQUAL(2, calledDeathListenerCallback); }
void testFinishSong() { TEST_SETUP(); message = songit_next(&it, &cmds, &result, IT_READER_MASK_ALL); TESTEQUAL(0xAA, message); message = songit_next(&it, &cmds, &result, IT_READER_MASK_ALL); TESTEQUAL(0, message); TESTEQUAL(3, result); for (i=0; i < SONG_CMD_COUNT - 2; i++) { message = songit_next(&it, &cmds, &result, IT_READER_MASK_ALL); } TESTEQUAL(SI_FINISHED, message); TEST_TEARDOWN(); }
int TeeSongIterator::nextCommand(byte *buf, int *result) { static const int ready_masks[2] = {TEE_LEFT_READY, TEE_RIGHT_READY}; static const int active_masks[2] = {TEE_LEFT_ACTIVE, TEE_RIGHT_ACTIVE}; static const int pcm_masks[2] = {TEE_LEFT_PCM, TEE_RIGHT_PCM}; int i; int retid; #ifdef DEBUG_TEE_ITERATOR fprintf(stderr, "[Tee] %02x\n", _status); #endif if (!(_status & (TEE_LEFT_ACTIVE | TEE_RIGHT_ACTIVE))) /* None is active? */ return SI_FINISHED; if (_readyToMorph) return SI_MORPH; if ((_status & (TEE_LEFT_ACTIVE | TEE_RIGHT_ACTIVE)) != (TEE_LEFT_ACTIVE | TEE_RIGHT_ACTIVE)) { /* Not all are is active? */ int which = 0; #ifdef DEBUG_TEE_ITERATOR fprintf(stderr, "\tRequesting transformation...\n"); #endif if (_status & TEE_LEFT_ACTIVE) which = TEE_LEFT; else if (_status & TEE_RIGHT_ACTIVE) which = TEE_RIGHT; memcpy(buf, _children[which].buf, sizeof(buf)); *result = _children[which].result; _readyToMorph = true; return _children[which].retval; } /* First, check for unreported PCMs */ for (i = TEE_LEFT; i <= TEE_RIGHT; i++) if ((_status & (ready_masks[i] | pcm_masks[i])) == (ready_masks[i] | pcm_masks[i])) { _status &= ~ready_masks[i]; return SI_PCM; } for (i = TEE_LEFT; i <= TEE_RIGHT; i++) if (!(_status & ready_masks[i])) { /* Buffers aren't ready yet */ _children[i].retval = songit_next(&(_children[i].it), _children[i].buf, &(_children[i].result), IT_READER_MASK_ALL | IT_READER_MAY_FREE | IT_READER_MAY_CLEAN); _status |= ready_masks[i]; #ifdef DEBUG_TEE_ITERATOR fprintf(stderr, "\t Must check %d: %d\n", i, _children[i].retval); #endif if (_children[i].retval == SI_ABSOLUTE_CUE || _children[i].retval == SI_RELATIVE_CUE) return _children[i].retval; if (_children[i].retval == SI_FINISHED) { _status &= ~active_masks[i]; /* Recurse to complete */ #ifdef DEBUG_TEE_ITERATOR fprintf(stderr, "\t Child %d signalled completion, recursing w/ status %02x\n", i, _status); #endif return nextCommand(buf, result); } else if (_children[i].retval == SI_PCM) { _status |= pcm_masks[i]; _status &= ~ready_masks[i]; return SI_PCM; } } /* We've already handled PCM, MORPH and FINISHED, CUEs & LOOP remain */ retid = TEE_LEFT; if ((_children[TEE_LEFT].retval > 0) /* Asked to delay */ && (_children[TEE_RIGHT].retval <= _children[TEE_LEFT].retval)) /* Is not delaying or not delaying as much */ retid = TEE_RIGHT; #ifdef DEBUG_TEE_ITERATOR fprintf(stderr, "\tl:%d / r:%d / chose %d\n", _children[TEE_LEFT].retval, _children[TEE_RIGHT].retval, retid); #endif #if 0 if (_children[retid].retval == 0) { /* Perform remapping, if neccessary */ byte *buf = _children[retid].buf; if (*buf != SCI_MIDI_SET_SIGNAL && *buf < 0xf0) { /* Not a generic command */ int chan = *buf & 0xf; int op = *buf & 0xf0; chan = _children[retid].channel_remap[chan]; *buf = chan | op; } } #endif /* Adjust delta times */ if (_children[retid].retval > 0 && _children[1-retid].retval > 0) { if (_children[1-retid].retval == _children[retid].retval) /* If both _children wait the same amount of time, ** we have to re-fetch commands from both */ _status &= ~ready_masks[1-retid]; else /* If they don't, we can/must re-use the other ** child's delay time */ _children[1-retid].retval -= _children[retid].retval; } _status &= ~ready_masks[retid]; memcpy(buf, _children[retid].buf, sizeof(buf)); *result = _children[retid].result; return _children[retid].retval; }