<s> from mt_media import Source , AudioFormat , AudioData <EOL> import ctypes <EOL> import os <EOL> import math <EOL> class ProceduralSource ( Source ) : <EOL> def __init__ ( self , duration , sample_rate = <NUM_LIT> , sample_size = <NUM_LIT:16> ) : <EOL> self . _duration = float ( duration ) <EOL> self . audio_format = AudioFormat ( <EOL> channels = <NUM_LIT:1> , <EOL> sample_size = sample_size , <EOL> sample_rate = sample_rate ) <EOL> self . _offset = <NUM_LIT:0> <EOL> self . _bytes_per_sample = sample_size >> <NUM_LIT:3> <EOL> self . _bytes_per_second = self . _bytes_per_sample * sample_rate <EOL> self . _max_offset = int ( self . _bytes_per_second * self . _duration ) <EOL> if self . _bytes_per_sample == <NUM_LIT:2> : <EOL> self . _max_offset &= <NUM_LIT> <EOL> def _get_audio_data ( self , bytes ) : <EOL> bytes = min ( bytes , self . _max_offset - self . _offset ) <EOL> if bytes <= <NUM_LIT:0> : <EOL> return None <EOL> timestamp = float ( self . _offset ) / self . _bytes_per_second <EOL> duration = float ( bytes ) / self . _bytes_per_second <EOL> data = self . _generate_data ( bytes , self . _offset ) <EOL> self . _offset += bytes <EOL> return AudioData ( data , <EOL> bytes , <EOL> timestamp , <EOL> duration , <EOL> [ ] ) <EOL> def _generate_data ( self , bytes , offset ) : <EOL> '''<STR_LIT>''' <EOL> raise NotImplementedError ( '<STR_LIT>' ) <EOL> def _seek ( self , timestamp ) : <EOL> self . _offset = int ( timestamp * self . _bytes_per_second ) <EOL> self . _offset = min ( max ( self . _offset , <NUM_LIT:0> ) , self . _max_offset ) <EOL> if self . _bytes_per_sample == <NUM_LIT:2> : <EOL> self . _offset &= <NUM_LIT> <EOL> class Silence ( ProceduralSource ) : <EOL> def _generate_data ( self , bytes , offset ) : <EOL> if self . _bytes_per_sample == <NUM_LIT:1> : <EOL> return '<STR_LIT>' * bytes <EOL> else : <EOL> return '<STR_LIT>' * bytes <EOL> class WhiteNoise ( ProceduralSource ) : <EOL> def _generate_data ( self , bytes , offset ) : <EOL> return os . urandom ( bytes ) <EOL> class Sine ( ProceduralSource ) : <EOL> def __init__ ( self , duration , frequency = <NUM_LIT> , ** kwargs ) : <EOL> super ( Sine , self ) . __init__ ( duration , ** kwargs ) <EOL> self . frequency = frequency <EOL> def _generate_data ( self , bytes , offset ) : <EOL> if self . _bytes_per_sample == <NUM_LIT:1> : <EOL> start = offset <EOL> samples = bytes <EOL> bias = <NUM_LIT> <EOL> amplitude = <NUM_LIT> <EOL> data = ( ctypes . c_ubyte * samples ) ( ) <EOL> else : <EOL> start = offset >> <NUM_LIT:1> <EOL> samples = bytes >> <NUM_LIT:1> <EOL> bias = <NUM_LIT:0> <EOL> amplitude = <NUM_LIT> <EOL> data = ( ctypes . c_short * samples ) ( ) <EOL> step = self . frequency * ( math . pi * <NUM_LIT:2> ) / self . audio_format . sample_rate <EOL> for i in range ( samples ) : <EOL> data [ i ] = int ( math . sin ( step * ( i + start ) ) * amplitude + bias ) <EOL> return data <EOL> class Saw ( ProceduralSource ) : <EOL> def __init__ ( self , duration , frequency = <NUM_LIT> , ** kwargs ) : <EOL> super ( Saw , self ) . __init__ ( duration , ** kwargs ) <EOL> self . frequency = frequency <EOL> def _generate_data ( self , bytes , offset ) : <EOL> if self . _bytes_per_sample == <NUM_LIT:1> : <EOL> samples = bytes <EOL> value = <NUM_LIT> <EOL> max = <NUM_LIT:255> <EOL> min = <NUM_LIT:0> <EOL> data = ( ctypes . c_ubyte * samples ) ( ) <EOL> else : <EOL> samples = bytes >> <NUM_LIT:1> <EOL> value = <NUM_LIT:0> <EOL> max = <NUM_LIT> <EOL> min = - <NUM_LIT> <EOL> data = ( ctypes . c_short * samples ) ( ) <EOL> step = ( max - min ) * <NUM_LIT:2> * self . frequency / self . audio_format . sample_rate <EOL> for i in range ( samples ) : <EOL> value += step <EOL> if value > max : <EOL> value = max - ( value - max ) <EOL> step = - step <EOL> if value < min : <EOL> value = min - ( value - min ) <EOL> step = - step <EOL> data [ i ] = value <EOL> return data <EOL> class Square ( ProceduralSource ) : <EOL> def __init__ ( self , duration , frequency = <NUM_LIT> , ** kwargs ) : <EOL> super ( Square , self ) . __init__ ( duration , ** kwargs ) <EOL> self . frequency = frequency <EOL> def _generate_data ( self , bytes , offset ) : <EOL> if self . _bytes_per_sample == <NUM_LIT:1> : <EOL> samples = bytes <EOL> value = <NUM_LIT:0> <EOL> amplitude = <NUM_LIT:255> <EOL> data = ( ctypes . c_ubyte * samples ) ( ) <EOL> else : <EOL> samples = bytes >> <NUM_LIT:1> <EOL> value = - <NUM_LIT> <EOL> amplitude = <NUM_LIT> <EOL> data = ( ctypes . c_short * samples ) ( ) <EOL> period = self . audio_format . sample_rate / self . frequency / <NUM_LIT:2> <EOL> count = <NUM_LIT:0> <EOL> for i in range ( samples ) : <EOL> count += <NUM_LIT:1> <EOL> if count == period : <EOL> value = amplitude - value <EOL> count = <NUM_LIT:0> <EOL> data [ i ] = value <EOL> return data </s>
