Skip to content
No description, website, or topics provided.
JavaScript ActionScript Shell
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src
test_web_app
LICENSE-MIT.txt
README.md

README.md

Overview

This is an experimental sound engine & midifile player. At the moment it just uses flash 10 and is in a early stage of development. Use it on your on risk ;)

ROUGHLY tested with Firefox 23 and Chrome 28 and IE 10.

In short this library contains three parts:

  • DynSoundManager: which is basically a flash sample player wrapped in js.
  • MIDI.Player: reads Midi files and feeds the sample player with notes.
  • Envelope: Create Envelopes

NOTE: the MIDI.Player does not work in IE!

Development

I wrote this library due to the lack of dynamic soundlibrary for webbrowsers.

If there is enough interest, I can make the library more "failsafe" , or even make use of the html5 audio api. Effects like echo, distortion, flanger etc would also be possible.

Demo

* DEMO Page

DynSoundManager functionality

Loading Sounds

	// loads a sample as c2. 12 represents the corresponding midi note.
	dynsoundManager.load("harp", "12", "audio/harp-c2.mp3");
	// and another one
	dynsoundManager.load("female", "48", "audio/chorus-female-c5.mp3");
NOTE: Only MP3 are allowed. NOTE: I recommend to use low rate mp3s like 32kbit/s at the moment. MP3 with a higher bitrate are possible, but they use much more ram!

Playing Sounds

There are two ways to play sounds.

Playing a note once

	// play(instrumentId, noteId, volume, durationInMilliseconds)
	dynsoundManager.play("harp", "12", 0.5, 1000)); 
	// the sampler is quite smart. Eventhough theres only a sample loaded for midinote 12 you can do this:
	dynsoundManager.play("harp", "13", 1, 1000)); 
	// in the background the sampler bends the sample for midinote 12 to midinote 13.

NOTE: Volume goes from 0 to 1 and gets evaluated in a linear fashion. other values are possible, but will distort the sound. when you like it, do it ;) NOTE: Duration just limits the playing and will fade out in a smooth way. But it will not prolong the sample if it is to short.

Playing a 'Named Note'

	// playNamedNote(name, instrumentId, initNoteId, initVolume)
	// this will generate a note which will be looped again and again.
	dynsoundManager.playNamedNote("test", "harp","22")
	
	// now you can change its properties in realtime. These are your options
	dynsoundManager.setNamedNoteSetting("test", "midiNr", 30)
	dynsoundManager.setNamedNoteSetting("test", "vol", 0.2) // goes from  0 to 1
	dynsoundManager.setNamedNoteSetting("test", "pan", 0.1) // goes from -1 to +
	
	// you can change the loop behaviour and skip bytes at the start and end
	// this has to be done with the InstrumentSettings (more about settings you can read below)
	dynsoundManager.setInstrumentSetting("harp","skip_bytes_at_start", "5000")
	dynsoundManager.setInstrumentSetting("harp","skip_bytes_at_end", "3000")

	// get settings
	dynsoundManager.getNamedNoteSetting("test", "midiNr");
	// stop it 
	dynsoundManager.stopNamedNote("test");

NOTE: once created, the namednote sticks to the same sample at the moment and doesnt pick the nearest fitting

Settings

There are three kinds of settings

  • InstrumentSetting: options for the whole instrument
  • InstrumentNoteSetting: options only for one specific note of the instrument
  • Overall Settings: these options influence all played notes
	// setInstrumentSetting(instrument, settingName, settingValue);
 	dynsoundManager.setInstrumentSetting("harp","skip_bytes_at_start", "5000")
	dynsoundManager.setInstrumentSetting("harp","skip_bytes_at_end", "3000")
	dynsoundManager.setInstrumentSetting("harp","vol", "0.8") // 0 - 1 recommended
	dynsoundManager.setInstrumentSetting("harp","pan", "-0.5") // -1 - +1
	dynsoundManager.setInstrumentSetting("harp","fade_out_time", "5000") // in ms, only effects notes with a duration shorter then the sample used
	// setInstrumentNoteSetting(instrument, instrumentNote,settingName, settingValue);
	dynsoundManager.setInstrumentNoteSetting("harp","24","skip_bytes_at_start", "5000")
	dynsoundManager.setInstrumentNoteSetting("harp","24","skip_bytes_at_end", "3000")
	dynsoundManager.setInstrumentNoteSetting("harp","24","vol", "0.5") // 0 - 1 recommended
	dynsoundManager.setInstrumentNoteSetting("harp","24","pan", "+0.8") // -1 - +1
	dynsoundManager.setInstrumentNoteSetting("harp","24","fade_out_time", "5000") // in ms, only effects notes with a duration shorter then the sample used
	
	// getters
	dynsoundManager.getInstrumentSetting("harp","skip_bytes_at_end")
	dynsoundManager.getInstrumentNoteSetting("harp","skip_bytes_at_end")
	
	// overall settings
	dynsoundManager.setVolume(0.8); // 0 - 1
	dynsoundManager.setPan(-0.8);   // -1 - +1 , left to right
	dynsoundManager.setRate(2);     // shifts everything up or down. e.g. 2 would shift everything one octave up, 0.5 one octave down
 

MIDI.Player functionality

NOTE: The MIDI.Player does not work in IE

	// first tell the MIDI.Player where the DynSoundManager is
	MIDI.Player.setDynSoundManager(dynsoundManager);
	
	// now you have to asign instruments to the different channels
	// register them
	dynsoundManager.setChannelInstrument(0, "harp");
	dynsoundManager.setChannelInstrument(1, "piano");
	dynsoundManager.setChannelInstrument(2, "female");
	dynsoundManager.setChannelInstrument(3, "drums");
	// ...
	
	// load a song and start it
	MIDI.Player.loadFile('audio/test.mid');
	MIDI.Player.start()
	
	// set repeat mode. default is true
	MIDI.Player.repeat = true
	
	// stop the song currently loaded. This will also reset it back to start
	MIDI.Player.stop()
	
	// change the song. this will stop the old one if it is playing
	MIDI.Player.changeSong("audio/forellenquintett.mid")
	
	// you also can change the tempo, e.g. will playback the file with half the tempo
	MIDI.Player.timeStretch = 2
	
	// or can play it in a standarized way. this will playback the song without the tempochanges defined in the midi file.
	MIDI.Player.trueTempo = false
	// e.g. if timestretch is 1 and the song is played in a standardized fashion, the bpm will be 60
	MIDI.Player.timeStretch = 1
	// e.g. if timestretch is 2 and the song is played in a standardized fashion, the bpm will be 30
	MIDI.Player.timeStretch = 2
	// e.g. if timestretch is 0.5 and the song is played in a standardized fashion, the bpm will be 120
	MIDI.Player.timeStretch = 2
	
	// this can be really useful to synchronize the music to e.g. a game / game element etcetc.	

Envelope functionality

This Library also provides a helper class to setup envelops.
	// Envelope(value_table, times_table, mode, time_offset, curve, custom_curve, custom_start, custom_end)
// define a simple envelope with linear progession from point to point
// start at 0, reach 1 on second 1, go back to zero which will be reached at second 3.
// the envelope default state is "stopped", default mode is "repeat"
ev = new Envelope([0,1,0],[1,3])
// start it
ev.start()

// update it with delta time in seconds. for a game you could input here 1/framerate
ev.update(0.070) // add 70 ms
ev.current_value
ev.current_time

// you can set callback functions
ev.onUpdate = function() {console.log("Updated")}
ev.onFinish = function() {console.log("Envelope finished")}

// you also can create much more complicated envelopes thanks to the "custom_curve" attribute
// NOTE: this feature isnt perfect yet. custom curves can produce cracks at the transition point to the next defined point in the envelope
// NOTE: the custom_curve string argument is plain javascript. atm you can use 'y' and 'x' in your calculations.
// a sin 
ev = new Envelope([1,1],[1],"repeat",0,"custom","Math.sin(y/30)")
// same as the first example but with a "wavy" line
ev = new Envelope([0,1,0],[1,3],"repeat",0,"custom","Math.sin(y/30)")

// stop the envelope
ev.stop()

// look at its state, can be "playing", "stopped", "finished"
ev.state

// the mode, if it is "repeat", it will do so
ev.mode

Memory usage

// get memory usage
dynsoundManager.getMemoryUse()

Tribute

This piece of code is inspired by the following libraries;

* SoundManager2 by Scott Schiller * jasmid: Reads MIDI file byte-code, and translats into a Javascript array. * MIDI.js: Midi file player with many interfaces. * Pitch bending with flash: A clear example how to do dsp coding with flash * Sonatina Symphonic Orchestra: a creative commons-licensed orchestral sample library with many high quality samples to play around with.
You can’t perform that action at this time.