File: singleImpulseToDatabase.py

package info (click to toggle)
clam 1.4.0-6
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 17,836 kB
  • ctags: 20,981
  • sloc: cpp: 92,504; python: 9,721; ansic: 1,602; xml: 444; sh: 239; makefile: 153; perl: 54; asm: 15
file content (138 lines) | stat: -rwxr-xr-x 4,199 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/python

# TODO: When the distance goes beyound the wave file length the IR tail migth click or even disapear on silence. Solution compute the maximum delay and add it to all the waves.

# sudo apt-get install python-numpy
# sudo apt-get install sox

import os
import sys
import numpy
import math
import cmath
import normalizeAndWav

def readDatFile(filename) :
	wavefile = file(filename, "r")
	return [ float(sample) for time, sample in [ line.split() for line in wavefile.readlines() if line[0]!=";"]]

def writeDatFile(filename, samples) :
	result = []
	result += ["; Sample Rate 44100\n"]
	result += ["; Channels 1\n"]
	result += [ "%.11g %.11g\n"%(timeInSamples/44100., sample) for timeInSamples, sample in  zip( range(0, len(samples)), samples) ]
	wavefile = file(filename, "w")
	wavefile.writelines(result)

def shiftSamples(audio, deltaSamples) :
	if deltaSamples == 0 : return
	if deltaSamples > 0 :
		audio[deltaSamples:] = audio[:-deltaSamples]
		audio[0:deltaSamples] = 0
	else:
		deltaSamples = abs(deltaSamples) # make it positive
		audio[0:-deltaSamples] = audio[deltaSamples:]
		audio[-deltaSamples:] = 0

# Configurable parameters. (TODO make them arguments with sane defaults)

setting = 2
if setting == 1:
	NX = 10
	NY = 10
	sizeX = 2. #meters
	sizeY = 2. #meters
	recordingDistance = .524263 #meters
	xs = NX/2.
	ys = NY/2.
elif setting == 2:
	NX = 10
	NY = 10
	sizeX = 12. #meters
	sizeY = 12. #meters
	recordingDistance = 7 #meters
	xs = NX/2.
	ys = NY/2.
elif setting == 3: #offline 1 - guitar
	NX = 20
	NY = 20
	sizeX = 12. #meters
	sizeY = 12. #meters
	recordingDistance = 6 #meters
	xs = NX/2.
	ys = NY/8.
elif setting == 4: #offline 2 - cajon
	NX = 20
	NY = 20
	sizeX = 12. #meters
	sizeY = 12. #meters
	recordingDistance = 6 #meters
	xs = NX/2.
	ys = 7*NY/8.
elif setting == 5: #offline 2 - bailaora
	NX = 20
	NY = 20
	sizeX = 12. #meters
	sizeY = 12. #meters
	recordingDistance = 6 #meters
	xs = 3*NX/4.
	ys = 0
else:
	assert False, "bad setting"

databasePrefix = "carneltest"
wavSourcePrefix = "wavs/CarnelTest"
print "Usage: ", sys.argv[0], "wav-source-prefix database-prefix"
print "Example: ", sys.argv[0], "wavs/CarnelShort carnelshort"
if len(sys.argv)==3:
	wavSourcePrefix = sys.argv[1]
	databasePrefix = sys.argv[2]
databaseDir = databasePrefix+"Database"
print "wavSourcePrefix:", wavSourcePrefix
print "databaseDir:", databaseDir

recordingAzimut = 0 #radians
recordedFilesPattern = databasePrefix+"%s.dat"
filepattern =  databaseDir+"/%s_emissor_%i-%i-%i_receptor_%i-%i-%i.dat"

print "creating database dir: ", databaseDir
os.system("mkdir -p %s" % databaseDir)
for suffix in ("P","X","Y"):
	os.system("sox %s%s.wav %s%s.dat"%(wavSourcePrefix,suffix,databasePrefix,suffix) )


print "Loading recorded impulse responses..."
recordedComponents = dict( [ 
	( suffix, numpy.array(readDatFile(recordedFilesPattern % suffix)) ) 
		for suffix in ("P", "X", "Y") ] )
scale = complex(sizeX/NX, sizeY/NY)
minDistance = min(scale.real, scale.imag)
for xt in range(NX) : 
	for yt in range(NY) :
		gridWayToSource = (complex(xs, ys) - complex(xt, yt))
		wayToSource = complex(gridWayToSource.real*scale.real, gridWayToSource.imag*scale.imag)
		distanceToSource = abs(wayToSource) or minDistance
		azimuthToSource = math.atan2(wayToSource.real, wayToSource.imag)
		distanceFactor = recordingDistance/distanceToSource
		azimuthRotation = azimuthToSource - recordingAzimut
		deltaSamples = int((distanceToSource - recordingDistance)*44100/340)
		print distanceToSource, wayToSource, deltaSamples
		assert(deltaSamples >= -2000)

		P,X,Y = [distanceFactor * component for component in 
			[recordedComponents[c] for c in ["P","X","Y"] ] ]
		for component in P,X,Y:
			shiftSamples(component, deltaSamples)
		X, Y = \
			(X * math.cos(azimuthRotation) + Y * math.sin(azimuthRotation), 
			-X * math.sin(azimuthRotation) + Y * math.cos(azimuthRotation))

		print "Writing data...", xt, yt
		#continue
		writeDatFile(filepattern % ("p", 0,0,0, xt,yt,0) , P)
		writeDatFile(filepattern % ("vx", 0,0,0, xt,yt,0) , X)
		writeDatFile(filepattern % ("vy", 0,0,0, xt,yt,0) , Y)
	print
print "\n== Normalize and convert to wav ==\n"
normalizeAndWav.processDir(databaseDir)