EVR.Sound.Prompt = function(sound)
{
   EVR.Animation.call(this, SOUND_PROMPT_FRAME_RATE);
   this.sound = sound;
   this.shifted = false;
   this.initialize();
   this.append();
   this.play();
}
EVR.Sound.Prompt.prototype = new EVR.Prompt;
EVR.inherit(EVR.Sound.Prompt, EVR.Animation);
EVR.Sound.Prompt.prototype.initialize = function()
{
   var container = this.sound;
   var text = SOUND_PROMPT_TEXT;
   var color = SOUND_PROMPT_COLOR;
   var size = SOUND_PROMPT_SIZE;
   var offset = SOUND_PROMPT_OFFSET;
   var spacing = SOUND_PROMPT_LETTER_SPACING;
   var height = SOUND_PROMPT_HEIGHT;
   EVR.Prompt.call(
      this, container, text, color, size, null, null, null, offset, spacing,
      height);
}
EVR.Sound.Prompt.prototype.sequence = function()
{
   var step = SOUND_PROMPT_STEP;
   var shifted = this.shifted;
   if (shifted)
   {
      this.move(step);
   }
   else
   {
      this.move(-step);
   }
   this.shifted = !shifted;
}
EVR.Sound.Prompt.prototype.hide = function()
{
   this.set_opacity(0);
}
EVR.Sound.Prompt.prototype.show = function()
{
   this.set_opacity(1);
}
EVR.Sound.Prompt.prototype.toString = function()
{
   return "[object EVR.Sound.Prompt]";
}
EVR.include("sound/audio/HTML5.js");
EVR.include("sound/audio/BGSound.js");
EVR.include("sound/audio/Embed.js");
EVR.Sound.Audio = function(container, type, format)
{
   EVR.Component.call(this, container, type);
   this.volume = SOUND_INITIAL_VOLUME;
   this.volume_step = SOUND_VOLUME_STEP;
   this.muted = true;
   this.format = format;
}
EVR.Sound.Audio.prototype = new EVR.Component;
EVR.Sound.Audio.prototype.set_song = function(name)
{
   this.song = name;
   this.set_path();
}
EVR.Sound.Audio.prototype.set_path = function()
{
   var root = SOUND_PATH;
   var song = this.song;
   var format = this.format;
   var quality = SOUND_QUALITY;
   var extension = format;
   var path = root + song + "/" + format + "/" + quality + "." + extension;
   this.element.setAttribute("src", path);
}
EVR.Sound.Audio.prototype.mute = function()
{
   if (this.muted)
   {
      this.muted = false;
      if (this.volume <= 0)
      {
	 this.increase_volume();
      }
   }
   else
   {
      this.muted = true;
   }
   this.set_volume();
}
EVR.Sound.Audio.prototype.increase_volume = function()
{
   var volume = this.volume + this.volume_step;
   if (volume > 1)
   {
      volume = 1.0;
   }
   if (this.muted)
   {
      this.mute();
   }
   this.volume = volume;
   this.set_volume();
}
EVR.Sound.Audio.prototype.decrease_volume = function()
{
   var volume = this.volume - this.volume_step;
   if (volume <= 0)
   {
      volume = 0;
      if (!this.muted)
      {
	 this.mute();
      }
   }
   else if (this.muted)
   {
      this.mute();
   }
   this.volume = volume;
   this.set_volume();
}
EVR.Sound.Audio.prototype.toString = function()
{
   "[object EVR.Sound.Audio]";
}
EVR.Sound.Audio.BGSound = function(container)
{
   EVR.Sound.Audio.call(this, container, "bgsound", "mp3");
   this.set_attributes();
   this.append();
}
EVR.Sound.Audio.BGSound.prototype = new EVR.Sound.Audio;
EVR.Sound.Audio.BGSound.prototype.set_attributes = function()
{
   var element = this.element;
   element.loop = -1;
   element.volume = -10000;
}
EVR.Sound.Audio.BGSound.prototype.set_volume = function()
{
   var element = this.element;
   if (this.muted)
   {
      element.volume = -10000;
   }
   else
   {
      element.volume = - parseInt((1 - this.volume) * 1500);
   }
}
EVR.Sound.Audio.BGSound.prototype.toString = function()
{
   return "[object EVR.Sound.Audio.BGSound]";
}
EVR.Sound.Audio.HTML5 = function(container)
{
   this.container = container;
   this.initialize_audio();
   this.volume = SOUND_INITIAL_VOLUME;
   this.volume_step = SOUND_VOLUME_STEP;
   this.set_attributes();
   this.append();
}
EVR.Sound.Audio.HTML5.prototype = new EVR.Sound.Audio;
EVR.Sound.Audio.HTML5.prototype.initialize_audio = function()
{
   var format = "ogg";
   if (!document.createElement("audio").canPlayType("audio/ogg"))
   {
      format = "mp3";
   }
   EVR.Sound.Audio.call(this, this.container, "audio", format);
}
EVR.Sound.Audio.HTML5.prototype.set_attributes = function()
{
   var element = this.element;
   element.volume = 0;
   element.addEventListener(
      "ended", function() { this.currentTime = 0; }, false);
}
EVR.Sound.Audio.HTML5.prototype.mute = function()
{
   EVR.Sound.Audio.prototype.mute.call(this);
   var element = this.element;
   if (element.paused)
   {
      element.play();
   }
}
EVR.Sound.Audio.HTML5.prototype.set_volume = function()
{
   var element = this.element;
   if (this.muted)
   {
      element.volume = 0;
   }
   else
   {
      element.volume = this.volume;
   }
}
EVR.Sound.Audio.HTML5.prototype.set_song = function(name)
{
   var element = this.element;
   var paused = element.paused;
   EVR.Sound.Audio.prototype.set_song.call(this, name);
   element.load();
   if (!paused && !this.muted)
   {
      element.play();
   }
}
EVR.Sound.Audio.HTML5.prototype.toString = function()
{
   return "[object EVR.Sound.Audio.HTML5]";
}
216.73.216.141
216.73.216.141
216.73.216.141
 
September 13, 2013

from array import array
from time import sleep

import pygame
from pygame.mixer import Sound, get_init, pre_init

class Note(Sound):

    def __init__(self, frequency, volume=.1):
        self.frequency = frequency
        Sound.__init__(self, self.build_samples())
        self.set_volume(volume)

    def build_samples(self):
        period = int(round(get_init()[0] / self.frequency))
        samples = array("h", [0] * period)
        amplitude = 2 ** (abs(get_init()[1]) - 1) - 1
        for time in xrange(period):
            if time < period / 2:
                samples[time] = amplitude
            else:
                samples[time] = -amplitude
        return samples

if __name__ == "__main__":
    pre_init(44100, -16, 1, 1024)
    pygame.init()
    Note(440).play(-1)
    sleep(5)

This program generates and plays a 440 Hz tone for 5 seconds. It can be extended to generate the spectrum of notes with a frequency table or the frequency formula. Because the rewards in Send are idealized ocean waves, they can also be represented as tones. Each level has a tone in its goal and a tone based on where the player's disc lands. Both play at the end of a level, sounding harmonic for a close shot and discordant for a near miss. The game can dynamically create these tones using the program as a basis.

I'm also building an algorithmically generated song: Silk Routes (Scissored). Here is an example of how it sounds so far.