import sys

PITCH = 440 # our beloved a
epsilon = 0.0000000000001
NOTE_NAMES = ['c', 'c#', 'd', 'd#', 'e', 'f', 'f#', 'g', 'g#', 'a', 'a#', 'h']

def root(n, a):
  x = float(1) # 1.0 alternatively to specify float
  while True:
    y = x - (x**n - a) / (x**(n-1) * n) 
    if abs(x - y) < epsilon:
      break
    x = y
  return x

step = root(12,2)

base_c = step*step*step*PITCH

def generate_octave(note):
  octave = {}
  for name in NOTE_NAMES:
    octave[name] = note
    note *= step
  return octave

def my_range(start, end, step):
  res = []
  i = start
  while i < end:
    res.append(i)
    i += step
  return res

def smart_range(start, end, step):
  i = start
  while i < end:
    yield i
    i += step

def inf(start,step):
  i = start
  while True:
    yield i
    i += step

octave = generate_octave(base_c)

freqs = map(lambda x: octave[x], open(sys.argv[1]).read().split())

import math

def generate_freq(freq):
  res = []
  for i in range(44100):
    if i < 10000:
      value = 2*i*math.sin(i*freq/44100*2*math.pi)
    elif i < 34100:
      value = 20000*math.sin(i*freq/44100*2*math.pi)
    else:
      value = (44100-i)*2*math.sin(i*freq/44100*2*math.pi)
    res.append(value)
  return res

def generate_sine(freqs):
  res = []
  for freq in freqs:
    res.extend(generate_freq(freq))
  return res

data = generate_sine(freqs)

import struct, wave

data = map(lambda x:struct.pack("<h",x), data)
data = ''.join(data)

f = wave.open(sys.argv[2], "wb")

f.setparams((1,2,88200,0,"NONE", "not compressed"))
f.writeframes(data)
f.close()
