Esempio n. 1
0
  void Arpeggiator::process() {
    mopo_float frequency = input(kFrequency)->at(0);
    float min_gate = (MIN_VOICE_TIME + VOICE_KILL_TIME) * frequency;
    mopo_float gate = INTERPOLATE(min_gate, 1.0, input(kGate)->at(0));

    mopo_float delta_phase = frequency / sample_rate_;
    mopo_float new_phase = phase_ + buffer_size_ * delta_phase;

    // If we're past the gate phase and we're playing a note, turn it off.
    if (new_phase >= gate && last_played_note_ >= 0) {
      int offset = CLAMP((gate - phase_) / delta_phase, 0, buffer_size_ - 1);
      note_handler_->noteOff(last_played_note_, offset);
      last_played_note_ = -1;
    }

    // Check if it's time to play the next note.
    if (getNumNotes() && new_phase >= 1) {
      int offset = CLAMP((1 - phase_) / delta_phase, 0, buffer_size_ - 1);
      std::pair<mopo_float, mopo_float> note = getNextNote();
      note_handler_->noteOn(note.first, note.second, offset);
      last_played_note_ = note.first;
      phase_ = new_phase - 1.0;
    }
    else
      phase_ = new_phase;
  }
Esempio n. 2
0
int Player_Mac::readBuffer(int16 *data, const int numSamples) {
	Common::StackLock lock(_mutex);

	memset(data, 0, numSamples * 2);
	if (_soundPlaying == -1) {
		return numSamples;
	}

	bool notesLeft = false;

	for (int i = 0; i < _numberOfChannels; i++) {
		if (!(_channelMask & (1 << i))) {
			continue;
		}

		uint samplesLeft = numSamples;
		int16 *ptr = data;

		while (samplesLeft > 0) {
			int generated;
			if (_channel[i]._remaining == 0) {
				uint32 samples;
				int pitchModifier;
				byte velocity;
				if (getNextNote(i, samples, pitchModifier, velocity)) {
					_channel[i]._remaining = samples;
					_channel[i]._pitchModifier = pitchModifier;
					_channel[i]._velocity = velocity;

				} else {
					_channel[i]._pitchModifier = 0;
					_channel[i]._velocity = 0;
					_channel[i]._remaining = samplesLeft;
				}
			}
			generated = MIN<uint32>(_channel[i]._remaining, samplesLeft);
			if (_channel[i]._velocity != 0) {
				_channel[i]._instrument.generateSamples(ptr, _channel[i]._pitchModifier, _channel[i]._velocity, generated, _channel[i]._remaining, _fadeNoteEnds);
			}
			ptr += generated;
			samplesLeft -= generated;
			_channel[i]._remaining -= generated;
		}

		if (_channel[i]._notesLeft) {
			notesLeft = true;
		}
	}

	if (!notesLeft) {
		stopAllSounds_Internal();
	}

	return numSamples;
}
bool hasNoteWithHammerOn(const Voice &voice, const Position &pos)
{
    for (const Note &note : pos.getNotes())
    {
        if (note.hasProperty(Note::HammerOnOrPullOff))
        {
            const Note *nextNote =
                getNextNote(voice, pos.getPosition(), note.getString());
            return nextNote && nextNote->getFretNumber() > note.getFretNumber();
        }
    }

    return false;
}
Esempio n. 4
0
void OSUSTANDARD::genAccTimings(Play* _play)
{
	accTimings.clear();
	std::vector<osu::TIMING>().swap(accTimings);

	play = _play;
	const int KEYS = 2;
	std::tuple<long, int, int> frame;
	Hitobject *prevNotes, *currNotes, *nextNotes;

	// Frame vars
	int iFrame = -1;
	bool stop = false;

	// process each column individualy
	int iNote;					// keep track where we are on the map
	bool nextNote;				// whether to fetch next note on column or not
	std::vector<bool> pressStates;			// which state we are expecting
	pressStates.resize(KEYS);

	// init vars for each column
	{
		iNote = -1;

		currNotes = getNextNote(&iNote);
		nextNotes = getNextNote(&iNote);
		
		nextNote = false;

		for (int key = 0; key < KEYS; key++)
			pressStates[key] = true;
	}

	// get first frame
	frame = getNextEvent(&iFrame);

	do // key press-release processor
	{
		int keyPresses = std::get<1>(frame);
		int keyReleases = std::get<2>(frame);

		for (int key = 0; key < KEYS; key++)
		{
			bool valid = (((keyPresses & (1 << key)) > 0) && (pressStates[key] == true)) ||
						 (((keyReleases & (1 << key)) > 0) && (pressStates[key] == false));

			// if there is a key event on a column er are expecting
			if (valid)
			{
				int hitTiming = INT_MAX;
				int hitState = 1;

				if (currNotes != nullptr)
				{
					if (pressStates[key] == true)	// if we are pressing the key
					{
						hitState = SCORE::getJudgment(std::get<0>(frame), currNotes->getTime(), pressStates[key]);
						hitTiming = std::get<0>(frame) - currNotes->getTime();
					}
					else							// if we are releasing the key
					{
						hitState = SCORE::getJudgment(std::get<0>(frame), currNotes->getEndTime(), pressStates[key]);
						hitTiming = std::get<0>(frame) - currNotes->getEndTime();
					}

					SCORE::KeyInfo info = {};
						info.hitTiming = hitTiming;
						info.key = key;
						info.nextNote = &nextNote;
						info.pressState = &pressStates;

					switch (hitState)
					{
						case 0:		// hit
							SCORE::processHit(&accTimings, currNotes, info);
							break;

						case 1:		// hit and miss
							SCORE::processMiss(&accTimings, currNotes, info);
							break;

						case 2:     // never hit the note
							SCORE::processMiss(&accTimings, currNotes, info);

							// get next note
							if (nextNote == true)
							{
								prevNotes = currNotes;
								currNotes = nextNotes;
								nextNotes = getNextNote(&iNote);

								nextNote = false;
							}
	
							// redo this frame
							key--;
							continue;
							break;

						case 3:		// no hit, no miss
							break;

						default:
							break;
					};
				}
			}

			// get next note
			if (nextNote == true)
			{
				prevNotes = currNotes;
				currNotes = nextNotes;
				nextNotes = getNextNote(&iNote);

				nextNote = false;
			}
		}

		frame = getNextEvent(&iFrame); // get next press/release whatever column it is
		stop = !(iFrame < play->replay->getNumFrames()); // stop when we reached end of replay
	} while (!stop);

	std::sort(accTimings.begin(), accTimings.end(), sortAccTimings);
}
Esempio n. 5
0
void MusicPlayer::nextNote() {

    getNextNote();
    startNoteTimer();

}
bool canHammerOnOrPullOff(const Voice &voice, int position, const Note &note)
{
    const Note *nextNote = getNextNote(voice, position, note.getString());
    return nextNote && nextNote->getFretNumber() != note.getFretNumber();
}
Esempio n. 7
0
// fill buff
int SoundGenPCJr::chanGen(int chan, int16 *stream, int len) {
    ToneChan *tpcm;
    Tone toneNew;
    int fillSize;
    int retVal;

    tpcm = &_tchannel[chan];

    retVal = -1;

    while (len > 0) {
        if (tpcm->noteCount <= 0) {
            // get new tone data
            toneNew.freqCount = 0;
            toneNew.atten = 0xF;
            toneNew.type = kGenTone;
            if ((tpcm->avail) && (getNextNote(chan, &toneNew) == 0)) {
                tpcm->atten = toneNew.atten;
                tpcm->freqCount = toneNew.freqCount;
                tpcm->genType = toneNew.type;

                // setup counters 'n stuff
                // SAMPLE_RATE samples per sec.. tone changes 60 times per sec
                tpcm->noteCount = SAMPLE_RATE / 60;
                retVal = 0;
            } else {
                // if it doesn't return an
                tpcm->genType = kGenSilence;
                tpcm->noteCount = len;
                tpcm->avail = 0;
            }
        }

        // write nothing
        if ((tpcm->freqCount == 0) || (tpcm->atten == 0xf)) {
            tpcm->genType = kGenSilence;
        }

        // find which is smaller.. the buffer or the
        fillSize = (tpcm->noteCount <= len) ? tpcm->noteCount : len;

        switch (tpcm->genType) {
        case kGenTone:
            fillSize = fillSquare(tpcm, stream, fillSize);
            break;
        case kGenPeriod:
        case kGenWhite:
            fillSize = fillNoise(tpcm, stream, fillSize);
            break;
        case kGenSilence:
        default:
            // fill with whitespace
            memset(stream, 0, fillSize * sizeof(int16));
            break;
        }

        tpcm->noteCount -= fillSize;
        stream += fillSize;
        len -= fillSize;
    }

    return retVal;
}