aboutsummaryrefslogtreecommitdiff
path: root/src/opcodes.cpp
blob: 606cd2f41155f229484f22e53d1e1f347df0139f (plain)
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
#include <plugin.h>
#include <festival/festival.h>
#include <sstream>

struct ftts : csnd::Plugin<1, 2> {
	static constexpr char const *otypes = "i";
	static constexpr char const *itypes = "Si";
	EST_Wave wave;
	FUNC *table;

	int genft(int size) {
		EVTBLK *evt;
		MYFLT *pf;

		evt = (EVTBLK*) csound->malloc(sizeof(EVTBLK));
		evt->opcod = "f";
		evt->strarg = NULL;
		evt->pcnt = 5;
		pf = &evt->p[0];
		pf[0] = FL(0);
		pf[1] = FL(0);
		pf[2] = evt->p2orig = FL(0);
		pf[3] = evt->p3orig = -size;
		pf[4] = FL(2); // gen numbe
		pf[5] = FL(0);
		int n = csound->get_csound()->hfgens(csound->get_csound(), &table, evt, 1);
		if (UNLIKELY(n != 0)) {
			return NOTOK;
		}
		csound->free(evt);
		return OK;
	}

	int init() {
		// create mutex for realtime run; check csound.c like line 3685
		STRINGDAT &word = inargs.str_data(0);
		int heap_size = 210000;
		int load_init_files = 1;
		festival_initialize(load_init_files, heap_size);
		std::ostringstream pitch;
		pitch << "(set! duffint_params '((start "
			<< ((int) inargs[1]) << ") end ("
			<< ((int) inargs[1]) << ")))";
		festival_eval_command(pitch.str().c_str());

		festival_eval_command("(Parameter.set 'Int_Method 'DuffInt)");
		festival_eval_command("(Parameter.set 'Int_Target_Method Int_Targets_Default)");
		festival_eval_command("(Parameter.set 'Audio_Required_Rate 44100)");
		festival_text_to_wave(word.data, wave);
		festival_wait_for_spooler();
	
		int adjusted_size = (csound->sr() / wave.sample_rate()) * wave.length();
		if ((genft(adjusted_size)) != OK) {
			return csound->init_error("Cannot create ftable");
		}

		table->soundend = adjusted_size;
		table->nchanls = 1;
		table->flenfrms = adjusted_size;
		table->gen01args.sample_rate = csound->sr();
		table->cpscvt = 0;
		table->cvtbas = LOFACT; // * csound->sr() * csound->get_csound()->onedsr;
		table->loopmode1 = 0;
		table->loopmode2 = 0;
		table->begin1 = 0;
		table->end1 = adjusted_size;
		table->begin2 = 0;
		table->end2 = adjusted_size;
		
		read_in();
		outargs[0] = table->fno;
		return OK;
	}

	int read_in() {
		MYFLT lastsample = 0;
		int read_pos = 0;
		int kcount = 0;
		int write_pos = 0;
		int srdiv = csound->sr() / wave.sample_rate();
		
		while (read_pos < wave.length() && write_pos < table->soundend) {
			if (kcount == 0) {
				lastsample = (MYFLT) wave.a(read_pos++, 0)*0.00001;
			}

			table->ftable[write_pos] = lastsample;

			write_pos++;

			if (++kcount > srdiv) {
				kcount = 0;
			}
		}
		return OK;
	}
};

#include <modload.h>
void csnd::on_load(csnd::Csound *csound) {
	csnd::plugin<ftts>(csound, "ftts", csnd::thread::i);
}