Menu

drum-circle-protocol

Roger B. Dannenberg Lawrence

Drum Circle Protocol

All communication is via a single TCP connection to/from clients/server except for HTTP used to find the server IP address and set up a connection.

The drum server has access to users and passwords and checks passwords when a connection is made (see Hello Message). In addition, the drum server has at least 2 classes of users: normal and admin. An admin can perform some special operations including Configure and send Voice messages.

Request (for Drum Server info)

Before talking directly to Drum Server, a client will make a request via HTTP, using POST to the web server for IP address, port, and secret session code for Drum Server.

The url is 'www.music.cs.cmu.edu', and the following key-value pairs are required:

username: <username> -- a drum player's id
password: <password> -- a drum player's password

Response (of Drum Server info)

After sending the request for Drum Server info, the client would receive a response containing the relevant info from the web server, if the <username> and <password> both match the ones stored in the database of web server.(Assume that Drum Server started before the client starts and stored its IP, port and secret session code in the database successfully.)

The response message consists of the following:

  • Status line

  • Headers

  • An empty line

  • HTTP message body data

IP address, port and secret session code are merged into a string, and stored in the message body data(mentioned above):

IP+'#'+port+'#'+secret_session_code -- pound is used to split information


Command numbers are:

  • 1 = AUDIOMSG

  • 2 = CHATMSG

  • 3 = DRUMMSG

  • 4 = CLOCKSYNCMSG

  • 5 = CONFIGMSG

  • 6 = HELLOMSG

  • 7 = SETDELAY

  • 8 = STARTMSG

  • 9 = BYEMSG

  • 10 = DIRMSG

  • 11 = SYNCMSG

Connection state numbers are:

  • 1 = ACCEPTED --connection built

  • 2 = WRONGNAME -- username doesn't exist

  • 3 = WRONGPWD -- password is wrong

  • 4 = WRONGSSC -- secret session code is wrong

  • 5 = WRONGSTATE -- user is not enabled

  • 6 = FATAL -- something wrong with the drum server

Hello Message (Outgoing to Server)

When a client first connects, it sends the secret session code to the server. If the server does not get the valid secret session code as the first message from the client, it drops the connection. If it does get the correct code, it sends a Hello Message as a reply, and then a CONFIGMSG; If it doesn't, it only sends a Hello Message, containing the error number.

  • msg_type (1 byte) = 6 = HELLOMSG -- a message type
  • length (4 bytes) -- network byte order 32-bit integer, length of session_code + user_name + # + password + zero byte
  • session_code (4 byte integer in network byte order) -- the random 32-bit secret session code.
  • user_name(1 byte per char), no end-of-string character (it's implied by "#")
  • '#'(1 byte) --pound is used to seperate the user_name and password
  • password(1 byte per char), zero-terminated string

Hello Message (Incoming to Client)

  • msg_type(1 byte) = 6 = HELLOMSG -- a message type
  • state_num(1 byte) --tell the client if the connection is built, if not, it is an error number

Configure (Incoming to Client)

When a client first connects, the server sends configuration information. Changes may be made later by sending another configuration message.

  • msg_type (1 byte) = 5 = CONFIGMSG -- a message type
  • play_beats (1 byte) - 8 bits indicating when to flash cues (if any). Low-order bit is on the downbeat, and there is one bit for each eighth note.
  • solo_mode (1 byte) - if true, the notes scheduled to be played in even measures are not forwarded by the server; this creates "gaps" where the players can "solo" (although all solos are merged and played back on the odd measures).

A configure message will be followed immediately by a Set Delay message.

Configure (Outgoing to Server, admin only)

An admin can send and change configuration information with this message.

  • msg_type (1 byte) = 5 = CONFIGMSG -- a message type
  • play_beats (1 byte) - 8 bits indicating when to flash cues (if any). Low-order bit is on the downbeat, and there is one bit for each eighth note.
  • solo_mode (1 byte) - if true, the notes scheduled to be played in even measures are not forwarded by the server; this creates "gaps" where the players can "solo" (although all solos are merged and played back on the odd measures).

(more configuration information is needed to assign drum sounds to different drums of different players)

Talkback Audio System (Outgoing to Server, Incoming to Client, admin only)

The audio system is used for voice communication to alert the ensemble and give instructions. Voice is one-way via TCP from an admin client to server and from the server to all the clients. Only admin clients can send a voice message to users. Voice messages are short recordings rather than continuous streams. The recordings are typically broken into packets, originally to allow streaming over UDP packets, but now this allows long audio messages to be interleaved with other messages. Packets for a single audio recording begin with "A" except the last packet which begins with "E". The voice message format is:

  • msg_type (1 byte) = 1 = AUDIOMSG -- a message type
  • length (4 bytes) -- network byte order 32-bit integer, 1 + number of audio samples
  • code (1 byte) -- ASCII "A" if this is not the end, "E" if this is the end of a recording
  • samples (1 byte each) -- 8 bit, 8kHz ulaw bytes

Chat System (Outgoing to Server)

Chat messages are all broadcast to everyone OR sent just to the administrator. Messages are sent via TCP as follows:

  • msg_type (1 byte) = 2 = CHATMSG -- a message type

  • length (4 bytes) -- network byte order 32-bit integer, length of destination + text

  • destination (1 byte per char, zero terminated)

    • The user name of the receiver. If this is an empty string (i.e. zero characters followed by 1 zero terminating byte), then the message goes to all admins, which normally would be the drum circle leader. If this is the string "*", then the message goes to all clients. If this is any other string, and the string matches a user name, the message is sent to that user. If this does not satisfy any of the previous tests, the message is sent (back) to the sender with the prefix "Recipient not found: ".
  • text (1 byte per char)

    • the message, zero terminated (zero byte is included in the length count). If this is an incoming message to the server, the name of the sender is prefixed to the message before sending it out to receivers. For example, a CHATMSG message comes into the server on a connection that was previously authenticated (using a password in a HELLOMSG) to belong to "Fred", and the destination is "Betty", and the text is "Hello". The outgoing message will have sender = "Fred", destination = "P" (private). The text will be "Hello".

Chat System (Incoming to Client)

Messages are sent via TCP as follows:

  • msg_type (1 byte) = 2 = CHATMSG -- a message type

  • length (4 bytes) -- network byte order 32-bit integer, length of sender + destination + text

  • sender (1 byte per char, zero terminated) -- The user name of the sender.

  • destination (1 byte)

    • "A", "P" or "*". If "A" this message was sent to all admins. If "P" this is a private message directed to this recipient only. If "*" this is a message to everyone.
  • text (1 byte per char) -- the message, zero terminated (zero byte is included in the length count).

The message displayed should match one of the following styles:
1. (private from Fred): Hello
2. (from Fred to all): Hello
3. (from Fred to admins): Hello

Set Delay (Outgoing to server, admin only)

  • msg_type (1 byte) = 7 = SETDELAY
  • start_time (4 bytes) -- millisecond time of master clock when this tempo starts; message should be sent 4 seconds or more ahead of start time so that clients all get the message ahead of the start time. Set Delay should not be called again until the previous start time has passed.
  • beats_per_cycle (1 byte) -- number of beats in one cycle; incoming beat time stamps have been delayed by this many beats. If beats_per_cycle is zero (0), the tempo/performance stops.
  • beat_period (2 byte integer in network order) -- the length in ms of a beat

While SETDELAY is in effect (i.e. until a beats_per_cycle of zero is sent), the server sends out time-keeping drum hits using channel 0, pitch 0 and channel 0, pitch 1 drums.

Set Delay (Incoming to client)

  • msg_type (1 byte) = 7 = SETDELAY
  • start_time (4 bytes) -- millisecond time of master clock when this tempo starts
  • beats_per_cycle (1 byte) -- number of beats in one cycle; incoming beat time stamps have been delayed by this many beats. If zero, the drumming should stop (or at least the time-keeping drum hits will stop.
  • beat_period (2 byte integer in network order) -- the length in ms of a beat

This information might be displayed to users, but since delay is controlled in the server, and the server sends "metronome" beats at the correct tempo, the data is not used by the client program to control anything.

Drum Strokes (Outgoing to server)

Drum stroke messages are sent for every user drum stroke via TCP as follows:

  • msg_type (1 byte) = 3 = DRUMMSG -- a message type
  • sender (1 byte) -- ID number for player
  • time_stamp (4 bytes) -- (estimated) absolute global clock time in ms of user time when drum was played (not the delayed time when the other users should hear it)
    drum_number (1 byte) -- indicates which of several drums were hit. The upper 4 bits give the drum class (e.g. bongo, timbale, cowbell), and the low-order 4 bits give different sounds from that drum class. Currently, there are two drums of class 0 (time-keeping low drums), and 7 drums (0-6) in each of five classes 1-5.
    drum velocity (1 byte) -- a MIDI velocity indicating how hard the drum was hit

Drum Strokes (Incoming to client)

  • msg_type (1 byte) = 3 = DRUMMSG -- a message type
  • sender (1 byte) -- ID number for player, 0 is used for "metronome" -- drum beats that are used to keep all the players together. The metronome is generated by the server.
  • time_stamp (4 bytes) -- absolute global clock time in ms when the drum stroke should be synthesized
  • drum_number (1 byte) -- indicates which of several drums were hit, should be consecutively numbered from 0, where drums 0 and 1 are the "metronome" drums.
  • drum velocity (1 byte) -- a MIDI velocity indicating how hard the drum was hit. For the metronome generated by the server, the velocity is 100.

Clock Sync (Outgoing to server)

  • msg_type (1 byte) = 4 = CLOCKSYNCMSG -- a message type
  • sequence_number (2 bytes) -- message ID to be returned by server
    last_round_trip_time (4 bytes) -- round-trip time in ms from last clock sync round, used by server to collect network statistics
  • last_clock_offset_ms (4 bytes) -- what was the estimated local time - server time at the last clock sync message?

Clock Sync (Incoming to client)

  • msg_type (1 byte) = 4 = CLOCKSYNCMSG -- a message type
  • sequence_number (2 bytes) -- message ID returned by server from outgoing clock sync message
  • global_time (4 bytes) -- time at the server in ms at the time the message was sent

Start (Outgoing to server)

Obsolete. The Start command tells the server to start or stop sending timekeeping drum hits. Timekeeping hits are a sequence of drum stroke messages with precise timing according to the beats per cycle and beat period to help users synchronize (experience shows that users cannot easily synchronize with each other with the long feedback loop created when drum beats are delayed one cycle.)

  • msg_type (1 byte) = 8 = STARTMSG - a message type
  • start_flag (1 byte) - either 0 (stop) or 1 (start)
  • time (4 bytes) - ms time at which to change state

Bye (Outgoing to server)

The Bye command tells the server to shut down. The main purpose is to flush and close the log file since there is no way to do this from the web interface. Ideally, you should say "Bye" from a client drum application logged in with admin privileges (the Bye message is ignored if it does not come from an admin) before you leave the web page showing server status.

  • msg_type (1 byte) = 9 = BYEMSG - a message type

Direction (Incoming to client)

A string is displayed to give directions.

  • msg_type (1 byte) = 10 = DIRMSG - a message type

  • length (4 bytes) -- network byte order 32-bit integer, length of text

  • text (1 byte per char) -- the message, zero terminated (zero byte is included in the length count).

Direction (Outgoing to server)

A string is sent to give directions.

  • msg_type (1 byte) = 10 = DIRMSG - a message type

  • length (4 bytes) -- network byte order 32-bit integer, length of text

  • text (1 byte per char) -- the message, zero terminated (zero byte is included in the length count).

Synchronized (Outgoing to server)

After synchronization is achieved, the client wants to know what is the state of play. This message requests the server to send information. When the server receives this message, it generates a SETDELAY message and a DIRMSG for this client.

  • msg_type (1 byte) = 11 = SYNCMSG - a message type

Bandwidth

Assume 100 players, 5 notes per second -> 500 notes per second total.
1 DRUMMSG = 16 bytes; 16 * 500 = 8000; 8000 * 8 = 64Kbps download per client. 6.4Mbps out from server.
Overhead is 4/16.

Scheduling

Admin sends DELAYMSG with at least 2s advanced notice. Server forwards message to clients that then schedule it to occur as scheduled. On the server side, we have notes scheduled for the future too, so these have to "see" the future schedule, especially for the solo mode where notes are muted on even measures. For now, the future state will take place immediately.


Related

Wiki: drum-circle-home

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.