Sine wave?
Bengt Richter
bokr at oz.net
Sun Dec 22 17:32:25 EST 2002
On Sun, 22 Dec 2002 13:42:19 -0500, "EC" <vitamonkey at home.com> wrote:
>Ive been banging my head against the wall for the past few days trying to
>generate a sine wave... My math skills arent the best, I'll admit, and I
>think I'm going crosseyed trying to understand this... I *think* the
>following code should work but it outputs some really weird stuff. I'm
>sorta new so please help if you can! Thank you
>
>Eric
>
>#-------------------------------------------
>import math
>import wave
>import string
>
>pi = math.pi
>sin = math.sin
>cos = math.cos
>
>#init output and related vars
>sr = 44100
>Outfile = wave.open("outfile.wav", "w")
>Outfile.setnchannels(1)
>Outfile.setsampwidth(4)
>Outfile.setframerate(sr)
>Outfile.setcomptype("NONE", "Uncompressed")
>Outtemp = []
>Outstr = ""
>
>def get_phase(curphs, freq):
> phinc = (freq*1.0000/sr*1.0000)*360
> phase = curphs + phinc
> if phase >= 360:
> phase -= 360
> elif phase < 0:
> phase += 360
> return phase
>
>def gen_wav(sec, freq, ampcent):
> numsamp = sec*sr
> amp = (ampcent*1.0000/100)*32767
> i = 0
> temp = []
> t = 0
> curphase = 0
> while i < numsamp:
> curphase = get_phase(curphase, freq)
> t = int(round(amp*sin(2*pi*curphase)))
> temp.append(t)
> i+=1
> return temp
>
>Outtemp = gen_wav(.01, 440, 75)
>
>Outstr = string.join(map(str, Outtemp), ",")
>print Outstr
>Outfile.writeframes(Outstr)
>Outfile.close()
>
Try this ( just run python sinewave.py and it should generate 2 seconds
of 2khz at 75% amplitude that you can listen to with media player.
Also will plot the first 34 samples on console screen, self-scaling
when it exceeds the display region (right away here). See after this.
My media player didn't like 4-byte samples, so that was changed, among
other things ;-)
#--< sinewave. py >-------------------------------------------
import math
import wave
import array
pi = math.pi
twopi = 2.0*pi
sin = math.sin
cos = math.cos
#init output and related vars
samplesPerSecond = 44100
Outfile = wave.open("outfile.wav", "w")
Outfile.setnchannels(1)
Outfile.setsampwidth(2) # 2 bytes for 32767 amplitude
Outfile.setframerate(samplesPerSecond)
Outfile.setcomptype("NONE", "Uncompressed")
def gen_wav(seconds, frequency, amplitudePercentOfMax):
# calculate frequency as cycles/sample
cyclesPerSample = float(frequency)/samplesPerSecond
numberOfSamples = int(seconds*samplesPerSecond)
maxAmplitude = (amplitudePercentOfMax/100.)*32767
sampleArray = array.array('h')
for nSamples in xrange(numberOfSamples):
cycles = nSamples*cyclesPerSample
cycles -= int(cycles) # makes 0.0<=cycles<1.0
sampleValue = int(round(maxAmplitude*sin(twopi*cycles))) # round
sampleArray.append(sampleValue)
return sampleArray
if __name__ == '__main__':
#Outtemp = gen_wav(.01, 440, 75)
# generate .001 sec = 44.1 samples & 2 cycles with 20 amplitude
#sampleArray = gen_wav(.00075, 2000, (20./32767.)*100)
sampleArray = gen_wav(2, 2000, 75)
# print first 34 samples as selfscaling ascii plot
grid = list(' |%19s|%19s|' %('',''))
scale = 1.0; maximumMagnitude = 20
for i in range(min(34,len(sampleArray))):
sample= sampleArray[i]
if abs(sample)>maximumMagnitude:
maximumMagnitude=abs(sample)
scale = 20./maximumMagnitude
x= int(round(sampleArray[i]*scale))+21
print ''.join(grid[:x]+['*']+grid[x+1:])
Outfile.writeframes(sampleArray.tostring())
Outfile.close()
#-------------------------------------------------------------
Output from above:
[14:27] C:\pywk\clp>python sinewave.py
| * |
| | *
| | *
| | *
| | *
| | *
| | *
| | * |
| | * |
| | * |
| | * |
| * |
| * | |
| * | |
| * | |
| * | |
* | |
* | |
| * | |
| * | |
| * | |
| * | |
| * |
| | * |
| | * |
| | * |
| | * |
| | *
| | *
| | * |
| | * |
| | * |
| | * |
| * |
Regards,
Bengt Richter
More information about the Python-list
mailing list