Fex

Check-in [b6d5daddeb]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:log transform added; cursor colog configurable
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk | origin/sfml
Files: files | file ages | folders
SHA3-256:b6d5daddebfd7088c2f27a984aaa25a109744c7c5391a890a49c3265fbd01e06
User & Date: jesse.mcclure@umassmed.edu 2016-02-17 19:07:47
Context
2016-02-17
20:54
added eraser toggle; change key bindings - Mod+Space "locks" a mode Leaf check-in: 2fdfa46cc7 user: jesse.mcclure@umassmed.edu tags: trunk, origin/sfml
19:07
log transform added; cursor colog configurable check-in: b6d5daddeb user: jesse.mcclure@umassmed.edu tags: trunk, origin/sfml
18:45
remove accidental binary check-in: 1eac79ebc2 user: jesse.mcclure@umassmed.edu tags: trunk, origin/sfml
Changes

Changes to TODO.

1


2
3
4
5
6
7
8
9
10
11
12



x Add eraser function to spectrogram module
	- needs testing
- Add log transformation to frequency?
- Add cursorFG to config.cpp and python code
- Too many "magic numbers" for eraser sizes...
x Implement config file reading
	* offloaded to pyfex
	* fex only uses command line parameters
	* this makes porting across platforms easier
		* at least for me: I have no idea where a Win user would keep config files.


>
>


<
<







1
2
3
4
5


6
7
8
9
10
11
12

- eraser control (toggle on / off)
	- bring back "modes"?
x Add eraser function to spectrogram module
	- needs testing


- Too many "magic numbers" for eraser sizes...
x Implement config file reading
	* offloaded to pyfex
	* fex only uses command line parameters
	* this makes porting across platforms easier
		* at least for me: I have no idea where a Win user would keep config files.

Changes to pyfex/default.ini.

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
[defaults]
window length              = 256
bin size                   = 64
low pass                   = 01.25
high pass                  = 10.00
threshold                  = 18.00
floor                      = 24.00


[colors]
window background          = #606468FF
spectrogram background     = #FFFFFFFF
spectrogram foreground     = #000000FF
threshold                  = #58749848
point border               = #3399FFFF
point fill                 = #3399FF48
lines                      = #E86850FF


[warbler]
#match file extension       = wav
#match mime type            = audio/x-wav
match path                 = warber
threshold                  = 14.00

[sparrow]
match path                 = sparrow
threshold                  = 24.00







>









>










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
[defaults]
window length              = 256
bin size                   = 64
low pass                   = 01.25
high pass                  = 10.00
threshold                  = 18.00
floor                      = 24.00
log transform              = false

[colors]
window background          = #606468FF
spectrogram background     = #FFFFFFFF
spectrogram foreground     = #000000FF
threshold                  = #58749848
point border               = #3399FFFF
point fill                 = #3399FF48
lines                      = #E86850FF
cursor                     = #FF0000AA

[warbler]
#match file extension       = wav
#match mime type            = audio/x-wav
match path                 = warber
threshold                  = 14.00

[sparrow]
match path                 = sparrow
threshold                  = 24.00

Changes to pyfex/fexUI.

12
13
14
15
16
17
18

19
20
21
22
23
24
25

26
27
28
29
30
31
32
	'./fex',
	'--winSize=' +    conf['window length'],
	'--binSize=' +    conf['bin size'],
	'--loPass=' +     conf['low pass'],
	'--hiPass=' +     conf['high pass'],
	'--threshold=' +  conf['threshold'],
	'--floor=' +      conf['floor'],

	'--winBG=' +      col['window background'],
	'--specBG=' +     col['spectrogram background'],
	'--specFG=' +     col['spectrogram foreground'],
	'--threshFG=' +   col['threshold'],
	'--pointBG=' +    col['point fill'],
	'--pointFG=' +    col['point border'],
	'--linesFG=' +    col['lines']

]

def run_fex(files):
	if len(files) == 0:
		print("zero")
		# prompt with dialog returning list of files
		# run_fex(list of files)







>







>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
	'./fex',
	'--winSize=' +    conf['window length'],
	'--binSize=' +    conf['bin size'],
	'--loPass=' +     conf['low pass'],
	'--hiPass=' +     conf['high pass'],
	'--threshold=' +  conf['threshold'],
	'--floor=' +      conf['floor'],
	'--log10=' +      conf['log transform'],
	'--winBG=' +      col['window background'],
	'--specBG=' +     col['spectrogram background'],
	'--specFG=' +     col['spectrogram foreground'],
	'--threshFG=' +   col['threshold'],
	'--pointBG=' +    col['point fill'],
	'--pointFG=' +    col['point border'],
	'--linesFG=' +    col['lines']
	'--cursorFG=' +   col['cursor']
]

def run_fex(files):
	if len(files) == 0:
		print("zero")
		# prompt with dialog returning list of files
		# run_fex(list of files)

Changes to src/config.cpp.

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
	unsigned short int r,g,b,a;
	r = (hex & 0xFF000000) >> 24;
	g = (hex & 0x00FF0000) >> 16;
	b = (hex & 0x0000FF00) >> 8;
	a = (hex & 0x000000FF);
	return sf::Color(r,g,b,a);
}









Config::Config(int argc, char *const *argv) {
	struct option opts[] = {
		{ "winSize",     optional_argument, 0, 0 },
		{ "binSize",     optional_argument, 0, 0 },
		{ "loPass",      optional_argument, 0, 0 },
		{ "hiPass",      optional_argument, 0, 0 },
		{ "threshold",   optional_argument, 0, 0 },
		{ "floor",       optional_argument, 0, 0 },

		{ "winBG",       optional_argument, 0, 0 },
		{ "specBG",      optional_argument, 0, 0 },
		{ "specFG",      optional_argument, 0, 0 },
		{ "threshFG",    optional_argument, 0, 0 },
		{ "pointBG",     optional_argument, 0, 0 },
		{ "pointFG",     optional_argument, 0, 0 },
		{ "linesFG",     optional_argument, 0, 0 },

		{0,              0,                 0, 0 }
	};
	int i, c, index;

	for (i = 1; (c=getopt_long_only(argc, argv, "", opts, &index)) != -1; ++i) {
		if (c != 0 || !optarg) continue;
		else if (index == 0)  conf.winlen     = atoi(optarg);
		else if (index == 1)  conf.hop        = atoi(optarg);
		else if (index == 2)  conf.lopass     = atof(optarg);
		else if (index == 3)  conf.hipass     = atof(optarg);
		else if (index == 4)  conf.threshold  = atof(optarg);
		else if (index == 5)  conf.floor      = atof(optarg);

		else if (index == 6)  conf.winBG      = toColor(optarg);
		else if (index == 7)  conf.specBG     = toColor(optarg);
		else if (index == 8)  conf.specFG     = toColor(optarg);
		else if (index == 9)  conf.threshFG   = toColor(optarg);
		else if (index == 10) conf.pointBG    = toColor(optarg);
		else if (index == 11) conf.pointFG    = toColor(optarg);
		else if (index == 12) conf.linesFG    = toColor(optarg);

	}
	if (i > argc) exit(1);
	fname = strdup(argv[i]);
	char *dup = strdup(argv[i]);
	name = strdup(basename(dup));
	free(dup);
}

Config::~Config() {
	if (name) free(name);
	if (fname) free(fname);
}








>
>
>
>
>
>
>
>









>







>



>








>
|
|
|
|
|
|
|
>













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
	unsigned short int r,g,b,a;
	r = (hex & 0xFF000000) >> 24;
	g = (hex & 0x00FF0000) >> 16;
	b = (hex & 0x0000FF00) >> 8;
	a = (hex & 0x000000FF);
	return sf::Color(r,g,b,a);
}

bool toBool(char *str) {
	switch (str[0]) {
		case 'T': case 't': case '1': case 'Y': case 'y': return true; break;
		case 'F': case 'f': case '0': case 'N': case 'n': return false; break;
		default: return false;
	}
}

Config::Config(int argc, char *const *argv) {
	struct option opts[] = {
		{ "winSize",     optional_argument, 0, 0 },
		{ "binSize",     optional_argument, 0, 0 },
		{ "loPass",      optional_argument, 0, 0 },
		{ "hiPass",      optional_argument, 0, 0 },
		{ "threshold",   optional_argument, 0, 0 },
		{ "floor",       optional_argument, 0, 0 },
		{ "log10",       optional_argument, 0, 0 },
		{ "winBG",       optional_argument, 0, 0 },
		{ "specBG",      optional_argument, 0, 0 },
		{ "specFG",      optional_argument, 0, 0 },
		{ "threshFG",    optional_argument, 0, 0 },
		{ "pointBG",     optional_argument, 0, 0 },
		{ "pointFG",     optional_argument, 0, 0 },
		{ "linesFG",     optional_argument, 0, 0 },
		{ "cursorFG",    optional_argument, 0, 0 },
		{0,              0,                 0, 0 }
	};
	int i, c, index;
	char noarg[] = "";
	for (i = 1; (c=getopt_long_only(argc, argv, "", opts, &index)) != -1; ++i) {
		if (c != 0 || !optarg) continue;
		else if (index == 0)  conf.winlen     = atoi(optarg);
		else if (index == 1)  conf.hop        = atoi(optarg);
		else if (index == 2)  conf.lopass     = atof(optarg);
		else if (index == 3)  conf.hipass     = atof(optarg);
		else if (index == 4)  conf.threshold  = atof(optarg);
		else if (index == 5)  conf.floor      = atof(optarg);
		else if (index == 6)  conf.log10      = toBool(optarg);
		else if (index == 7)  conf.winBG      = toColor(optarg);
		else if (index == 8)  conf.specBG     = toColor(optarg);
		else if (index == 9)  conf.specFG     = toColor(optarg);
		else if (index == 10) conf.threshFG   = toColor(optarg);
		else if (index == 11) conf.pointBG    = toColor(optarg);
		else if (index == 12) conf.pointFG    = toColor(optarg);
		else if (index == 13) conf.linesFG    = toColor(optarg);
		else if (index == 14) conf.cursorFG   = toColor(optarg);
	}
	if (i > argc) exit(1);
	fname = strdup(argv[i]);
	char *dup = strdup(argv[i]);
	name = strdup(basename(dup));
	free(dup);
}

Config::~Config() {
	if (name) free(name);
	if (fname) free(fname);
}

Changes to src/config.hpp.

9
10
11
12
13
14
15

16
17
18
19
20
21
22
		struct {
			int winlen           = 256;
			int hop              = 64;
			double lopass        = 01.25;
			double hipass        = 10.00;
			double threshold     = 18.00;
			double floor         = 24.00;

			sf::Color winBG      = sf::Color(0x60,0x64,0x68);
			sf::Color specBG     = sf::Color(0xFF,0xFF,0xFF);
			sf::Color specFG     = sf::Color(0x00,0x00,0x00);
			sf::Color threshFG   = sf::Color(0x58,0x74,0x98,0x48);
			sf::Color pointFG    = sf::Color(0x33,0x99,0xFF);
			sf::Color pointBG    = sf::Color(0x33,0x99,0xFF,0x48);
			sf::Color linesFG    = sf::Color(0xE8,0x68,0x50);







>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
		struct {
			int winlen           = 256;
			int hop              = 64;
			double lopass        = 01.25;
			double hipass        = 10.00;
			double threshold     = 18.00;
			double floor         = 24.00;
			bool log10           = false;
			sf::Color winBG      = sf::Color(0x60,0x64,0x68);
			sf::Color specBG     = sf::Color(0xFF,0xFF,0xFF);
			sf::Color specFG     = sf::Color(0x00,0x00,0x00);
			sf::Color threshFG   = sf::Color(0x58,0x74,0x98,0x48);
			sf::Color pointFG    = sf::Color(0x33,0x99,0xFF);
			sf::Color pointBG    = sf::Color(0x33,0x99,0xFF,0x48);
			sf::Color linesFG    = sf::Color(0xE8,0x68,0x50);

Changes to src/fft.cpp.

152
153
154
155
156
157
158

159
160
161
162
163
164
165
166
		for (f = f1; f < f2; ++f) {
			if (erase[nfreq * t + f]) continue;
			if (amp[nfreq * t + f] < max) continue;
			max = amp[nfreq * t + (fmax=f)];
		}
		if (max < -1.0 * conf.threshold) continue;
		if (n) { /* increment lengths for fex calculation for all but first point */

			pathLength += hypot(freq[fmax]-pf,time[t]-pt);
			timeLength += time[t]-pt;
		}
		pf = freq[fmax]; pt = time[t];
		lines[n].position = sf::Vector2f(t + 0.5, - fmax - 0.5);
		points[4*n].position = sf::Vector2f(t, - fmax);
		points[4*n+1].position = sf::Vector2f(t + 1, - fmax);
		points[4*n+2].position = sf::Vector2f(t + 1, - fmax - 1);







>
|







152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
		for (f = f1; f < f2; ++f) {
			if (erase[nfreq * t + f]) continue;
			if (amp[nfreq * t + f] < max) continue;
			max = amp[nfreq * t + (fmax=f)];
		}
		if (max < -1.0 * conf.threshold) continue;
		if (n) { /* increment lengths for fex calculation for all but first point */
			if (conf.log10) pathLength += hypot(log10(freq[fmax])-log10(pf),time[t]-pt);
			else pathLength += hypot(freq[fmax]-pf,time[t]-pt);
			timeLength += time[t]-pt;
		}
		pf = freq[fmax]; pt = time[t];
		lines[n].position = sf::Vector2f(t + 0.5, - fmax - 0.5);
		points[4*n].position = sf::Vector2f(t, - fmax);
		points[4*n+1].position = sf::Vector2f(t + 1, - fmax);
		points[4*n+2].position = sf::Vector2f(t + 1, - fmax - 1);