Beispiel #1
0
	virtual void handleNote(uint8_t note, uint8_t duration) {
		int octave = noteOctave(note);
		if(channel < 8) {
			if(curOctave != octave) {
				if(curOctave == -1 || curOctave - octave > 1 || octave - curOctave > 1) {
					mmlf("o%d", octave);
				} else if(curOctave == octave + 1) {
					mmlf("<");
				} else if(curOctave == octave - 1) {
					mmlf(">");
				}
			}
			curOctave = octave;
		}
		if(duration > 0) {
			int mmlDuration;
			bool dot = false, percent = false;
			if(192 % duration == 0) {
				mmlDuration = 192 / duration;
			} else if(192 % (duration * 2 / 3) == 0 && (duration * 2) % 3 == 0) {
				dot = true;
				mmlDuration = 192 * 3 / duration / 2;
			} else {
				percent = true;
			}
			char buf[100];
			if(channel < 8) {
				sprintf(buf, "%s", noteName(note));
			} else {
				sprintf(buf, "n%d,", note);
			}
			if(percent) sprintf(buf + strlen(buf), "%%%d", duration);
			else sprintf(buf + strlen(buf), "%d", mmlDuration);
			if(dot) strcat(buf, ".");
			if(nextKeyOff) strcat(buf, "&");
			if(nextPortamento) {
				int nextNote = note + (nextPortamento * duration + (nextPortamento < 0 ? -16383 : 16383)) / 16384;
				int nextOctave = noteOctave(nextNote);
				strcat(buf, "_");
				if(nextOctave != octave) sprintf(buf + strlen(buf), "o%d", nextOctave);
				curOctave = nextOctave;
				sprintf(buf + strlen(buf), "%s", noteName(nextNote));
			}
			mmlf("%s", buf);
		}
		nextKeyOff = false;
		nextPortamento = 0;
	}
Beispiel #2
0
void Tuner::draw(double time)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	text.print(noteName(notes[currentNote]), 960 - 140, 540 - 16, 32);

	float level = d.rms();
	// scale to 0 .. 1
	level = (level - o.noiseRMS) / (o.signalRMS - o.noiseRMS); 

	d.analyze();
	float detectedFrequency = d.result();
	float cents = centDifference(detectedFrequency, targetFrequency);
	
	char textBuf[64];
	sprintf(textBuf, "%.0f", cents);
	text.print(textBuf, 960 - 100, 540 - 16, 32);
	sprintf(textBuf, "%.2f", level);
	text.print(textBuf, 960 - 400, 540 - 16, 32);
	
	glUseProgram(programId);
	glEnableVertexAttribArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);

	drawBackground();

	glUniform3f(uniformTintId, level, level, level);
	// clamp to -50 .. +50
	float clamped = std::min(std::max(cents, -50.0f), 50.0f);
	// scale to -45° .. +45°
	float angle = clamped / 50 * PI / 4;
	gaugeVertices[2] = 960 + needleLength * cosf(angle);
	gaugeVertices[3] = gaugePositions[currentNote] + needleLength * sin(angle);
	glBufferData(GL_ARRAY_BUFFER, sizeof(float) * gaugeVertices.size(), gaugeVertices.data(), GL_STATIC_DRAW);
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
	glDrawArrays(GL_LINES, 0, 2);
	glDisableVertexAttribArray(0);

	if (!hit && fabs(cents) < o.precisionCentDelta)
	{
		hit = true;
		hitStart = time;
	}
	if (hit && fabs(cents) > o.precisionCentDelta)
	{
		hit = false;
	}
	if (hit && time - hitStart > o.precisionHoldTime)
	{
		nextNote();
	}
}
Beispiel #3
0
//------------------------------------------------------------------------------
const char* noteName(const double & pitch)
{
  return noteName(toInt(pitch));
}