#include struct ratio { int over; int under; }; main(int argc, char *argv[]) { struct ratio diamond[29][29]; struct ratio one_one; int relation[29]; int i, k; int limit; if(argc < 2) { fprintf(stderr, "To produce Incipient Tonality Diamonds, enter the tonal relation along a side.\n"); fprintf(stderr, "(See Harry Partch, \"Genesis of a Music\", Chapters 7 and 8).\n"); fprintf(stderr, "The untonalities will form one side of the diamond and the otonalities the other\n"); fprintf(stderr, "and the rest get filled in from there.\n\n"); fprintf(stderr, "For example, try entering [%s 4 5 6] (the ordinary triad relations)\n", argv[0]); fprintf(stderr, "to see the septimal just scale,\n", argv[0]); fprintf(stderr, "or [%s 4 5 6 7 8 9 10 11] to see Partch's 11 limit \n", argv[0]); fprintf(stderr, "as laid out on the Diamond Marimba\n"); exit(-1); } if(argc > 30) { fprintf(stderr, "Hard coded maximum of 29\n"); exit(-1); } limit = argc - 1; for(i = 1; i < argc; i++) relation[i-1] = atoi(argv[i]); one_one.over = one_one.under = 1; for(i = 0; i < limit; i++) { orelate(&diamond[i][0], &one_one, relation[i]); for(k = 1; k < limit; k++) /* into diamond[i][k] put diamond[i][0] * relation[k]/1 */ urelate(&diamond[i][k], &diamond[i][0], relation[k]); } for(i = 0; i < limit; i++) { for(k = 0; k < limit; k++) { printf("%3d/%-3d ", diamond[i][k].over, diamond[i][k].under); } printf("\n\n"); } } orelate(struct ratio *cell, struct ratio *base, int relation) { struct ratio multiplier; multiplier.under = 1; multiplier.over = relation; ratio_multiply_cpy(cell, base, &multiplier); } urelate(struct ratio *cell, struct ratio *base, int relation) { struct ratio multiplier; multiplier.over = 1; multiplier.under = relation; ratio_multiply_cpy(cell, base, &multiplier); } ratio_multiply_cpy(struct ratio *cell, struct ratio *base, struct ratio *multiplier) { cell->over = multiplier->over * base->over; cell->under = multiplier->under * base->under; normalize(cell); } normalize(struct ratio *cell) { prime_reduce(cell); if(cell->over == cell->under) { cell->over = cell->under = 1; return; } if(cell->over < cell->under) { if(cell->under%2 == 0) { cell->under /= 2; normalize(cell); return; } else { cell->over *= 2; normalize(cell); return; } } if(cell->under < cell->over) { if(cell->over/2 < cell->under) return; if(cell->over%2 == 0) { cell->over /= 2; normalize(cell); return; } else { cell->under *= 2; normalize(cell); return; } } } prime_reduce(struct ratio *cell) { static int prime[] = { 29, 23, 19, 17, 13, 11, 7, 5, 3, 2, 0 }; int i; for(i = 0; prime[i] != 0; i++) { if(cell->under%prime[i] == 0 && cell->over%prime[i] == 0) { cell->under /= prime[i]; cell->over /= prime[i]; prime_reduce(cell); } } return; }