| 746 | } |
| 747 | |
| 748 | s32 ImJumpMidiInternal(ImPlayerData* data, s32 chunk, s32 measure, s32 beat, s32 tick, s32 sustain) |
| 749 | { |
| 750 | u8* sndData = ImInternalGetSoundData(data->soundId); |
| 751 | if (!sndData) { return imInvalidSound; } |
| 752 | |
| 753 | measure--; |
| 754 | beat--; |
| 755 | chunk--; |
| 756 | if (measure >= 1000 || beat >= 12 || tick >= 480) |
| 757 | { |
| 758 | return imArgErr; |
| 759 | } |
| 760 | |
| 761 | ImMidiLock(); |
| 762 | memcpy(&s_imSoundPrevState, data, sizeof(ImPlayerData)); |
| 763 | memcpy(&s_imSoundNextState, data, sizeof(ImPlayerData)); |
| 764 | |
| 765 | IM_DBG_MSG("JMP c:%d t:%03d.%02d.%03d -> c:%d t:%03d.%02d.%03d [s:%d]", s_imSoundNextState.seqIndex, ImTime_getMeasure(data->nextTick), ImTime_getBeat(data->nextTick), ImTime_getTicks(data->nextTick), chunk, measure, beat, tick, sustain); |
| 766 | u32 nextTick = ImFixupSoundTick(data, ImTime_setMeasure(measure) + ImTime_setBeat(beat) + ImTime_setTick(tick)); |
| 767 | // If we either change chunks or jump backwards, the sequence needs to be setup/reset. |
| 768 | if (chunk != s_imSoundNextState.seqIndex || nextTick < (u32)s_imSoundNextState.nextTick) |
| 769 | { |
| 770 | if (ImSetSequence(&s_imSoundNextState, sndData, chunk)) |
| 771 | { |
| 772 | IM_LOG_ERR("%s", "sq jump to invalid chunk."); |
| 773 | ImMidiUnlock(); |
| 774 | return imFail; |
| 775 | } |
| 776 | } |
| 777 | s_imSoundNextState.nextTick = nextTick; |
| 778 | ImAdvanceMidi(&s_imSoundNextState, sndData, s_jumpMidiCmdFunc); |
| 779 | if (s_imEndOfTrack) |
| 780 | { |
| 781 | IM_LOG_WRN("sq jump to invalid ms:bt:tk...", NULL); |
| 782 | ImMidiUnlock(); |
| 783 | return imFail; |
| 784 | } |
| 785 | |
| 786 | if (sustain) |
| 787 | { |
| 788 | // Loop through the channels. |
| 789 | for (s32 c = 0; c < MIDI_CHANNEL_COUNT; c++) |
| 790 | { |
| 791 | ImMidiCommand(data->player, c, MID_SUSTAIN_SWITCH, 0); |
| 792 | ImMidiCommand(data->player, c, MID_MODULATIONWHEEL_MSB, 0); |
| 793 | ImHandleChannelPitchBend(data->player, c, 0, imPanCenter); |
| 794 | } |
| 795 | ImJumpSustain(data->player, sndData, &s_imSoundPrevState, &s_imSoundNextState); |
| 796 | } |
| 797 | else |
| 798 | { |
| 799 | ImMidiStopAllNotes(data->player); |
| 800 | } |
| 801 | |
| 802 | memcpy(data, &s_imSoundNextState, sizeof(ImPlayerData)); |
| 803 | s_imEndOfTrack = 1; |
| 804 | ImMidiUnlock(); |
| 805 |
no test coverage detected