Methodology

Sonifying Hamlet is a realtime app through which the textual data of Shakespeare’s Hamlet is decontextualized and reconstructed as acoustic objects. Within each sonification, a set of pre-created sounds have been tied to various textual events which the user may select. These events include the frequency with which individual characters speak, the frequency with which other characters appear adjacent to the presently speaking characters (i.e. the iteration of the text’s networks of physical proximity), the appearance of computationally sorted topics, and the appearance of thematically significant words. In each case, the available options enable the users to customize the sonification according to their textual and acoustic interests. This thereby renders the play as both an object to be data-mined acoustically, and as a constraint on production of computational music. That is, SH supports the text’s oscillation between the center and periphery of user attention.

Sonifying Hamlet was coded in Javascript. It makes use of the following libraries: Socket.IO, Express, Howler.JS, JQuery, XML2JS, Browserfy, Watchify, and Nodemon. The sounds of Sonifying Hamlet were selected from Logic Pro X. Sounds tied to textual data were created by recording individual notes of Logic’s pre-built instruments. Background sounds were selected from Logic’s prebuilt loops. Additionally, MALLET was used to topic model the text for topic-oriented sonifications.

The text Hamlet was chosen for its accessibility and ubiquity. That is to say that Hamlet is a public domain text that is widely read and performed. While the sonifications themselves, the acoustic component of Sonifying Hamlet, are instances of fair use and would thus be feasible with literary objects that are still under copyright, Sonifying Hamlet also reproduces the entire text verbatim as a means of allowing the user to track what section is being sonified at any given moment. This feature thus requires an expired copyright. In regards to the text’s ubiquity, as Hamlet is so widely read, and, more pointedly, as I have read it and seen it performed so many times at different stages of my life, I have long since lost the sense of strangeness and hermeneutic potency that colored my first few encounters with it. As this project is about creating an alien thing from something familiar, testing the success of this new novelty meant choosing what is for me the very antithesis of novelty. All of this is not to deny that Hamlet is a remarkable play. It’s just that the focus of Sonifying Hamlet is the experiment in acoustically remediating a literary object and as such Hamlet is here a means to an end. Truthfully, any similarly accessible and ubiquitous text would have done just as well.

Beginning with the Folger LIbrary’s xml file of Hamlet, the first step towards creating Sonifying Hamlet was to render this file in usable and compact format. For this, the file was first converted to JSON format using xml2js, a node library, and then a parser script was written to reconstruct the dialogue absent xml tags. Next, the text was topic modeled. This entailed first dividing the reconstructed text into ‘bags of words’, wherein the full speech of each character became a bag. (For especially verbose characters, their speech was divided into several bags). Then, these bags were processed through MALLET, which output a set of topics in txt format. This text file was then converted to JSON by hand. Next, a series of functions were written to break dialogue from the reconstructed text down into 1-3 line chunks*, and to associate each of these chunks with its associated topics, with the characters for whom those topics dominated their speech, with other characters who were then present in the scene, with the word counts of the given line and of the other characters then present, and with thematically significant words. Additionally, functions were written to create ordering templates, as well as the topic bags and speaker bags needed for Chance I and II. The output of all of these were combined into single file which serves as the basis for all of the app’s sonifications.

Once this sonification guide was constructed, a module was created which builds and emits the actual sonification data according to this guide, the audio files, and user selection. Each sonification is built as follows:

  • Background Audio: Each sonification has a unique background loop. At the start of each sonification, the audio file associated with this is emitted to the browser.
  • All sonifications: Except where otherwise noted, each sonification traverses user selected scenes in 1-3 line chunks*, according to a timer (one chunk every 5 seconds).
  • Presence I: If the current chunk is spoken by a character that the user has selected, then a log of the intensity/volume of the play’s characters is updated, such that the more a character speaks the louder they will sound when they are also-present-but-not-currently-speaking. Similarly, the more a character speaks while another character is not present in the scene, the quieter that also-present-but-not-currently-speaking character will sound. After this, a sonification object is built consisting of the dialogue chunk, the speaker’s audio, the audio files of the other characters present in the scene, and the intensity log. This object is then emitted to the browser where it is decoded and rendered.
  • Presence II: Similar to Presence I, if the current chunk is spoken by a character that the user has selected, then a log of where the characters are in space is updated, such that a character moves more to center the more they speak, and moves away from center the more others speak. After this, a sonification object is built consisting of the dialogue chunk, the speaker’s audio, and the spatial log. This object is then emitted to the browser where it is decoded and rendered.
  • Themes I: If the current chunk is correlated to a topic that the user has selected, then a sonification object is built consisting of the dialogue chunk and the topic’s audio. This object is then emitted to the browser where it is decoded and rendered.
  • Themes II: This sonification’s timer is 1.5 seconds instead of the 5 seconds used for the others. If the current chunk contains one or more theme words (or their synonyms) that the user has selected, then a sonification object is built consisting of the dialogue chunk, the audio for the selected and matched words, and the audio for all characters present in that scene. This object is then emitted to the browser where it is decoded and rendered.
  • Themes III: If the current chunk is correlated to topics, which are themselves the dominant topics of at least one user selected character, then a sonification object is built consisting of the dialogue chunk, the audio of speaker, a record of which characters’ top three topics were matched, and a record of whose very top topic was matched. This object is then emitted to the browser where it is decoded and rendered.
  • Chance I: In place of traversing selected scenes in 1-3 line chunks, this sonification traverses selected scenes according to the order in which characters speak. Once every 5 seconds, it moves to the next character in that scene’s order. If that character has been selected by the user, a bag of dialogue is built consisting of all of that character’s dialogue from all of the selected scenes. One chunk of 1-3* lines is then randomly selected and added to a sonification object that also contains the audio file of the speaker, and audio files of any topics matched to that randomly selected line. This object is then emitted to the browser where it is decoded and rendered.
  • Chance II: In place of traversing selected scenes in 1-3 line chunks, this sonification traverses selected scenes according to the order in which topics appear. Once every 5 seconds, it moves to the next set of topics in that scene’s order. If a topic in that set has been selected by the user, then a bag of dialogue is built consisting of all of lines of dialogue correlated to that topic from all of the selected scenes. If more than one user selected topic is present in that set, then one of these is randomly selected and a bag of dialogue is built consisting of all of lines of dialogue correlated to that topic from all of the selected scenes. One chunk of 1-3 lines* is then randomly selected from this bag and added to a sonification object that also contains the audio file of the speaker of that randomly selected line. This object is then emitted to the browser where it is decoded and rendered.
  • Client-side: A handful of client-side modules handle collecting user selections, emitting them to the server, decoding and rendering audio and textual data as it is received, and managing pause, seek, and volume options.

*The dialogue is chunked in this way in order to break up especially long passages.