예제 #1
0
bool VoicerBaseUGenInternal::sendMidiNote(const int midiChannel, 
										  const int midiNote,
										  const int velocity) throw()
{
	const int userData = createUserData(midiChannel, midiNote);
	
	ugen_assert(userData != UGen::defaultUserData);
	ugen_assert(velocity >= 0);

	if(velocity > 0)
	{
		if(numVoices_ > 0)
		{
			const int voicesUsed = countNonstealingVoices();
			if(voicesUsed >= numVoices_)
			{
				UGen stealee = chooseStealee();
					
				if(stealee.isNotNull())
				{
					stealee.userData = stealingUserData;
					stealee.steal(forcedSteal_);
				}
			}
		}
		
		// stop double notes, AU lab was sending two ons but only one off 
		// stealNote(midiChannel, midiNote, false, true);  // let's only do this in the Juce version..
		
		UGen newEvent = spawnEvent(*this, currentEventIndex++, midiChannel, midiNote, velocity);
        
        if(newEvent.isNotNull())
        {
            newEvent.userData = userData;
            events.add(newEvent);
        }        
	}
	else
	{
		UGen releasee = chooseReleasee(midiChannel, midiNote);
		
		if(releasee.isNotNull())
		{
			//releasee.userData = UGen::defaultUserData; // need to rethink why I really wanted to do this
			releasee.release();
		}
	}
	
	return true;
}
예제 #2
0
void VoicerUGenInternal::processBlock(bool& shouldDelete, const unsigned int blockID, const int /*channel*/) throw()
{	
	if(shouldStopAllEvents() == true) initEvents();
	
	if(midiMessages.isEmpty() == true)
	{
		const ScopedLock sl(lock);
		SpawnBaseUGenInternal::processBlock(shouldDelete, blockID, -1);
	}
	else
	{
		const int blockSize = uGenOutput.getBlockSize();
		MidiBuffer::Iterator iter(midiMessages);
		MidiMessage message(0xf4, 0.0);
		
		int samplePos = 0;
		int startSample = 0;
		
		const int numChannels = getNumChannels();
		const int midiChannel = midiChannel_;
		
		while(iter.getNextEvent(message, samplePos) && (samplePos < blockSize))
		{
			const ScopedLock sl(lock);
				
			if(samplePos < 0) samplePos = 0;
			
			const int numSamples = samplePos - startSample;
		
			if(numSamples > 0)
			{				
				for(int channel = 0; channel < numChannels; channel++)
				{
					bufferData[channel] = proxies[channel]->getSampleData() + startSample;
				}
				
				mixer.prepareForBlock(numSamples, blockID + startSample, -1);
				mixer.setOutputs(bufferData, numSamples, numChannels);
				mixer.processBlock(shouldDelete, blockID + startSample, -1);				
			}
			
			startSample = samplePos;
			
			if(message.isForChannel(midiChannel))
			{
				if(message.isNoteOnOrOff())
				{
					const int midiNote = message.getNoteNumber();
					const int velocity = message.getVelocity();
										
					if(velocity > 0)
					{
						if(numVoices_ > 0)
						{
							const int voicesUsed = countNonstealingVoices();
							if(voicesUsed >= numVoices_)
							{
								UGen stealee = chooseStealee();
								
								if(stealee.isNotNull())
								{
									stealee.userData = stealingUserData;
									stealee.steal(forcedSteal_);
								}
							}
						}
						
						// stop double notes, AU lab was sending two ons but one off - seems fixed in Au Lab 2.2
						//stealNote(midiChannel, midiNote, false, true); 
						
						UGen newEvent = spawnEvent(*this, currentEventIndex++, midiChannel, midiNote, velocity);
						newEvent.userData = createUserData(midiChannel, midiNote);
						events.add(newEvent);
					}
					else
					{
						UGen releasee = chooseReleasee(midiChannel, midiNote);
						if(releasee.isNotNull()) releasee.release();
					}
				}
				else if(message.isController())
				{
					getController(message.getControllerNumber()) = message.getControllerValue() / 127.f;
				}
				else if(message.isPitchWheel())
				{
					getPitchWheel() = (jlimit(-8191, 8191, message.getPitchWheelValue() - 8192) / 8191.f);
				}
				else if(message.isChannelPressure())
				{
					getChannelPressure() = (message.getChannelPressureValue() / 127.f);
				}
				else if(message.isAftertouch())
				{
					getKeyPressure(message.getNoteNumber()) = (message.getAfterTouchValue() / 127.f);
				}
				else if(message.isProgramChange())
				{
					getProgram() = (message.getProgramChangeNumber());
				}
				else if(message.isAllNotesOff())
				{
					initEvents();
				}
			}
		}
		
		const ScopedLock sl(lock);
		
		const int numSamples = blockSize - startSample;
		
		if(numSamples > 0)
		{			
			for(int channel = 0; channel < numChannels; channel++)
			{
				bufferData[channel] = proxies[channel]->getSampleData() + startSample;
			}
			
			mixer.prepareForBlock(numSamples, blockID + startSample, -1);
			mixer.setOutputs(bufferData, numSamples, numChannels);
			mixer.processBlock(shouldDelete, blockID + startSample, -1);
		}
				
		midiMessages.clear();
		events.removeNulls();
	}	
}