Gerbil Vest: A Crude Lapping Generator
January 16, 2013
I’ve continued to tinker with automatic song generation since I posted Nickelmatic as I had a nagging sense that it was shooting fish in a barrel. The project I was intending to follow it suddenly started behaving frighteningly like Scott Walker when I was expecting Gordon Lightfoot — hey, you never know what direction these things are going to take — but it also led me in a new direction that has temporarily taken precedence.
I was trying to solve this problem: how can I take the endless and semi-comprehensible-at-best output from a Markov text generation algorithm, and filter it down to a subset that could plausibly serve as lyrics? I started working with syllables and emphasis, which quickly led me to the Festival speech synthesizer. This is capable of dictating audible speech from any piece of text, along with all the disambiguation that entails. (It can also sing — but more on that later.)
I’m a dedicated punner, so being able to split arbitrary text into its constituent chunks of audio (“constituent” into “k ax n s t ih ch uw ax n t”, for example) got me thinking: this would be a pretty comprehensive way to generate spoonerisms (famously, “the queer old dean” / “the dear old queen”) independent of all the quelling spirks that English has to offer. As long as Festival knows how to say it, we can spoonerize it: just try swapping a few of the initial segments and check to see if the results are words.
For example:
- Cunningly Strapped
- Verbal Generation
- Wickedly Funded
- Happily Crude
- Word Tease
Technically, this involved making at least a little bit of sense out of Festival. Not trivial, since the project appears to have been dormant for years (not much help when you’re trying to ask questions) and most of it is written in Scheme, a language only a deeply masochistic logician could love. (That’s probably a redundant subclause and might earn me some unhappy words from masochistic logicians.)
To cause Festival to spill its guts when parsing an utterance, give it the following command:
(utt.save (utt.synth (Utterance Text "Text to parse goes here")) "-")
…and it will respond (voluminously)…
EST_File utterance
DataType ascii
version 2
EST_Header_End
Features max_id 73 ; type Text ; iform "\"Text to parse goes here\"" ;
Stream_Items
1 id _1 ; name Text ; whitespace "" ; prepunctuation "" ;
2 id _2 ; name to ; whitespace " " ; prepunctuation "" ;
3 id _3 ; name parse ; whitespace " " ; prepunctuation "" ;
4 id _4 ; name goes ; whitespace " " ; prepunctuation "" ;
5 id _5 ; name here ; whitespace " " ; prepunctuation "" ;
6 id _10 ; name here ; pos_index 14 ; pos_index_score 0 ; pos rb ; phr_pos r ; pbreak_index 0 ; pbreak_index_score 0 ; pbreak B ; blevel 3 ;
7 id _9 ; name goes ; pos_index 17 ; pos_index_score 0 ; pos vbz ; phr_pos v ; phrase_score -5.70426 ; pbreak_index 1 ; pbreak_index_score 0 ; pbreak NB ;
8 id _8 ; name parse ; pos_index 17 ; pos_index_score 0 ; pos vb ; phr_pos v ; phrase_score -6.60872 ; pbreak_index 1 ; pbreak_index_score 0 ; pbreak NB ;
9 id _7 ; name to ; pos_index 15 ; pos_index_score 0 ; pos to ; phr_pos to ; phrase_score -5.42555 ; pbreak_index 1 ; pbreak_index_score 0 ; pbreak NB ;
10 id _6 ; name Text ; pos_index 8 ; pos_index_score 0 ; pos nn ; phr_pos n ; phrase_score -10.3227 ; pbreak_index 1 ; pbreak_index_score 0 ; pbreak NB ;
11 id _11 ; name B ;
12 id _12 ; name syl ; stress 1 ;
13 id _18 ; name syl ; stress 0 ;
14 id _21 ; name syl ; stress 1 ;
15 id _26 ; name syl ; stress 1 ;
16 id _30 ; name syl ; stress 1 ;
17 id _34 ; name pau ; dur_factor 0 ; end 0.22 ; source_end 0.090699 ;
18 id _13 ; name t ; dur_factor 0.634789 ; end 0.310965 ; source_end 0.195659 ;
19 id _14 ; name eh ; dur_factor -0.133182 ; end 0.410191 ; source_end 0.331396 ;
20 id _15 ; name k ; dur_factor -0.351397 ; end 0.494949 ; source_end 0.463243 ;
21 id _16 ; name s ; dur_factor -0.772883 ; end 0.575693 ; us_diphone_left s_ ; source_end 0.627433 ;
22 id _17 ; name t ; dur_factor -0.925472 ; end 0.632332 ; us_diphone_right _t ; source_end 0.801778 ;
23 id _19 ; name t ; dur_factor 0.567944 ; end 0.721827 ; source_end 0.917295 ;
24 id _20 ; name ax ; dur_factor 0.185781 ; end 0.777332 ; source_end 1.00126 ;
25 id _22 ; name p ; dur_factor 0.950834 ; end 0.905509 ; source_end 1.13827 ;
26 id _23 ; name aa ; dur_factor -0.0479225 ; end 1.00696 ; source_end 1.25813 ;
27 id _24 ; name r ; dur_factor 0.608371 ; end 1.086 ; source_end 1.42938 ;
28 id _25 ; name s ; dur_factor -0.635089 ; end 1.17236 ; source_end 1.55365 ;
29 id _27 ; name g ; dur_factor -0.367088 ; end 1.23428 ; source_end 1.64954 ;
30 id _28 ; name ow ; dur_factor -0.231509 ; end 1.37174 ; source_end 1.79892 ;
31 id _29 ; name z ; dur_factor -0.930547 ; end 1.42384 ; source_end 1.89767 ;
32 id _31 ; name hh ; dur_factor -0.111275 ; end 1.48751 ; source_end 1.97252 ;
33 id _32 ; name ih ; dur_factor 2.02008 ; end 1.60242 ; source_end 2.07464 ;
34 id _33 ; name r ; dur_factor 0.212421 ; end 1.66797 ; source_end 2.29317 ;
35 id _35 ; name pau ; dur_factor 0 ; end 1.88797 ; source_end 2.5747 ;
36 id _36 ; name L-L% ;
37 id _37 ; name H* ;
38 id _38 ; name H* ;
39 id _49 ; f0 88.3204 ; pos 1.66797 ;
40 id _48 ; f0 91.7665 ; pos 1.54497 ;
41 id _47 ; f0 99.9185 ; pos 1.42384 ;
42 id _46 ; f0 103.457 ; pos 1.30301 ;
43 id _45 ; f0 110.942 ; pos 1.17236 ;
44 id _44 ; f0 117.665 ; pos 0.956234 ;
45 id _43 ; f0 110.972 ; pos 0.777332 ;
46 id _42 ; f0 113.275 ; pos 0.749579 ;
47 id _41 ; f0 116.1 ; pos 0.632332 ;
48 id _40 ; f0 119.867 ; pos 0.360578 ;
49 id _39 ; f0 103.517 ; pos 0.22 ;
(...snip...)
This lists the words, then the number of syllables with stress information (I’m still trying to figure out how to dump the actual syllables), then finally the segments (“t-eh eh-k k-s s-t t-t t-ax ax-p p-aa aa-r r-s s-g g-ow ow-z z-hh hh-ih ih-r”) and frequency (pitch) information. And more, not included here.
For our purposes, we just strip out what looks like a segment and build up a list of these for each word. That’s the hard work and the rest is just a bit of brute force to determine what combinations work and what’s just nonsense.
The results are pretty satisfying. Give it a word like “possibility” and you’ll get…
possibility Deere's: disability / Paar's Parr's par's pars
possibility Dick's: disability / pock's pocks pox
possibility Dillard: disability / Pollard
possibility Dillard's: disability / Pollard's
possibility Dillon: disability / pollen
possibility Dillon's: disability / pollen's
possibility Dipper: disability / Popper
possibility Dipper's: disability / Popper's
possibility Dix: disability / pock's pocks pox
possibility Dix's: disability / pox's
possibility Dylan: disability / pollen
possibility Dylan's: disability / pollen's
possibility dearly: disability / parley
possibility dears: disability / Paar's Parr's par's pars
possibility deer's: disability / Paar's Parr's par's pars
possibility deers: disability / Paar's Parr's par's pars
possibility demur: disability / Palmer
possibility demurs: disability / Palmer's
possibility deter: disability / Potter potter
possibility deterred: disability / pottered
possibility deters: disability / Potter's potter's potters
possibility dick's: disability / pock's pocks pox
possibility dicks: disability / pock's pocks pox
possibility dill's: disability / pall's
possibility dillies: disability / Polly's
possibility dills: disability / pall's
possibility dilly: disability / Polly
possibility dilly's: disability / Polly's
possibility dimmed: disability / palmed
possibility dimmer: disability / Palmer
possibility dimmer's: disability / Palmer's
possibility dimmers: disability / Palmer's
possibility dims: disability / palm's palms
possibility dinned: disability / pond
possibility dipped: disability / popped
possibility dipper: disability / Popper
possibility dipper's: disability / Popper's
possibility dippers: disability / Popper's
possibility dipping: disability / popping
possibility dips: disability / pops
possibility disabilities: disability / possibilities possibility's
possibility disability: disability / possibility
possibility disability's: disability / possibilities possibility's
possibility ditties: disability / potties
possibility ditty: disability / potty
possibility ditty's: disability / potties
Starming chuff!
Check out Gerbil Vest for the source code and more generated spoonerisms.
Categorized as: Uncategorized
Leave a Reply