#!/usr/bin/env python2.2
# libsndfile-python (a python wrapper for libsndfile)
# Copyright (C) 2003  RM (rm.pylibsnd ! arcsin ! org)
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
import os
import os.path
import sys
import math
import struct
import numarray

# change the import path so that this will run correctly in
# the distribution directory root, without installing
if (os.path.exists('./build') and os.path.isdir('./build')):
	# make sure it's on the front ...
	dir_content = os.listdir('./build')
	path = ""
	for file in dir_content:
		if (os.path.exists(os.path.join('./build',
						file,
						'sndfile'))):
			path = os.path.join('./build',
					    file)
			break
		# end if
	# end for
	sys.path.reverse()
	sys.path.append(path)
	sys.path.reverse()
# end if


import sndfile


def make_test_sine_wave():
	rate = 44100
	freq = 440
	info = sndfile.SF_INFO(samplerate=rate, 
			       channels = 1, 
		   	       format = (sndfile.SF_FORMAT_WAV|
					sndfile.SF_FORMAT_PCM_16), 
			       sections = 1, 
			       seekable = 1)
	s = sndfile.open("test.wav", mode="w", info=info)
	print s.strerror()

	print s.get_info()
	tbuf = range(0, 200)
	for i in range(0, 400):
		fbuf =[math.sin(2*math.pi*freq*(x+i*200)/float(rate)) 
				for x in tbuf]
		if (sndfile.get_numarray_mode() == 0):
			buffer = struct.pack("200f", *fbuf)
		else: 
			print "writing using numarray"
			buffer = numarray.array(fbuf, numarray.Float32)
		# end if
		s.write_float (buffer)
	# end for
	s.close()

# end def

def make_test_stereo_sine_wave():
	rate = 44100
	freq = 440
	info = sndfile.SF_INFO(samplerate=rate, 
			       channels = 2, 
		   	       format = (sndfile.SF_FORMAT_WAV|
					sndfile.SF_FORMAT_PCM_16), 
			       sections = 1, 
			       seekable = 1)
	s = sndfile.open("test-stereo.wav", mode="w", info=info)
	print s.strerror()

	print s.get_info()
	tbuf = []
	for i in range (0, 200):
		tbuf.append(i)
		tbuf.append(i)
	# end for
	#i = 0
	#fbuf =[  math.sin(2*math.pi*freq*(x+i*200)/float(rate))
	#	 for x in tbuf]
	#print fbuf[0:100]
	for i in range(0, 400):

		fbuf =[  math.sin(2*math.pi*freq*(x+i*200)/float(rate))
			 for x in tbuf]
		if (sndfile.get_numarray_mode() == 0):
			buffer = struct.pack("400f", *fbuf)
		else: 
			buffer = numarray.array(fbuf, numarray.Float32)
		# end if
		s.write_float (buffer)
	# end for
	s.close()

# end def


def runtest(name, read_function, write_function):
	f1 = "test.wav"
	f2 = "output-%s.wav"%name
	s_in = sndfile.open(f1, "r")
	s_out = sndfile.open(f2, "w", s_in.get_info())
	print s_in.get_info()
	print s_out.get_info()
	while 1:
		v = s_in.__dict__[read_function](100)
		if (len(v) == 0):
			break
		# end if
		s_out.__dict__[write_function](v)
	# end while
	s_in.close()
	s_out.close()

# end def runtest



try:
	sndfile.set_numarray_mode(1)
except: 
	print "Unable to use numarray extension"
# end try

make_test_sine_wave()
runtest("short", "read_short", "write_short")
runtest("shortf", "readf_short", "writef_short")
runtest("int", "read_int", "write_int")
runtest("intf", "readf_int", "writef_int")
runtest("float", "read_float", "write_float")
runtest("floatf", "readf_float", "writef_float")
runtest("double", "read_double", "write_double")
runtest("doublef", "readf_double", "writef_double")

sndfile.set_numarray_mode(0)
make_test_sine_wave()
runtest("short", "read_short", "write_short")
runtest("shortf", "readf_short", "writef_short")
runtest("int", "read_int", "write_int")
runtest("intf", "readf_int", "writef_int")
runtest("float", "read_float", "write_float")
runtest("floatf", "readf_float", "writef_float")
runtest("double", "read_double", "write_double")
runtest("doublef", "readf_double", "writef_double")

print sndfile.command(cmd=sndfile.SFC_GET_LIB_VERSION)
sndfile.command(cmd=sndfile.SFC_GET_LOG_INFO, len = 2048)

foo = sndfile.open("casdfafd.wav", "w")
foo.read_raw(10)
print foo.command(cmd=sndfile.SFC_GET_LOG_INFO, len = 2048),
foo.close()

make_test_stereo_sine_wave()
foo = sndfile.open("test-stereo.wav", "r")
print ("SFC_CALC_SIGNAL_MAX of test.wav was %f"%
      foo.command(cmd=sndfile.SFC_CALC_SIGNAL_MAX))
print ("SFC_CALC_NORM_SIGNAL_MAX  of test.wav was %f"%
      foo.command(cmd=sndfile.SFC_CALC_NORM_SIGNAL_MAX))
print ("SFC_CALC_NORM_MAX_ALL_CHANNELS  of test-stereo.wav was",
      foo.command(cmd=sndfile.SFC_CALC_NORM_MAX_ALL_CHANNELS))

print ("SFC_SET_NORM_FLOAT  returns",
      foo.command(cmd=sndfile.SFC_SET_NORM_FLOAT, len = 1))
print ("SFC_SET_NORM_DOUBLE  returns",
      foo.command(cmd=sndfile.SFC_SET_NORM_DOUBLE, len = 0))


print ("SFC_SET_RAW_START_OFFSET returns",
      foo.command(cmd=sndfile.SFC_SET_RAW_START_OFFSET, len = 0))


print ("SFC_GET_NORM_FLOAT  returns",
      foo.command(cmd=sndfile.SFC_GET_NORM_FLOAT))
print ("SFC_GET_NORM_DOUBLE  returns",
      foo.command(cmd=sndfile.SFC_GET_NORM_DOUBLE))
print ("SFC_GET_SIMPLE_FORMAT_COUNT  returns",
      foo.command(cmd=sndfile.SFC_GET_SIMPLE_FORMAT_COUNT))
foo.close()

print ("SFC_GET_SIMPLE_FORMAT_COUNT  returns",
      sndfile.command(cmd=sndfile.SFC_GET_SIMPLE_FORMAT_COUNT))
print ("SFC_GET_FOMAT_MAJOR_COUNT  returns",
      sndfile.command(cmd=sndfile.SFC_GET_FORMAT_MAJOR_COUNT))
print ("SFC_GET_FOMAT_SUBTYPE_COUNT  returns",
      sndfile.command(cmd=sndfile.SFC_GET_FORMAT_SUBTYPE_COUNT))


foo = sndfile.open("test-stereo.wav", "rw")
print ("SFC_FILE_TRUNCATE  returns",
       foo.command(cmd=sndfile.SFC_FILE_TRUNCATE, len = 42))
print foo.strerror()
# why does this fail -- because it has to be opened raw?
print ("SFC_SET_RAW_START_OFFSET returns",
      foo.command(cmd=sndfile.SFC_SET_RAW_START_OFFSET, len = 0))
print foo.strerror()
foo.close()


make_test_stereo_sine_wave()
foo = sndfile.open("test-stereo.wav", "r",
		   info=sndfile.SF_INFO(frames=100,
					channels=1,
					samplerate=44100,
					format=sndfile.SF_FORMAT_RAW|
					sndfile.SF_FORMAT_PCM_S8,
					sections=1, seekable=1))
print foo.command(cmd=sndfile.SFC_GET_LOG_INFO, len = 2048),
print ("SFC_SET_RAW_START_OFFSET returns",
      foo.command(cmd=sndfile.SFC_SET_RAW_START_OFFSET, len = 0))
print foo.strerror()
foo.close()


n = sndfile.command(cmd=sndfile.SFC_GET_SIMPLE_FORMAT_COUNT)
format_info = sndfile.SF_FORMAT_INFO(0)
info = sndfile.SF_INFO()
for i in range(0, n):
	format_info.format = i
	format_info = sndfile.command(cmd=sndfile.SFC_GET_SIMPLE_FORMAT, 
				      data = format_info)
	print format_info
# end for		
print "========================================================"

#### the example in the command.html docs is wrong!?

m = sndfile.command(cmd=sndfile.SFC_GET_FORMAT_SUBTYPE_COUNT)
subtype_info = sndfile.SF_FORMAT_INFO(0)
for j in range(0, m):
	subtype_info.format = j
	ret = sndfile.command(cmd=\
				     sndfile.SFC_GET_FORMAT_SUBTYPE,
				     data = subtype_info)
	info.format = sndfile.SF_FORMAT_WAV | subtype_info.format
	print "\t", subtype_info
	# format check seems broken!
	if (sndfile.format_check(info)):
		print "\t", subtype_info
	# end if
# end for

print "========================================================"

	
n = sndfile.command(cmd=sndfile.SFC_GET_FORMAT_MAJOR_COUNT)
format_info = sndfile.SF_FORMAT_INFO(0)
for i in range(0, n):
	format_info.format = i
	format_info = sndfile.command(cmd=sndfile.SFC_GET_FORMAT_MAJOR, 
				      data = format_info)
	print format_info
# end for	


sys.exit(0)
