first commit

This commit is contained in:
David Ali
2026-01-28 22:20:52 +01:00
commit c913cacf8d
13 changed files with 1172 additions and 0 deletions

178
examples/example_names.c Normal file
View File

@@ -0,0 +1,178 @@
/*
* EXAMPLE: Structured Name Generation (The "Brain")
*
* Unlike the random motor babbler, this program applies high-level linguistic
* constraints to the articulatory physics engine. It defines specific phoneme
* subsets (Languages) and grammar rules (Syllable Structure) to guide the mouth.
*
* It demonstrates that by constraining the chaos of the physics engine with
* simple rules (Attractor States), we can generate distinct, recognizable
* "accents" or "languages".
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "articulator.h"
#include "transcriber.h"
extern char RAW_OUTPUT_BUFFER[];
extern const phoneme_t PHONEME_DB[];
extern const ortho_rule_t ORTHO_IPA[];
extern const ortho_rule_t ORTHO_POLISH[];
extern const ortho_rule_t ORTHO_HUNGARIAN[];
extern const ortho_rule_t ORTHO_GERMAN[];
extern const ortho_rule_t ORTHO_CYRILLIC[];
extern const ortho_rule_t ORTHO_ORCISH[];
/* --- LANGUAGE DEFINITIONS --- */
/* Standard Fantasy/English-ish */
const char* LANG_COMMON[] = {"p", "b", "t", "d", "k", "g", "m", "n", "f", "v", "s", "z", "ʃ", "h", "r",
"l", "w", "j", "i", "u", "e", "o", "a", "ə", "ɪ", "ɛ", "æ", "ɔ", NULL};
const char* LANG_SLAVIC[] = {
// Vowels (Simple 6 system)
"i", "u", "e", "o", "a", "ɨ", // ɨ is Polish 'y'
// Consonants
"p", "b", "t", "d", "k", "g", "m", "n", "ɲ", // n, ń
"f", "v", "s", "z", "x", // f, w, s, z, ch
"ts", "dz", // c, dz
"ʃ", "ʒ", "", "", // sz, ż, cz, dż
"ɕ", "ʑ", "", "", // ś, ź, ć, dź
"l", "r", "j", "w", // l, r, j, ł
NULL};
/* Harsh/Orcish (Back of throat, Guttural) */
const char* LANG_ORCISH[] = {"k", "g", "q", "ɢ", "ʔ", "x", "χ", "ʁ", "h", "p", "b", "t", "d", "u", "o", "ɑ", "ɔ", NULL};
/* Soft/Elvish (Liquids, Fricatives, Front Vowels) */
const char* LANG_ELVISH[] = {"p", "b", "t", "d", "m", "n", "f", "v", "s", "z", "ʃ", "ʒ", "θ", "ð",
"l", "ʎ", "r", "w", "j", "i", "y", "e", "ø", "a", "ɛ", "œ", NULL};
/* --- FILTER HELPER --- */
/* Check if an IPA symbol exists in the allowed list */
int is_allowed(const char* ipa, const char** allowed_list) {
for (int i = 0; allowed_list[i] != NULL; i++) {
if (strcmp(ipa, allowed_list[i]) == 0) return 1;
}
return 0;
}
/* --- UPDATED GENERATOR --- */
void generate_name(const char* race_name, const char** allowed_sounds, int syllables) {
printf("\n=== Generating %s Name (%d syl) ===\n", race_name, syllables);
// 1. Build Index Cache for this Language
int v_indices[100], v_count = 0;
int c_indices[100], c_count = 0;
for (int i = 0; PHONEME_DB[i].ipa != NULL; i++) {
// Only add if it's in the allowed list
if (is_allowed(PHONEME_DB[i].ipa, allowed_sounds)) {
if (is_vowel_index(i)) {
if (v_count < 100) v_indices[v_count++] = i;
} else {
if (c_count < 100) c_indices[c_count++] = i;
}
}
}
if (v_count == 0 || c_count == 0) {
printf("Error: No sounds found for %s\n", race_name);
return;
}
// 2. Build Sequence (C-V-C pattern)
int len = 0;
int seq[100];
for (int s = 0; s < syllables; s++) {
// Onset
if (rand() % 10 < 7) seq[len++] = c_indices[rand() % c_count];
// Nucleus
seq[len++] = v_indices[rand() % v_count];
// Coda
if (rand() % 10 < 4) seq[len++] = c_indices[rand() % c_count];
}
// 3. Simulate & Transcribe
simulate_sequence(seq, len);
}
int main(void) {
srand(time(NULL));
char word[256];
for (int i = 0; i < 3; i++) {
generate_name("Human", LANG_COMMON, 2 + i);
printf("RAW: \"%s\"\n", RAW_OUTPUT_BUFFER);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_IPA);
printf("IPA: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_POLISH);
printf(" PL: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_HUNGARIAN);
printf(" HU: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_GERMAN);
printf(" DE: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_CYRILLIC);
printf(" RU: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_ORCISH);
printf("ORC: \"%s\"\n", word);
}
for (int i = 0; i < 3; i++) {
generate_name("Slavic", LANG_SLAVIC, 2 + i);
printf("RAW: \"%s\"\n", RAW_OUTPUT_BUFFER);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_IPA);
printf("IPA: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_POLISH);
printf(" PL: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_HUNGARIAN);
printf(" HU: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_GERMAN);
printf(" DE: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_CYRILLIC);
printf(" RU: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_ORCISH);
printf("ORC: \"%s\"\n", word);
}
for (int i = 0; i < 3; i++) {
generate_name("Orcish", LANG_ORCISH, 2 + i);
printf("RAW: \"%s\"\n", RAW_OUTPUT_BUFFER);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_IPA);
printf("IPA: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_POLISH);
printf(" PL: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_HUNGARIAN);
printf(" HU: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_GERMAN);
printf(" DE: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_CYRILLIC);
printf(" RU: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_ORCISH);
printf("ORC: \"%s\"\n", word);
}
for (int i = 0; i < 3; i++) {
generate_name("Elvish", LANG_ELVISH, 2 + i);
printf("RAW: \"%s\"\n", RAW_OUTPUT_BUFFER);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_IPA);
printf("IPA: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_POLISH);
printf(" PL: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_HUNGARIAN);
printf(" HU: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_GERMAN);
printf(" DE: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_CYRILLIC);
printf(" RU: \"%s\"\n", word);
transcribe(RAW_OUTPUT_BUFFER, word, ORTHO_ORCISH);
printf("ORC: \"%s\"\n", word);
}
return 0;
}