Пример #1
0
void Arponaut::ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames)
{
    // Mutex is already locked for us.
    ENoteLength noteLength = (ENoteLength) ((int(GetParam(kNoteLength)->Value())) + 1);
    EOctaves    octaves    = (EOctaves)    ((int(GetParam(kOctaves)->Value())) + 1);
    EArpMode    arpMode    = (EArpMode)    (int(GetParam(kArpMode)->Value()));
    EInsertMode insertMode = (EInsertMode) (int(GetParam(kInsertMode)->Value()));

    if (GetGUI()) {
        //GetGUI()->SetControlFromPlug(mMeterIdx_L, peakL);
        //GetGUI()->SetControlFromPlug(mMeterIdx_R, peakR);
    }

    int pos = GetSamplePos();
    running_ = (pos != lastPos_);
    int tnum, tden;
    GetTimeSig(&tnum, &tden);

    if (keymap_.held() == 0) {
        NoteOff(); // only sent if a note is already playing
    }
    
    if (running_ && keymap_.held()) {
        sequence_->setOctaves(octaves);
        sequence_->setArpMode(arpMode);
        sequence_->setInsertMode(insertMode);

        double perBeat = GetSamplesPerBeat() / noteLength;
        // trigger?
        int ibar = static_cast<int>(double(pos) / perBeat);
        int ilastBar = static_cast<int>(double(lastPos_) / perBeat);

        if ((pos == 0 && ibar == 0) || (ibar != ilastBar)) {
            // Log("pos %d pb %f Num %d Den %d ibar %d lastbar %d\n", pos, perBeat, tnum, tden, ibar, ilastBar);
            NoteOff();
            IMidiMsg* next = sequence_->next();

            if (next && next->StatusMsg() == IMidiMsg::kNoteOn) {
                SendMidiMsg(next);
                playing_ = *next;
            }

            matrix->SetDirty(false);
        }
    }

    lastPos_ = pos;
}
Пример #2
0
void Fl_MIDIKeyboard::release_key(uchar k) {
    if (pressed_keys[k]) {

        NoteOff(k);

        pressed_keys[k] = false;
        _npressed--;
        if (_npressed) {
            if (k == _maxpressed) {
                do k--;
                    while (!pressed_keys[k]);
                _maxpressed = k;
            }
            else if (k == _minpressed) {
                do k++;
                    while (!pressed_keys[k]);
                _minpressed = k;
            }
        }
        redraw();
        if (when() & MKB_WHEN_RELEASE) {
            _callback_status = MKB_RELEASE | k;
            do_callback();
        }
    //cout << "Released " << (char)k << " npressed = " << (int)_npressed << endl;
    }
}
Пример #3
0
void TrashMIDI(void)
{
  long Length;
  int J;

  /* If not logging, drop out */
  if(!MIDIOut) return;
  /* Turn sound off */
  for(J=0;J<MIDI_CHANNELS;J++) NoteOff(J);
  /* End of track */
  MIDIMessage(0xFF,0x2F,0x00);
  /* Put track length in file */
  fseek(MIDIOut,0,SEEK_END);
  Length=ftell(MIDIOut)-22;
  fseek(MIDIOut,18,SEEK_SET);
  fputc((Length>>24)&0xFF,MIDIOut);
  fputc((Length>>16)&0xFF,MIDIOut);
  fputc((Length>>8)&0xFF,MIDIOut);
  fputc(Length&0xFF,MIDIOut);

  /* Done logging */
  fclose(MIDIOut);
  Logging   = MIDI_OFF;
  LastMsg   = -1;
  TickCount = 0;
  MIDIOut   = 0;
}
Пример #4
0
void OCPiano::PressKey(const int Pitch, const bool Poly, const bool Tied)
{
    emit NoteOn(Pitch);
    int NoteType=tsnote;
    if (Tied) NoteType=tstiednote;
    if (Poly)
    {
        Types.append(NoteType+2);
        Pitches.append(Pitch);
        CurrentPitch=0;
    }
    else
    {
        Types.append(NoteType);
        Pitches.append(Pitch);
        CurrentPitch=Pitch;
        QList<QPair<int,int> >Notes;
        for (int i=0;i<Pitches.count();i++)
        {
            Notes.append(qMakePair(Pitches[i],Types[i]));
        }
        emit TriggerNotes(Notes);
        for (int i=0;i<Pitches.count()-1;i++)
        {
            emit NoteOff(Pitches[i]);
        }
        Pitches.clear();
        Types.clear();
    }
}
Пример #5
0
LRESULT CMainDlg::OnSave(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	char fileName[MAX_PATH];
	memset(fileName, 0, sizeof(fileName));
	OPENFILENAME ofn;
	memset(&ofn, 0, sizeof(ofn));
	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = m_hWnd;
	ofn.lpstrFilter = "Sound Files(*.wav)\0*.wav\0All Files(*.*)\0*.*\0";
	ofn.nFilterIndex = 1;
	ofn.lpstrFile = fileName;
	ofn.lpstrDefExt = ".wav";
	ofn.nMaxFile = MAX_PATH;
	ofn.Flags = OFN_OVERWRITEPROMPT;
	
	if (GetSaveFileName (&ofn))
	{
		WaveFile wvf;
		wvf.OpenWaveFile(fileName, 2);
		InitGen();
		long totalSamples = (long) ((durTotal * synthParams.sampleRate) + 0.5);
		long atkSamples = (long) (durAtkSus * synthParams.sampleRate);
		long n;
		for (n = 0; n < atkSamples; n++)
			wvf.Output1(Generate());
		NoteOff();
		while (n++ < totalSamples)
			wvf.Output1(Generate());
		for (n = 0; n < 440; n++)
			wvf.Output1(0);
		wvf.CloseWaveFile();
	}
	return 0;
}
Пример #6
0
 void PedalReleased()
 {
     if(waitingForPedalRelease)
     {
         NoteOff();
         waitingForPedalRelease=false;
     }
 }
Пример #7
0
void OCPiano::mouseReleaseEvent(QMouseEvent *event)
{
    Q_UNUSED(event);
    if (CurrentPitch>0)
    {
        emit NoteOff(CurrentPitch);
        CurrentPitch=0;
    }
    Paint();
}
Пример #8
0
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;
}
Пример #9
0
void 
BMidiLocalConsumer::Data(uchar* data, size_t length, bool atomic, bigtime_t time)
{
	if (atomic) {
		switch (data[0] & 0xF0) {
			case B_NOTE_OFF:
			{
				if (length == 3)
					NoteOff(data[0] & 0x0F, data[1], data[2], time);
				break;
			}

			case B_NOTE_ON:
			{
				if (length == 3)
					NoteOn(data[0] & 0x0F, data[1], data[2], time);
				break;
			}

			case B_KEY_PRESSURE:
			{
				if (length == 3)
					KeyPressure(data[0] & 0x0F, data[1], data[2], time);
				break;
			}

			case B_CONTROL_CHANGE:
			{
				if (length == 3)
					ControlChange(data[0] & 0x0F, data[1], data[2], time);
				break;
			}

			case B_PROGRAM_CHANGE:
			{
				if (length == 2)
					ProgramChange(data[0] & 0x0F, data[1], time);
				break;
			}

			case B_CHANNEL_PRESSURE:
			{
				if (length == 2)
					ChannelPressure(data[0] & 0x0F, data[1], time);
				break;
			}

			case B_PITCH_BEND:
			{
				if (length == 3)
					PitchBend(data[0] & 0x0F, data[1], data[2], time);
				break;
			}

			case 0xF0:
			{
				switch (data[0]) {
					case B_SYS_EX_START:
					{
						if (data[length - 1] == B_SYS_EX_END) {
							SystemExclusive(data + 1, length - 2, time);
						} else { // sysex-end is not required
							SystemExclusive(data + 1, length - 1, time);
						}
						break;
					}

					case B_TUNE_REQUEST:
					case B_SYS_EX_END:
					{
						if (length == 1) {
							SystemCommon(data[0], 0, 0, time);
						}
						break;
					}

					case B_CABLE_MESSAGE:
					case B_MIDI_TIME_CODE:
					case B_SONG_SELECT:
					{
						if (length == 2) {
							SystemCommon(data[0], data[1], 0, time);
						}
						break;
					}

					case B_SONG_POSITION:
					{
						if (length == 3) {
							SystemCommon(data[0], data[1], data[2], time);
						}
						break;
					}
	
					case B_TIMING_CLOCK:
					case B_START:
					case B_CONTINUE:
					case B_STOP:
					case B_ACTIVE_SENSING:
					{
						if (length == 1) {
							SystemRealTime(data[0], time);
						}
						break;
					}

					case B_SYSTEM_RESET:
					{
						if (length == 1) {
							SystemRealTime(data[0], time);
						} else if ((length == 6) && (data[1] == 0x51) 
								&& (data[2] == 0x03)) {
							int32 tempo = 
								(data[3] << 16) | (data[4] << 8) | data[5];

							TempoChange(60000000/tempo, time);
						}
					}
				}
				break;
			}
		}
	}
}
Пример #10
0
void __cdecl main(int argc, char **argv)
{
	HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	int running = 1;

#ifdef WIN32
	if (IsDebuggerPresent())
	{
		// turn on floating-point exceptions
		unsigned int prev;
		_clearfp();
		_controlfp_s(&prev, 0, _EM_ZERODIVIDE|_EM_INVALID);
	}
#endif

	// check the correct BASS was loaded
	if (HIWORD(BASS_GetVersion()) != BASSVERSION)
	{
		fprintf(stderr, "An incorrect version of BASS.DLL was loaded");
		return;
	}

	// set the window title
	SetConsoleTitle(TEXT(title_text));

	// set the console buffer size
	static const COORD bufferSize = { 80, 50 };
	SetConsoleScreenBufferSize(hOut, bufferSize);

	// set the console window size
	static const SMALL_RECT windowSize = { 0, 0, 79, 49 };
	SetConsoleWindowInfo(hOut, TRUE, &windowSize);

	// clear the window
	Clear(hOut);

	// hide the cursor
	static const CONSOLE_CURSOR_INFO cursorInfo = { 100, FALSE };
	SetConsoleCursorInfo(hOut, &cursorInfo);

	// set input mode
	SetConsoleMode(hIn, 0);

	// 10ms update period
	const DWORD STREAM_UPDATE_PERIOD = 10;
	BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, STREAM_UPDATE_PERIOD);

	// initialize BASS sound library
	const DWORD STREAM_FREQUENCY = 48000;
	if (!BASS_Init(-1, STREAM_FREQUENCY, BASS_DEVICE_LATENCY, 0, NULL))
		Error("Can't initialize device");

	// get device info
	BASS_GetInfo(&info);

	// if the device's output rate is unknown default to stream frequency
	if (!info.freq) info.freq = STREAM_FREQUENCY;

	// debug print info
	DebugPrint("frequency: %d (min %d, max %d)\n", info.freq, info.minrate, info.maxrate);
	DebugPrint("device latency: %dms\n", info.latency);
	DebugPrint("device minbuf: %dms\n", info.minbuf);
	DebugPrint("ds version: %d (effects %s)\n", info.dsver, info.dsver < 8 ? "disabled" : "enabled");

	// default buffer size = update period + 'minbuf' + 1ms extra margin
	BASS_SetConfig(BASS_CONFIG_BUFFER, STREAM_UPDATE_PERIOD + info.minbuf + 1);
	DebugPrint("using a %dms buffer\r", BASS_GetConfig(BASS_CONFIG_BUFFER));

	// create a stream, stereo so that effects sound nice
	stream = BASS_StreamCreate(info.freq, 2, BASS_SAMPLE_FLOAT, (STREAMPROC*)WriteStream, 0);

	// set channel to apply effects
	fx_channel = stream;

#ifdef BANDLIMITED_SAWTOOTH
	// initialize bandlimited sawtooth tables
	InitSawtooth();
#endif

	// initialize waves
	InitWave();

	// enable the first oscillator
	osc_config[0].enable = true;

	// reset all controllers
	Control::ResetAll();

	// start playing the audio stream
	BASS_ChannelPlay(stream, FALSE);

	// get the number of midi devices
	UINT midiInDevs = Midi::Input::GetNumDevices();
	DebugPrint("MIDI input devices: %d\n", midiInDevs);

	// print device names
	for (UINT i = 0; i < midiInDevs; ++i)
	{
		MIDIINCAPS midiInCaps;
		if (Midi::Input::GetDeviceCaps(i, midiInCaps) == 0)
		{
			DebugPrint("%d: %s\n", i, midiInCaps.szPname);
		}
	}

	// if there are any devices available...
	if (midiInDevs > 0)
	{
		// open and start midi input
		// TO DO: select device number via a configuration setting
		Midi::Input::Open(0);
		Midi::Input::Start();
	}

	// initialize to middle c
	note_most_recent = 60;
	voice_note[voice_most_recent] = unsigned char(note_most_recent);

	DisplaySpectrumAnalyzer displaySpectrumAnalyzer;
	DisplayKeyVolumeEnvelope displayKeyVolumeEnvelope;
	DisplayOscillatorWaveform displayOscillatorWaveform;
	DisplayOscillatorFrequency displayOscillatorFrequency;
	DisplayLowFrequencyOscillator displayLowFrequencyOscillator;
	DisplayFilterFrequency displayFilterFrequency;

	// initialize spectrum analyzer
	displaySpectrumAnalyzer.Init(stream, info);

	// initialize key display
	displayKeyVolumeEnvelope.Init(hOut);

	// show output scale and key octave
	PrintOutputScale(hOut);
	PrintKeyOctave(hOut);
	PrintGoToEffects(hOut);
	PrintAntialias(hOut);

	// show main page
	Menu::SetActivePage(hOut, Menu::PAGE_MAIN);

	while (running)
	{
		// if there are any pending input events...
		DWORD numEvents = 0;
		while (GetNumberOfConsoleInputEvents(hIn, &numEvents) && numEvents > 0)
		{
			// get the next input event
			INPUT_RECORD keyin;
			ReadConsoleInput(hIn, &keyin, 1, &numEvents);
			if (keyin.EventType == KEY_EVENT)
			{
				// handle interface keys
				if (keyin.Event.KeyEvent.bKeyDown)
				{
					WORD code = keyin.Event.KeyEvent.wVirtualKeyCode;
					DWORD modifiers = keyin.Event.KeyEvent.dwControlKeyState;
					if (code == VK_ESCAPE)
					{
						running = 0;
						break;
					}
					else if (code == VK_OEM_MINUS || code == VK_SUBTRACT)
					{
						Menu::UpdatePercentageProperty(output_scale, -1, modifiers, 0, 4);
						PrintOutputScale(hOut);
					}
					else if (code == VK_OEM_PLUS || code == VK_ADD)
					{
						Menu::UpdatePercentageProperty(output_scale, +1, modifiers, 0, 4);
						PrintOutputScale(hOut);
					}
					else if (code == VK_OEM_4)	// '['
					{
						if (keyboard_octave > 1)
						{
							for (int k = 0; k < KEYS; ++k)
							{
								if (key_down[k])
									NoteOff(k + keyboard_octave * 12);
							}
							--keyboard_octave;
							for (int k = 0; k < KEYS; ++k)
							{
								if (key_down[k])
									NoteOn(k + keyboard_octave * 12);
							}
							PrintKeyOctave(hOut);
						}
					}
					else if (code == VK_OEM_6)	// ']'
					{
						if (keyboard_octave < 9)
						{
							for (int k = 0; k < KEYS; ++k)
							{
								if (key_down[k])
									NoteOff(k + keyboard_octave * 12);
							}
							++keyboard_octave;
							for (int k = 0; k < KEYS; ++k)
							{
								if (key_down[k])
									NoteOn(k + keyboard_octave * 12);
							}
							PrintKeyOctave(hOut);
						}
					}
					else if (code == VK_F12)
					{
						use_antialias = !use_antialias;
						PrintAntialias(hOut);
					}
					else if (code >= VK_F1 && code < VK_F10)
					{
						Menu::SetActiveMenu(hOut, code - VK_F1);
					}
					else if (code == VK_F10)
					{
						PrintGoToEffects(hOut);
						Menu::SetActivePage(hOut, Menu::PAGE_MAIN);
					}
					else if (code == VK_F11)
					{
						PrintGoToMain(hOut);
						Menu::SetActivePage(hOut, Menu::PAGE_FX);
					}
					else if (code == VK_TAB)
					{
						if (modifiers & SHIFT_PRESSED)
							Menu::PrevMenu(hOut);
						else
							Menu::NextMenu(hOut);
					}
					else if (code == VK_UP || code == VK_DOWN || code == VK_RIGHT || code == VK_LEFT)
					{
						Menu::Handler(hOut, code, modifiers);
					}
				}

				// handle note keys
				for (int k = 0; k < KEYS; k++)
				{
					if (keyin.Event.KeyEvent.wVirtualKeyCode == keys[k])
					{
						// key down
						bool down = (keyin.Event.KeyEvent.bKeyDown != 0);

						// if key down state changed...
						if (key_down[k] != down)
						{
							// update state
							key_down[k] = down;

							// if pressing the key
							if (down)
							{
								// note on
								NoteOn(k + keyboard_octave * 12);
							}
							else
							{
								// note off
								NoteOff(k + keyboard_octave * 12);
							}
						}
						break;
					}
				}
			}
		}

		// center frequency of the zeroth semitone band
		// (one octave down from the lowest key)
		float const freq_min = powf(2, float(keyboard_octave - 6)) * middle_c_frequency;

		// update the spectrum analyzer display
		displaySpectrumAnalyzer.Update(hOut, stream, info, freq_min);

		// update note key volume envelope display
		displayKeyVolumeEnvelope.Update(hOut);

		if (Menu::active_page == Menu::PAGE_MAIN)
		{
			// update the oscillator waveform display
			displayOscillatorWaveform.Update(hOut, info, voice_most_recent);

			// update the oscillator frequency displays
			for (int o = 0; o < NUM_OSCILLATORS; ++o)
			{
				if (osc_config[o].enable)
					displayOscillatorFrequency.Update(hOut, voice_most_recent, o);
			}

			// update the low-frequency oscillator display
			displayLowFrequencyOscillator.Update(hOut);

			// update the filter frequency display
			if (flt_config.enable)
				displayFilterFrequency.Update(hOut, voice_most_recent);
		}

		// show CPU usage
		PrintConsole(hOut, { 73, 49 }, "%6.2f%%", BASS_GetCPU());

		// sleep for 1/60th of second
		Sleep(16);
	}

	if (midiInDevs)
	{
		// stop and close midi input
		Midi::Input::Stop();
		Midi::Input::Close();
	}

	// clean up spectrum analyzer
	displaySpectrumAnalyzer.Cleanup(stream);

	// clear the window
	Clear(hOut);

	BASS_Free();
}
Пример #11
0
int MIDILogging(int Switch)
{
  static const char MThd[] = "MThd\0\0\0\006\0\0\0\1";
                           /* ID  DataLen   Fmt Trks */
  static const char MTrk[] = "MTrk\0\0\0\0";
                           /* ID  TrkLen   */
  int J,I;

  /* Toggle logging if requested */
  if(Switch==MIDI_TOGGLE) Switch=!Logging;

  if((Switch==MIDI_ON)||(Switch==MIDI_OFF))
    if(Switch^Logging)
    {
      /* When turning logging off, silence all channels */
      if(!Switch&&MIDIOut)
        for(J=0;J<MIDI_CHANNELS;J++) NoteOff(J);

      /* When turning logging on, open MIDI file */
      if(Switch&&!MIDIOut&&LogName)
      {
        /* No messages have been sent yet */
        LastMsg=-1;

        /* Clear all storage */
        for(J=0;J<MIDI_CHANNELS;J++)
          MidiCH[J].Note=MidiCH[J].Pitch=MidiCH[J].Level=-1;

        /* Open new file and write out the header */
        MIDIOut=fopen(LogName,"wb");
        if(!MIDIOut) return(MIDI_OFF);
        if(fwrite(MThd,1,12,MIDIOut)!=12)
        { fclose(MIDIOut);MIDIOut=0;return(MIDI_OFF); }
        fputc((MIDI_DIVISIONS>>8)&0xFF,MIDIOut);
        fputc(MIDI_DIVISIONS&0xFF,MIDIOut);
        if(fwrite(MTrk,1,8,MIDIOut)!=8)
        { fclose(MIDIOut);MIDIOut=0;return(MIDI_OFF); }

        /* Write out the tempo */
        WriteTempo(MIDI_DIVISIONS);
      }

      /* Turn logging off on failure to open MIDIOut */
      if(!MIDIOut) Switch=MIDI_OFF;

      /* Assign new switch value */
      Logging=Switch;

      /* If switching logging on... */
      if(Switch)
      {
        /* Start logging without a pause */
        TickCount=0;

        /* Write instrument changes */
        for(J=0;J<MIDI_CHANNELS;J++)
          if((MidiCH[J].Type>=0)&&(MidiCH[J].Type&0x10000))
          {
            I=MidiCH[J].Type&~0x10000;
            MidiCH[J].Type=-1;
            MIDISetSound(J,I);
          }
      }
    }
Пример #12
0
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;
}
Пример #13
0
//--------------------------------------------------------------
void testApp::keyReleased(int key) {

    switch(key) {

    // send pgm change on arrow keys
    case OF_KEY_UP:
        currentPgm = (int) ofClamp(currentPgm+1, 0, 127);
        midiOut.sendProgramChange(synthChan, currentPgm);

        break;
    case OF_KEY_DOWN:
        currentPgm = (int) ofClamp(currentPgm-1, 0, 127);
        midiOut << ProgramChange(synthChan, currentPgm); // stream interface
        break;

    case OF_KEY_LEFT:
        currentPgm = (int) ofClamp(currentPgm+1, 0, 127);
        midiOut.sendProgramChange(effectsChan, currentPgm);

        break;
    case OF_KEY_RIGHT:
        currentPgm = (int) ofClamp(currentPgm-1, 0, 127);
        midiOut << ProgramChange(effectsChan, currentPgm); // stream interface
        break;

    // aftertouch
    case '[':
        touch = 64;
        midiOut.sendAftertouch(channel, touch);
        break;
    case ']':
        touch = 127;
        midiOut << Aftertouch(channel, touch); // stream interface
        break;

    // poly aftertouch
    case '<':
        polytouch = 64;
        midiOut.sendPolyAftertouch(channel, 64, polytouch);
        break;
    case '>':
        polytouch = 127;
        midiOut << PolyAftertouch(channel, 64, polytouch); // stream interface
        break;

    // sysex using raw bytes (use shift + s)
    case 'S': {
        // send a pitch change to Part 1 of a MULTI on an Akai sampler
        // from http://troywoodfield.tripod.com/sysex.html
        //
        // do you have an S2000 to try?
        //
        // note: this is probably not as efficient as the next two methods
        //       since it sends only one byte at a time, instead of all
        //       at once
        //
        midiOut.sendMidiByte(MIDI_SYSEX);
        midiOut.sendMidiByte(0x47);	// akai manufacturer code
        midiOut.sendMidiByte(0x00); // channel 0
        midiOut.sendMidiByte(0x42); // MULTI
        midiOut.sendMidiByte(0x48); // using an Akai S2000
        midiOut.sendMidiByte(0x00); // Part 1
        midiOut.sendMidiByte(0x00);	// transpose
        midiOut.sendMidiByte(0x01); // Access Multi Parts
        midiOut.sendMidiByte(0x4B); // offset
        midiOut.sendMidiByte(0x00);	// offset
        midiOut.sendMidiByte(0x01); // Field size = 1
        midiOut.sendMidiByte(0x00); // Field size = 1
        midiOut.sendMidiByte(0x04); // pitch value = 4
        midiOut.sendMidiByte(0x00); // offset
        midiOut.sendMidiByte(MIDI_SYSEX_END);

        // send again using a vector
        //
        // sends all bytes within one message
        //
        vector<unsigned char> sysexMsg;
        sysexMsg.push_back(MIDI_SYSEX);
        sysexMsg.push_back(0x47);
        sysexMsg.push_back(0x00);
        sysexMsg.push_back(0x42);
        sysexMsg.push_back(0x48);
        sysexMsg.push_back(0x00);
        sysexMsg.push_back(0x00);
        sysexMsg.push_back(0x01);
        sysexMsg.push_back(0x4B);
        sysexMsg.push_back(0x00);
        sysexMsg.push_back(0x01);
        sysexMsg.push_back(0x00);
        sysexMsg.push_back(0x04);
        sysexMsg.push_back(0x00);
        sysexMsg.push_back(MIDI_SYSEX_END);
        midiOut.sendMidiBytes(sysexMsg);

        // send again with the byte stream interface
        //
        // builds the message, then sends it on FinishMidi()
        //
        midiOut << StartMidi() << MIDI_SYSEX
                << 0x47 << 0x00 << 0x42 << 0x48 << 0x00 << 0x00 << 0x01
                << 0x4B << 0x00 << 0x01 << 0x00 << 0x04 << 0x00
                << MIDI_SYSEX_END << FinishMidi();
        break;
    }

    // print the port list
    case '?':
        midiOut.listPorts();
        break;

    // note off using raw bytes
    case ' ':
        // send with the byte stream interface, noteoff for note 60
        midiOut << StartMidi() << 0x80 << 0x3C << 0x40 << FinishMidi();
        break;

    default:

        // send a note off if the key is a letter or a number
        if(isalnum(key)) {
            note = ofMap(key, 48, 122, 0, 127);
            velocity = 0;
            midiOut << NoteOff(channel, note, velocity); // stream interface
        }
        break;
    }
}
Пример #14
0
int CMainDlg::PlayFM(int loop)
{
	WAVEFORMATEX wf;
	wf.wFormatTag = WAVE_FORMAT_PCM;
	wf.nChannels = 1;
    wf.nSamplesPerSec = synthParams.isampleRate;
    wf.nAvgBytesPerSec = wf.nSamplesPerSec * 2;
	wf.nBlockAlign = 2; 
    wf.wBitsPerSample = 16;
	wf.cbSize = 0;

	StopPlaying();

	InitGen();

	DWORD atkSusSamples = (DWORD) (durAtkSus * synthParams.sampleRate);
	DWORD totalSamples = (DWORD) (durTotal * synthParams.sampleRate);
	// add room for silence at end to minimize "click" when player turns off.
	DWORD bufSize = totalSamples + (DWORD) (0.1 * synthParams.sampleRate);
	SampleValue *samples;

#ifdef USE_DIRECTSOUND
	HRESULT hr;
	if (dirSndObj == NULL)
	{
		hr = DirectSoundCreate(NULL, &dirSndObj, NULL);
		if (hr == S_OK)
		{
			hr = dirSndObj->SetCooperativeLevel(m_hWnd, DSSCL_NORMAL);
			if (hr != S_OK)
			{
				dirSndObj->Release();
				dirSndObj = NULL;
				MessageBox("Cannot open direct sound output", "Error", MB_OK|MB_ICONSTOP);
				return -1;
			}
		}
	}
	void *pAudio1 = NULL;
	void *pAudio2 = NULL;
	DWORD dwAudio1 = 0;
	DWORD dwAudio2 = 0;

	DSBUFFERDESC dsbd;
	dsbd.dwSize = sizeof(dsbd);
	dsbd.dwFlags = 0; 
	dsbd.dwBufferBytes = bufSize * 2;
	dsbd.dwReserved = 0; 
	dsbd.lpwfxFormat = &wf;
	
	hr = dirSndObj->CreateSoundBuffer(&dsbd, &dirSndBuf, NULL);
	if (hr != S_OK)
		return -1;
	hr = dirSndBuf->Lock(0, bufSize, &pAudio1, &dwAudio1, NULL, NULL, DSBLOCK_ENTIREBUFFER);
	if (hr != S_OK)
	{
		MessageBox("Cannot create direct sound buffer", "Error", MB_OK|MB_ICONSTOP);
		return -1;
	}
	samples = (SampleValue *) pAudio1;
#else
	MMRESULT res; 
	if (woHandle == NULL)
	{
		res = waveOutOpen(&woHandle, WAVE_MAPPER, &wf, (DWORD) m_hWnd, 0, CALLBACK_WINDOW);
		if (res != MMSYSERR_NOERROR)
		{
			MessageBox("Cannot open wave output", "Error", MB_OK|MB_ICONSTOP);
			return -1;
		}
	}

	memset(&wh, 0, sizeof(wh));
	wh.dwBufferLength = bufSize * sizeof(SampleValue);
	wh.lpData = (LPSTR) malloc(wh.dwBufferLength);
	if (wh.lpData == NULL)
	{
		MessageBox("Cannot create wave out buffer", "Error", MB_OK|MB_ICONSTOP);
		return -1;
	}

	res = waveOutPrepareHeader(woHandle, &wh, sizeof(wh));
	samples = (SampleValue *) wh.lpData;
#endif

	DWORD n = 0; 
	while (n++ < atkSusSamples)
		*samples++ = (SampleValue) (Generate() * synthParams.sampleScale);
	NoteOff();
	while (!gen1EG.IsFinished() && n++ < bufSize)
		*samples++ = (SampleValue) (Generate() * synthParams.sampleScale);
	while (n++ < bufSize)
		*samples++ = 0;

#ifdef USE_DIRECTSOUND
	dirSndBuf->Unlock(pAudio1, dwAudio1, pAudio2, dwAudio2);
	dirSndBuf->Play(0, 0, loop ? DSBPLAY_LOOPING : 0);
	if (!loop)
		idTimer = SetTimer(1, (UINT) (durTotal * 1000.0) + 500);
#else
	if (loop)
	{
		wh.dwFlags |= WHDR_BEGINLOOP | WHDR_ENDLOOP;
		wh.dwLoops = 100;
	}
	waveOutWrite(woHandle, &wh, sizeof(wh));
#endif

	return 0;
}