#!/bin/env python
import sys
import time,wave
import pymedia.audio.sound as sound
import datetime
import random

EMULATE=0

import ctypes
import struct

waveOutGetVolume = (
  ctypes.windll.winmm.waveOutGetVolume)

waveOutSetVolume = (
  ctypes.windll.winmm.waveOutSetVolume)

# Some constants
MINIMUM_VOLUME = 0     # fader control (MSDN Library)
MAXIMUM_VOLUME = 65535 # fader control (MSDN Library)

def setVolume(volume):
    """Set the speaker volume on the 'Volume Control' mixer"""
    if not (MINIMUM_VOLUME <= volume <= MAXIMUM_VOLUME):
        raise ValueError, "Volume out of range"
    ret = waveOutSetVolume(0, volume)
    if ret != 0:
        print WindowsError, "Error %d while setting volume" % ret
    print 'Volume set to ' + str(volume)
    return

def aplayer(name):
  card = 0
  rate = 1
  tt = -1
  import pymedia.muxer as muxer, pymedia.audio.acodec as acodec, pymedia.audio.sound as sound
  dm= muxer.Demuxer( str.split( name, '.' )[ -1 ].lower() )
  snds= sound.getODevices()
  if card not in range( len( snds ) ):
    raise 'Cannot play sound to non existent device %d out of %d' % ( card+ 1, len( snds ) )
  f= open( name, 'rb' )
  snd= resampler= dec= None
  s= f.read( 32000 )
  t= 0
  volume = 0
  while len( s ):
    frames= dm.parse( s )
    if frames:
      for fr in frames:
        # Assume for now only audio streams
        if dec== None:
          print dm.getInfo(), dm.streams
          dec= acodec.Decoder( dm.streams[ fr[ 0 ] ] )
        r= dec.decode( fr[ 1 ] )
        if r and r.data:
          if snd== None:
            print 'Opening sound with %d channels -> %s' % ( r.channels, snds[ card ][ 'name' ] )
            snd= sound.Output( int( r.sample_rate* rate ), r.channels, sound.AFMT_S16_LE, card )
            if rate< 1 or rate> 1:
              resampler= sound.Resampler( (r.sample_rate,r.channels), (int(r.sample_rate/rate),r.channels) )
              print 'Sound resampling %d->%d' % ( r.sample_rate, r.sample_rate/rate )
          
          data= r.data
          if resampler:
            data= resampler.resample( data )
          if EMULATE:
            # Calc delay we should wait to emulate snd.play()

            d= len( data )/ float( r.sample_rate* r.channels* 2 )
            time.sleep( d )
            if int( t+d )!= int( t ):
              print 'playing: %d sec\r' % ( t+d ),
            t+= d
          else:
            volume += 100
            if volume < MAXIMUM_VOLUME:
              setVolume(volume)
            snd.play( data )
    if tt> 0:
      if snd and snd.getPosition()> tt:
        break
    s= f.read( 512 )
  while snd.isPlaying():
    volume += 100
    if volume < MAXIMUM_VOLUME:
      setVolume(volume)
    time.sleep(5)

winmm= ctypes.windll.winmm
vol=ctypes.c_uint()
print 'res', winmm.waveOutGetVolume(0, ctypes.byref(vol))
print 'volume = ' + str(vol)

if len(sys.argv) < 2:
  print 'Usage: alarm "07:24"'

config = 'p:/bin/alarmconfig.txt'
if len(sys.argv) > 2:
  config = sys.argv[2]

print 'config file = ' + config

f = open(config)
fileslist = f.readlines()
files_to_play = []
for line in fileslist:
  if not line == '\n':
    files_to_play.append(line[0:-1])
f.close()
random.seed()
file_to_play = files_to_play[random.randint(0, len(files_to_play) - 1)]
print 'selecting ' + file_to_play

timestring = sys.argv[1]
timep = time.strptime(timestring, '%H:%M')
year, month, day, hour, min, sec, wday, yday, isdst = timep
now_dt = datetime.datetime.now()
alarm_dt = datetime.datetime(now_dt.year, now_dt.month, now_dt.day,
                             hour, min, 0, 0, now_dt.tzinfo)
td = alarm_dt - now_dt
print 'sleeping for %d seconds\n' % td.seconds
time.sleep(td.seconds)
aplayer(file_to_play)


