static void I_OPL_SetMusicVolume(int volume) { unsigned int i; // Internal state variable. current_music_volume = volume; // Update the volume of all voices. for (i=0; i<OPL_NUM_VOICES; ++i) { if (voices[i].channel != NULL) { SetVoiceVolume(&voices[i], voices[i].note_volume); } } }
bool Ims::Reset(void) { if (m_ims == NULL) return false; // YM3812ResetChip(ym3812p); ResetChip(); SndOutput(1, 0x20); // Enable waveform select (bit 5) SetMode(m_ims->header.nSoundMode); for (int i=0; i<MAX_VOICE; i++) { NoteOff(i); SetVoiceVolume(i, 0); } Rewind(); return true; }
int Ims::PlayEvent(void) { static unsigned char stCode; unsigned char curCode; int delay, delayTime = 0; int voice, note, volume, index; int *paramArray; unsigned short int pitchBend; int instIndexInBnk; again: curCode = m_ims->songData[m_songDataIndex]; //fflush(stdout); //return (nElapsed * MAX_SLIDER_PROGRESS / m_cbImsDataSize); // 0x7F == 127 if (curCode > 0x7F) { m_songDataIndex++; stCode = curCode; } else curCode = stCode; voice = curCode & 0x0F; // 오른쪽 4비트를 얻는다 (채널 번호) // 왼쪽 4비트에 이벤트 종류가 저장되어 있다 switch (curCode & 0xF0) { case 0x80: // note off note = m_ims->songData[m_songDataIndex]; volume = m_ims->songData[m_songDataIndex + 1]; NoteOff(voice); SetVoiceVolume(voice, volume); NoteOn(voice, note); m_songDataIndex += 2; break; case 0x90: // note on note = m_ims->songData[m_songDataIndex]; volume = m_ims->songData[m_songDataIndex + 1]; NoteOff(voice); if (volume) { SetVoiceVolume(voice, volume); NoteOn(voice, note); } m_songDataIndex += 2; break; case 0xA0: // Set volume volume = m_ims->songData[m_songDataIndex]; SetVoiceVolume(voice, volume); m_songDataIndex++; break; case 0xC0: // Set Instrument index = m_ims->songData[m_songDataIndex]; instIndexInBnk = m_ims->instIndex[index].index; // 악기가 있다면.. if ( instIndexInBnk >= 0 && instIndexInBnk < m_ims->m_bnk->header.totalEntry) { paramArray = &m_ims->m_bnk->instRecord32[instIndexInBnk].op1.keyScaleLevel; SetVoiceTimbre(voice, paramArray); } else { /* printf("%d/%d\n", instIndexInBnk, m_ims->m_bnk->header.totalEntry); fflush(stdout); */ } m_songDataIndex++; break; case 0xE0: // Set Pitch memcpy(&pitchBend, &m_ims->songData[m_songDataIndex], sizeof(unsigned short int)); pitchBend = pitchBend / 2; SetVoicePitch(voice, pitchBend); m_songDataIndex += sizeof(unsigned short int); break; case 0xF0: // Set Tempo m_songDataIndex += 2; m_basicTempo = (m_ims->header.nBasicTempo * m_ims->songData[m_songDataIndex]); m_basicTempo += m_ims->header.nBasicTempo * m_ims->songData[m_songDataIndex + 1] / 128; m_songDataIndex += 3; break; } while (1) { delay = m_ims->songData[m_songDataIndex]; m_songDataIndex++; // IMS finish code if (m_ims->songData[m_songDataIndex] == 0xFC) { if ( m_repeatMode == REPEAT_THIS ) { Rewind(); } else { m_playMode=SONG_END; break; } delayTime += delay; return delayTime; } if (delay == 0xF8) delayTime += 240; else break; } delayTime += delay; if (delayTime == 0) goto again; else m_tick += delayTime; return delayTime; }