
Eddie Jonathan Garcia Borbon
PITCH CLASS SET CALCULATOR
Esta calculadora es una herramienta que pretende facilitar los cálculos de la teoría de conjuntos aplicada a la música, fue programada en java bajo el paradigma de la programación orientada a objetos.
Se puede calcular:
-Forma Normal.
-Forma Prima.
-Numero forte.
-Vector Intervalico.
-Transposición.
-Transposición con inversión.
Y también, cuenta con un breve resumen de la teoría de conjuntos aplicada al análisis y composición musical.
Interfaz Grafica - GUI

/************************************************************************************************************\
*
* PitchSet
*
* Esta clase incluye los metodos de las operaciones de la calculadora los cuales son:
* Transposicion, inverson, complemento, forma normal, forma prima y la matriz del intervalo
*
* los metodos son los siguientes
*
* PitchSet getComplement(); devuelve el conjunto complemento
* PitchSet transpose(int t); mueve o transporta todas las notas transportadas en un entero t
* PitchSet invert(); devuelve la inversion del conjunto (simetria en espejo)
* PitchSet TnI(int t); primero invierte y luego transpone
* String toString; devuelve una lista del conjunto en numeros separado por comas
* String toKeys(); devuelve una lista del conjunto en notas separado por comas
* PitchSet getNormalForm(); devuelve la forma normal
* PitchSet getPrimeForm(); devuelve la forma prima
*
\***********************************************************************************************************/
package Negocio;
import java.io.Serializable;
import java.util.*;
/**
*
* @author Brayan Steeven Roriguez y Eddie Jonathan Garcia Borbon
*/
public class PitchSet extends Thread implements Serializable{
// Declarando las variables
private String Cadena;
public int[] noteArray; // ordena los arreglos o conjuntos de notas
private PitchSet TnI;
private PitchSet NormalForm;
private PitchSet PrimeForm;
public String getCadena(){
return Cadena;
}
public void setCadena(String arg){ //Encapsulamiento
Cadena=arg;
}
PitchSet() {
int[] suspendido = {0, 2,7};
this.noteArray = suspendido; // Acorde Suspendido por defecto
}
public PitchSet(int[] noteArray) { // el arreglo de notas es de enteros
this.noteArray = noteArray;
checkIntegrity();//comprueba la integridad del arreglo
}
public PitchSet(String arg) { // llama a una cadena de enteros separado por comas, eliminando todos los espacios en blanco
StringTokenizer removeSpaces = new StringTokenizer(arg);
/******
* Se hace uso d ela clase StringTokenizer la cual nos ayuda a subdividir un string en substrings o tokens
* (normalmente un caracter) separador entre ellos denominado delimitador
* Tokens= cadena de caracteres que tiene un significado coherente
*/
String spaceFree = new String("");
while (removeSpaces.hasMoreTokens()) {
//hasMoreToken: este metodo se utiliza para comprobar si hay mas fichas disponibles en la cadena de tokenizer
// ahora se dividira el espacio de cadena vacio en tokens
spaceFree += removeSpaces.nextToken();
}
String delim = new String(","); // delimitador uno o mas caracteres utilizados para separar tokens
StringTokenizer integerTokens = new StringTokenizer(spaceFree, delim, false); //countTokens: este metodo se utiliza para calcular
int[] integersPassed = new int[integerTokens.countTokens()];
//el numero de veces que pueda ser llamado antes de que se genere alguna excepcion
int i = 0;
while (integerTokens.hasMoreTokens()) {
try {
String item = integerTokens.nextToken().toString();
try {
integersPassed[i] = modTwelve(new Integer(item).intValue());
//controlador de excepciones asociados a un bloque,ningun codigo puede seguir hasta comprobar
//la excepcion NumberFormatExpcetion,el cual indica que si no se introducen o si no es
// un caracter numerico no sigue
} catch (NumberFormatException n) {; // NoSuchElementException: metodo de enumeracion para indicar que no hay mas elementos
}
i++;
} catch (NoSuchElementException e) {;
}
} // ends while()
this.noteArray = integersPassed;
checkIntegrity();
}
/***
* PitchSet getComplement calcula el conjunto complemento del arreglo de notas dado por el usuario
*
*/
//ends getComplement
public PitchSet transpose(int x) { // recibe un entero, el cual sumara cada uno de los elementos del arreglo
x = modTwelve(x); // en caso de que x sea mayor que 12...se le aplica mod 12
int[] transposed = new int[this.noteArray.length];
for (int i = 0; i < this.noteArray.length; i++) {
transposed[i] = modTwelve(noteArray[i] + x);
}
PitchSet Trans = new PitchSet(transposed);
return Trans;
} // ends transpose()
/**
* Devuelve la Inversion del arreglo, la inversion es una operacion simple, se trata de convertir una altura x
* en negativa
* I(x)=-x+n ó x-n
* por ejemplo: I(7)=-7+8=1
* tenemos el conjunto <0,3,7,8,-1> su inversion seria <0,-3,7,8,-1>...Falta esta operacion
*
*
* PitchSet Invert es un inversor de grupos de alturas
* I(x)=12-x
*/
public PitchSet invert() {
int[] inverted = new int[this.noteArray.length];
for (int i = 0; i < this.noteArray.length; i++) {
if (this.noteArray[i] != 0) {
inverted[i] = (12 - this.noteArray[i]);
}
}
PitchSet Inv = new PitchSet(inverted);
return Inv;
} // ends invert()
public String toString() {// retorna un arreglo de numeros que representa las notas
String s = new String();
for (int i = 0; i < this.noteArray.length; i++) {
if (i == (this.noteArray.length - 1)) {
s += new Integer(noteArray[i]).toString();
} else {
s += new Integer(noteArray[i]).toString();
s += new String(", ");
} // ends if
}
return s;
} // ends toString()
/**
* retorna un arreglo de letras que representan las notas
*
*/
public String toKeys() {
String[] keyArray = {"C", "C#", "D", "Eb", "E", "F", "F#", "G", "Ab", "A", "Bb", "B"};
String s = new String();
for (int i = 0; i < this.noteArray.length; i++) {
if (i == (this.noteArray.length - 1)) {
s += keyArray[noteArray[i]];
} else {
s += keyArray[noteArray[i]];
s += new String(", ");
} // ends if
}
return s;
} // ends toKeys()
/*
* Operacion de transposicion + inversion
*
*/
/*
public PitchSet TnI(int t) {
PitchSet Inverted = this.invert();
PitchSet Transposed = Inverted.transpose(t);
return Transposed;
} // ends TnI()
*/
/*
* Operacion modulo 12
*/
public int[] getNote(){
return noteArray;
}
public int modTwelve(int i) {
if (i >= 0 && i < 12) {
return i;
} else {
i = i % 12; // the integer remainder after division by 12, which might be negative
if (i < 0) {
i += 12;
}
return i;
}
} // ends modTwelve()
/*
* calcula la suma de los elementos del arreglo
*
*/
public int sum(PitchSet PS) { // calculates the sum of all the note values
int l = PS.noteArray.length;
int SUM = 0;
for (int i = 0; i < l; i++) {
SUM += PS.noteArray[i];
}
return SUM;
}
public PitchSet getNormalForm()
{
return NormalForm;
}
public PitchSet getPrimeForm()
{
return PrimeForm;
}
@Override
public void run() {
/***
* esta clase calcula la forma normal
* El procedimiento básicamente utilizado en el análisis de alturas (Pitch Class),
* es el de obtener el camino más corto de su distribución interválica, es decir,
* el elemento de menor longitud según la escala cromática.
* Así, tenemos cuatro combinaciones posibles y la pregunta es la siguiente,
* ¿cuál es la ideal?. Para ello debemos realizar las formulaciones antedichas
* entre las diferentes distancias interválicas determinando, de ese modo,
* cuál de ellas es la que tiene la suma menor, que será, a su vez, la ideal.
* i<0,2> + i<2,6> + i<6,11> = 2 + 4 + 5 = 11
* i<2,6> + i<6,11> + i<11,0> = 4 + 5 + 1 = 10
* i<11,0> + i<0,2) + i<2,6> = 1 + 2 + 4 = 7
*
* por tanto, la última, la que posee la combinación 11, 0 ,2 ,6 la ideal
*/
int l = this.noteArray.length;
int check, sigma, rightside, pitchvalue, transum, tau;
pitchvalue = 0;
rightside = 0;
PitchSet Transposed;
PitchSet sorted = this.sort();
sigma = 1000;
tau = 1000;
for (int i = 0; i < l; i++) {
Transposed = sorted.transpose(-sorted.noteArray[i]);
Transposed = Transposed.rotate(i);
check = Transposed.noteArray[l - 1];
transum = sum(Transposed);
if (check < sigma) {
sigma = check;
rightside = i;
pitchvalue = sorted.noteArray[i];
tau = transum;
} else if (check == sigma && transum < tau) {
rightside = i;
pitchvalue = sorted.noteArray[i];
tau = transum;
} else if (check == sigma && transum == tau && pitchvalue > sorted.noteArray[i]) {
rightside = i;
pitchvalue = sorted.noteArray[i];
}
}
PitchSet Normalized = sorted.rotate(rightside);
NormalForm=Normalized;
PitchSet Normalized1, invNormalized, AnswerSet;
Normalized1 =Normalized;
invNormalized = this.invert();
Normalized1 = Normalized1.transpose(-Normalized1.noteArray[0]);
invNormalized = invNormalized.transpose(-invNormalized.noteArray[0]);
if (sum(Normalized1) < sum(invNormalized)) {
AnswerSet = Normalized1.sort();
} else {
AnswerSet = invNormalized.sort();
}
// Clases Especiales:
// Forte Prime form packed Prime form packed
// name from the right to the left
// ----------------------------------------------
// 5-20 (01568) (01378)
// 6-Z29 (023679) (013689)
// 6-31 (014579) (013589)
// 7-20 (0125679) (0124789)
// 8-26 (0134578T) (0124579T)
// 5-20
if (AnswerSet.toString().equals("0, 1, 3, 7, 8")) {
AnswerSet = new PitchSet("0,1,5,6,8");
}
// 6-Z29
if (AnswerSet.toString().equals("0, 1, 3, 6, 8, 9")) {
AnswerSet = new PitchSet("0,2,3,6,7,9");
}
// 6-31
if (AnswerSet.toString().equals("0, 1, 3, 5, 8, 9")) {
AnswerSet = new PitchSet("0,1,4,5,7,9");
}
// 7-20
if (AnswerSet.toString().equals("0, 1, 2, 4, 7, 8, 9")) {
AnswerSet = new PitchSet("0,1,2,5,6,7,9");
}
// 8-26
if (AnswerSet.toString().equals("0, 1, 2, 4, 5, 7, 9, 10")) {
AnswerSet = new PitchSet("0,1,3,4,5,7,8,10");
}
PrimeForm=AnswerSet;
} // ends getNormalForm()
public PitchSet rotate(int x) {
// reorganizar el orden del conjunto desplazando x lugares todos los campos a la izquierda
int l = this.noteArray.length; //
// ajustar x 0 <= x < l
if (x < 0 || x >= l) {
x = x % l;
if (x < 0) {
x += l;
}
}
// crea una matriz de enteros para llenar
int[] rotated = new int[l];
for (int i = 0; i < l; i++) {
if ((i + x) >= l) {
x -= l;
}
rotated[i] = noteArray[i + x];
}
PitchSet Rotated = new PitchSet(rotated);
return Rotated;
} // ends rotate()
public boolean Comprobacion(String a){
char[]b;
b=a.toCharArray();
for(int j=0;j<b.length;j++)
{
if((b[j]!='1')&&(b[j]!='2')&&(b[j]!='3')&&(b[j]!='4')&&(b[j]!='5')&&(b[j]!='6')&&(b[j]!='7')&&(b[j]!='8')&&(b[j]!='9')&&(b[j]!='0')&&(b[j]!=',')&&(b[j]!=' '))
{
return false;
}
}
return true;
}
public PitchSet sort() {
int l = this.noteArray.length;
int[] sorted = new int[l];
int k = 0;
for (int i = 0; i < 12; i++) {
for (int j = 0; j < l; j++) {
if (this.noteArray[j] == i) {
sorted[k] = i;
k++;
}
}
}
PitchSet Sorted = new PitchSet(sorted);
return Sorted;
} // ends sort()
void checkIntegrity() { // elimina entradas duplicadas
int l = this.noteArray.length;
int[] Twelve = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int[] buffer = new int[12];
int count = 0;
for (int i = 0; i < l; i++) {
if (Twelve[this.noteArray[i]] == 0) {
Twelve[this.noteArray[i]] = 1;
buffer[count] = this.noteArray[i];
count++;
} // ends if
} // ends for
int[] scrubbed = new int[count];
for (int j = 0; j < count; j++) {
scrubbed[j] = buffer[j];
}
this.noteArray = scrubbed;
}
public boolean contains(int c) { // comprueba si c esta en el arreglo de notas
int l = this.noteArray.length;
boolean answer = false;
for (int i = 0; i < l; i++) {
if (this.noteArray[i] == c) {
answer = true;
}
}
return answer;
}
}