<s> import wave , struct , random , math <EOL> import os , sys <EOL> from utility import * <EOL> from scales import * <EOL> sine = lambda f , t : math . sin ( <NUM_LIT:2> * math . pi * t * f / <NUM_LIT> ) <EOL> square = lambda f , t : <NUM_LIT> * ( ( t % ( <NUM_LIT> / f ) >= ( ( <NUM_LIT> / f ) / <NUM_LIT:2> ) ) * <NUM_LIT:2> - <NUM_LIT:1> ) <EOL> sawtooth = lambda f , t : ( t % ( <NUM_LIT> / f ) ) / ( <NUM_LIT> / f ) * <NUM_LIT:2> - <NUM_LIT:1> <EOL> def triangle ( f , t ) : <EOL> v = <NUM_LIT:2> * ( t % ( <NUM_LIT> / f ) ) / ( <NUM_LIT> / f ) <EOL> if t % ( <NUM_LIT> / f ) >= ( <NUM_LIT> / ( <NUM_LIT:2> * f ) ) : <EOL> v = <NUM_LIT:2> * <NUM_LIT:1> - v <EOL> v = <NUM_LIT:2> * v - <NUM_LIT:1> <EOL> return v <EOL> class Melopy : <EOL> def __init__ ( self , title = '<STR_LIT>' , volume = <NUM_LIT:20> , tempo = <NUM_LIT> , octave = <NUM_LIT:4> ) : <EOL> self . title = title . lower ( ) <EOL> self . rate = <NUM_LIT> <EOL> self . volume = volume <EOL> self . data = [ ] <EOL> self . tempo = tempo <EOL> self . octave = octave <EOL> self . wave_type = sine <EOL> def add_wave ( self , frequency , length , location = '<STR_LIT>' , level = None ) : <EOL> if location == '<STR_LIT>' : <EOL> location = len ( self . data ) <EOL> elif location < <NUM_LIT:0> : <EOL> location = <NUM_LIT:0> <EOL> elif location * <NUM_LIT> > len ( self . data ) : <EOL> location = len ( self . data ) / <NUM_LIT> <EOL> location = int ( location * <NUM_LIT> ) <EOL> if level == None : <EOL> level = self . volume <EOL> elif level > <NUM_LIT:100> : <EOL> level = <NUM_LIT:100> <EOL> elif level < <NUM_LIT:0> : <EOL> level = <NUM_LIT:0> <EOL> for n in range ( <NUM_LIT:0> , int ( <NUM_LIT> * length ) ) : <EOL> val = self . wave_type ( frequency , n ) <EOL> val *= level / <NUM_LIT> * <NUM_LIT> <EOL> if location + n >= len ( self . data ) : <EOL> self . data . append ( val ) <EOL> else : <EOL> current_val = self . data [ location + n ] <EOL> if current_val + val > <NUM_LIT> : <EOL> val = <NUM_LIT> <EOL> elif current_val + val < - <NUM_LIT> : <EOL> val = - <NUM_LIT> <EOL> else : <EOL> val += current_val <EOL> self . data [ location + n ] = val <EOL> def add_note ( self , note , length , location = '<STR_LIT>' , volume = None ) : <EOL> """<STR_LIT>""" <EOL> if not isinstance ( note , list ) : <EOL> note = [ note ] <EOL> if location == '<STR_LIT>' : <EOL> location = len ( self . data ) / <NUM_LIT> <EOL> if not isinstance ( volume , list ) : <EOL> volume = [ volume ] <EOL> if volume [ <NUM_LIT:0> ] == None : <EOL> volume = [ float ( self . volume ) / len ( note ) ] * len ( note ) <EOL> else : <EOL> volume = volume + [ volume [ - <NUM_LIT:1> ] ] * ( len ( note ) - len ( volume ) ) <EOL> for item , level in zip ( note , volume ) : <EOL> if item [ - <NUM_LIT:1> ] not in '<STR_LIT>' : <EOL> item += str ( self . octave ) <EOL> self . add_wave ( note_to_frequency ( item , self . octave ) , length , location , level ) <EOL> def add_melody ( self , melody , length ) : <EOL> for note in melody : <EOL> if note [ - <NUM_LIT:1> ] not in '<STR_LIT>' : <EOL> note += self . octave <EOL> self . add_wave ( note_to_frequency ( note ) , length ) <EOL> def add_whole_note ( self , note , location = '<STR_LIT>' , volume = None ) : <EOL> """<STR_LIT>""" <EOL> self . add_fractional_note ( note , <NUM_LIT:1.0> , location , volume ) <EOL> def add_half_note ( self , note , location = '<STR_LIT>' , volume = None ) : <EOL> """<STR_LIT>""" <EOL> self . add_fractional_note ( note , <NUM_LIT:1.0> / <NUM_LIT:2> , location , volume ) <EOL> def add_quarter_note ( self , note , location = '<STR_LIT>' , volume = None ) : <EOL> """<STR_LIT>""" <EOL> self . add_fractional_note ( note , <NUM_LIT:1.0> / <NUM_LIT:4> , location , volume ) <EOL> def add_eighth_note ( self , note , location = '<STR_LIT>' , volume = None ) : <EOL> """<STR_LIT>""" <EOL> self . add_fractional_note ( note , <NUM_LIT:1.0> / <NUM_LIT:8> , location , volume ) <EOL> def add_sixteenth_note ( self , note , location = '<STR_LIT>' , volume = None ) : <EOL> """<STR_LIT>""" <EOL> self . add_fractional_note ( note , <NUM_LIT:1.0> / <NUM_LIT:16> , location , volume ) <EOL> def add_fractional_note ( self , note , fraction , location = '<STR_LIT>' , volume = None ) : <EOL> """<STR_LIT>""" <EOL> self . add_note ( note , <NUM_LIT> / self . tempo * ( fraction * <NUM_LIT:4> ) , location , volume ) <EOL> def add_rest ( self , length ) : <EOL> for i in range ( int ( self . rate * length ) ) : <EOL> self . data . append ( <NUM_LIT:0> ) <EOL> def add_whole_rest ( self ) : <EOL> self . add_fractional_rest ( <NUM_LIT:1.0> ) <EOL> def add_half_rest ( self ) : <EOL> self . add_fractional_rest ( <NUM_LIT:1.0> / <NUM_LIT:2> ) <EOL> def add_quarter_rest ( self ) : <EOL> self . add_fractional_rest ( <NUM_LIT:1.0> / <NUM_LIT:4> ) <EOL> def add_eighth_rest ( self ) : <EOL> self . add_fractional_rest ( <NUM_LIT:1.0> / <NUM_LIT:8> ) <EOL> def add_sixteenth_rest ( self ) : <EOL> self . add_fractional_rest ( <NUM_LIT:1.0> / <NUM_LIT:16> ) <EOL> def add_fractional_rest ( self , fraction ) : <EOL> self . add_rest ( <NUM_LIT> / self . tempo * ( fraction * <NUM_LIT:4> ) ) <EOL> def parse ( self , string , location = '<STR_LIT>' ) : <EOL> tracks = string . split ( '<STR_LIT>' ) <EOL> if len ( tracks ) > <NUM_LIT:1> : <EOL> t = len ( self . data ) / <NUM_LIT> <EOL> for track in tracks : <EOL> self . parse ( track , t ) <EOL> return <EOL> cf = <NUM_LIT> <EOL> in_comment = False <EOL> for i , char in enumerate ( string ) : <EOL> if char == '<STR_LIT:/>' : <EOL> in_comment = not in_comment <EOL> if in_comment : <EOL> continue <EOL> elif char in '<STR_LIT>' : <EOL> if ( i + <NUM_LIT:1> < len ( string ) ) and ( string [ i + <NUM_LIT:1> ] in '<STR_LIT>' ) : <EOL> char += string [ i + <NUM_LIT:1> ] <EOL> self . add_fractional_note ( char , cf , location ) <EOL> if location != '<STR_LIT>' : <EOL> location += ( <NUM_LIT> / self . tempo * ( cf * <NUM_LIT:4> ) ) <EOL> elif char in map ( str , range ( <NUM_LIT:0> , <NUM_LIT:20> ) ) : <EOL> self . octave = int ( char ) <EOL> elif char == '<STR_LIT:+>' or char == '<STR_LIT>' : <EOL> self . octave += <NUM_LIT:1> <EOL> elif char == '<STR_LIT>' or char == '<STR_LIT:v>' or char == '<STR_LIT:->' : <EOL> self . octave -= <NUM_LIT:1> <EOL> elif char == '<STR_LIT:(>' or char == '<STR_LIT:]>' : <EOL> cf /= <NUM_LIT:2> <EOL> elif char == '<STR_LIT:)>' or char == '<STR_LIT:[>' : <EOL> cf *= <NUM_LIT:2> <EOL> elif char == '<STR_LIT:_>' : <EOL> self . add_fractional_rest ( cf ) <EOL> if location != '<STR_LIT>' : <EOL> location += ( <NUM_LIT> / self . tempo * ( cf * <NUM_LIT:4> ) ) <EOL> def parsefile ( self , filename , location = '<STR_LIT>' ) : <EOL> fr = open ( filename , '<STR_LIT:r>' ) <EOL> s = fr . read ( ) <EOL> fr . close ( ) <EOL> self . parse ( s , location ) <EOL> def render ( self ) : <EOL> """<STR_LIT>""" <EOL> melopy_writer = wave . open ( self . title + '<STR_LIT>' , '<STR_LIT:w>' ) <EOL> melopy_writer . setparams ( ( <NUM_LIT:2> , <NUM_LIT:2> , <NUM_LIT> , <NUM_LIT:0> , '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> p = - <NUM_LIT:1> <EOL> data_frames = [ ] <EOL> for i in range ( len ( self . data ) ) : <EOL> q = <NUM_LIT:100> * i / len ( self . data ) <EOL> if p != q : <EOL> sys . stdout . write ( "<STR_LIT>" % ( ( '<STR_LIT:=>' * int ( ( float ( i ) / len ( self . data ) * <NUM_LIT:50> ) ) + '<STR_LIT:>>' ) . ljust ( <NUM_LIT:50> ) , <NUM_LIT:100> * i / len ( self . data ) ) ) <EOL> sys . stdout . flush ( ) <EOL> p = q <EOL> packed_val = struct . pack ( '<STR_LIT:h>' , int ( self . data [ i ] ) ) <EOL> data_frames . append ( packed_val ) <EOL> data_frames . append ( packed_val ) <EOL> melopy_writer . writeframes ( '<STR_LIT>' . join ( data_frames ) ) <EOL> sys . stdout . write ( "<STR_LIT>" % ( '<STR_LIT:=>' * <NUM_LIT:50> ) ) <EOL> sys . stdout . flush ( ) <EOL> sys . stdout . write ( "<STR_LIT>" ) <EOL> melopy_writer . close ( ) <EOL> def play ( self ) : <EOL> """<STR_LIT>""" <EOL> os . startfile ( self . title + '<STR_LIT>' ) </s>
