/* * EXAMPLE: Pure Random Motor Babbling * * This example bypasses all linguistic rules, phoneme definitions, and attractor states. * It sends completely random vectors to the articulatory physics engine. * * That is the sound of raw, uncoordinated motor commands! Without a 'brain' * (linguistic rules) to smooth things out and coordinate the glottis with the tongue, * you essentially get the acoustic equivalent of a seizure or extreme distress. * * It proves that human speech is less about having a mouth and more about the * incredibly precise, learned choreography of closing it. */ #include #include #include #include "articulator.h" #include "transcriber.h" extern char RAW_OUTPUT_BUFFER[]; 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[]; float randf(float min, float max) { return min + ((float)rand() / (float)RAND_MAX) * (max - min); } // PURE RANDOM GENERATOR // No concept of vowels, consonants, or linguistic structure. // Just random points in the 6-dimensional muscle space. f6_t generate_random_target(void) { f6_t t; // 1. Randomize Articulators (0.0 - 1.0) t.tx = randf(0.0, 1.0); // Tongue Place (Front <-> Back) t.ty = randf(0.0, 1.0); // Tongue Height (Roof <-> Open) t.la = randf(0.0, 1.0); // Lips (Closed <-> Wide) t.lr = randf(0.0, 1.0); // Rounding (Spread <-> Round) // Velum (Oral vs Nasal) // We use discrete values (0.0 or 1.0) because continuous random values (e.g. 0.5) // create physically ambiguous targets that result in constant air leakage. t.nz = (rand() % 5 == 0) ? 1.0f : 0.0f; // 20% chance of nasal // 2. Randomize Glottis (Voicing) // We bias slightly towards voicing (0.5-1.0) to ensure audible output. // Using pure 0.0-1.0 would result in ~40% silent breathing. if (rand() % 10 < 2) { t.gt = randf(0.0, 0.4); // Breath/Silence } else { t.gt = randf(0.5, 0.9); // Voicing/Creak } return t; } void motor_babble(int count) { printf("\n=== Random Motor Babble (%d gestures) ===\n", count); // Allocate memory for the stream (1 chunk per gesture) f6_t* stream = malloc(sizeof(f6_t) * count); for (int i = 0; i < count; i++) { stream[i] = generate_random_target(); } // Run the physics simulation simulate_motor_stream(stream, count); char word[256]; 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); free(stream); } int main(void) { srand(time(NULL)); // Generate 5 random sequences of varying length for (int i = 0; i < 5; i++) { motor_babble(8 + rand() % 8); } return 0; }