From c3853f6dd796615f332fefcaaaf563794d867ee4 Mon Sep 17 00:00:00 2001 From: Richard Knight Date: Tue, 17 Mar 2020 18:47:36 +0000 Subject: initial --- examples/1-sqlite-basic.csd | 41 +++++++ examples/2-sqlite-krate.csd | 95 ++++++++++++++++ examples/3-postgresql-basic.csd | 100 +++++++++++++++++ examples/4-postgresql-analysis.csd | 104 +++++++++++++++++ examples/5-mysql-basic.csd | 110 ++++++++++++++++++ examples/6-mysql-randomnotes.csd | 99 +++++++++++++++++ examples/7-violsqlite.csd | 172 +++++++++++++++++++++++++++++ examples/sounds/violin.wav | Bin 0 -> 586448 bytes examples/toCheck/7-sqlite-pitchmatcher.csd | 140 +++++++++++++++++++++++ 9 files changed, 861 insertions(+) create mode 100644 examples/1-sqlite-basic.csd create mode 100644 examples/2-sqlite-krate.csd create mode 100644 examples/3-postgresql-basic.csd create mode 100644 examples/4-postgresql-analysis.csd create mode 100644 examples/5-mysql-basic.csd create mode 100644 examples/6-mysql-randomnotes.csd create mode 100644 examples/7-violsqlite.csd create mode 100644 examples/sounds/violin.wav create mode 100644 examples/toCheck/7-sqlite-pitchmatcher.csd (limited to 'examples') diff --git a/examples/1-sqlite-basic.csd b/examples/1-sqlite-basic.csd new file mode 100644 index 0000000..8177d4a --- /dev/null +++ b/examples/1-sqlite-basic.csd @@ -0,0 +1,41 @@ + + +-odac + + +/* + EXAMPLE 1 + + print some data from a sqlite3 database at i-rate + + +*/ + +sr = 44100 +kr = 4410 +nchnls = 2 +0dbfs = 1 +seed 0 + +; sqlite3 takes a file path, or :memory: for a temporary in-memory database +; gidb dbconnect "sqlite", "/tmp/example.db" +gidb dbconnect "sqlite", ":memory:" + +instr start_example + + ; print a random value + ires1 dbscalar gidb, "SELECT RANDOM()" + print ires1 + + ; print the second column (1) of the first row (0) + ires2 dbscalar gidb, "SELECT 99, 98", 0, 1 + print ires2 +endin + + + + +i "start_example" 0 1 + + + \ No newline at end of file diff --git a/examples/2-sqlite-krate.csd b/examples/2-sqlite-krate.csd new file mode 100644 index 0000000..d6a370f --- /dev/null +++ b/examples/2-sqlite-krate.csd @@ -0,0 +1,95 @@ + + +-odac + + +/* + EXAMPLE 2 + + Use a metro to trigger the insertion of points from a line into a sqlite database, + then read back the points in reverse order and play back with enveloping + + +*/ + +sr = 44100 +kr = 4410 +nchnls = 2 +0dbfs = 1 +seed 0 + + +; sqlite3 takes a file path, or :memory: for a temporary in-memory database +;gidb dbconnect "sqlite", ":memory:" +gidb dbconnect "sqlite", "/tmp/example.db" + + +instr start_example + + ; create the table with just one float column + kdone1 dbexec_k gidb, "CREATE TABLE IF NOT EXISTS frequencies (freq float)", -1 + + ; execute when create table statement has completed - clear out if the table does exist + kdone2 dbexec_k gidb, "DELETE FROM frequencies", kdone1 + + ; execute when delete has completed + schedkwhen kdone2, 0, 0, "db_insert", 0, 5 + schedkwhen kdone2, 0, 0, "db_select", 5, 10 + + +endin + + +; insert frequency values from line into database at k rate +instr db_insert + + ; generate some data and print + kfreq line 440, p3, 1000 + ktrigger metro 5 + printk 0.2, kfreq + + ; insert snapshot with each metro (as long as the last query is still not pending) + Squery sprintfk "INSERT INTO frequencies (freq) VALUES (%f)", kfreq + kdone dbexec_k gidb, Squery, ktrigger + +endin + + +; read frequency values from database at i rate: obtain the values in reverse order +instr db_select + + ; get all values in descending order into an array + ires[][] dbarray gidb, "SELECT freq FROM frequencies ORDER BY freq desc" + itimestep = 0.3 + index = 0 + itime = 0 + ilast = 0 + + ; loop through the values and play the frequency with some basic interpolation between last current values + while (index < lenarray(ires)) do + if (ilast != 0) then + event_i "i", "playpitch", itime, itimestep, ilast, ires[index][0] + endif + ilast = ires[index][0] + index += 1 + itime += itimestep * 0.8 + od +endin + + +; basic oscillator instrument with envelope +instr playpitch + ipitch1 = p4 + ipitch2 = p5 + kamp linseg 0, p3*0.2, 1, p3*0.6, 1, p3*0.2, 0 + kpitch line ipitch1, p3, ipitch2 + aout oscil 0.8, kpitch + outs aout*kamp, aout*kamp +endin + + + +i "start_example" 0 15 + + + \ No newline at end of file diff --git a/examples/3-postgresql-basic.csd b/examples/3-postgresql-basic.csd new file mode 100644 index 0000000..053ee07 --- /dev/null +++ b/examples/3-postgresql-basic.csd @@ -0,0 +1,100 @@ + + +-odac + + +/* + EXAMPLE 3 + + Run some queries on a PostgreSQL database using just inbuilt functions and system tables + + +*/ + +sr = 44100 +kr = 4410 +nchnls = 2 +0dbfs = 1 +seed 0 + + +; connect: type, hostname or IP, database name, username, password +gidb dbconnect "postgresql", "localhost", "databasename", "username", "password" + + +; print a random float from the database +instr execscalar + ires dbscalar gidb, "SELECT RANDOM()" + print ires +endin + + +; print the current_timestamp from the database +instr execscalarstr + Sres dbscalar gidb, "SELECT current_timestamp || '\n'" + prints Sres +endin + + +; print some float columns from the database activity statistics table +instr execarray + ires[][] dbarray gidb, "SELECT datid, pid, usesysid FROM pg_stat_activity" + printarray ires +endin + + +; print some string columns from the database activity table +instr execarraystr + Sres[][] dbarray gidb, "SELECT datname, usename, state, query_start FROM pg_stat_activity" + irow = 0 + + ; loop through as printarray does not support multidimensional string arrays + while (irow < lenarray(Sres)) do + icol = 0 + while (icol < 3) do + Sitem sprintf "%d, %d : %s\n", irow, icol, Sres[irow][icol] + prints Sitem + icol += 1 + od + irow += 1 + od + +endin + + +; print the current_timestamp from the database server twice per second, and print when the query has been executed +instr execscalar_k + ktrigger metro 2 + kdone, Sres dbscalar_k gidb, "SELECT 'now = ' || current_timestamp || '\n'", ktrigger + if (kdone == 1) then + printks "%s", 0, Sres + endif +endin + + +; print 2x2 random floats from the database every second +instr execarray_k + ktrigger metro 1 + kdone, kres[][] dbarray_k gidb, "SELECT RANDOM(), RANDOM() UNION SELECT RANDOM(), RANDOM()", ktrigger + if (kdone == 1) then + printk2 kres[0][0] + printk2 kres[0][1] + printk2 kres[1][0] + printk2 kres[1][1] + endif + +endin + + + + + +i "execscalar" 0 1 +i "execscalarstr" 2 1 +i "execarray" 4 1 +i "execarraystr" 6 1 +i "execscalar_k" 7 5 +i "execarray_k" 12 5 + + + \ No newline at end of file diff --git a/examples/4-postgresql-analysis.csd b/examples/4-postgresql-analysis.csd new file mode 100644 index 0000000..38a82a6 --- /dev/null +++ b/examples/4-postgresql-analysis.csd @@ -0,0 +1,104 @@ + + +-odac + + +/* + EXAMPLE 4 + + Pitch track an oscillator, inserting the time, frequency and amplitude values in a PostgreSQL database + as fast as it will accept, at k-rate. + Read back the values at i-rate in the db_play instrument and create events to mimic the original oscillator. + + +*/ + +sr = 44100 +kr = 4410 +nchnls = 2 +0dbfs = 1 +seed 0 + + +; connect: type, hostname or IP, database name, username, password +gidb dbconnect "postgresql", "localhost", "databasename", "username", "password" + + +; create table if it doesn't exist. truncate if it does +instr start_example + kdone1 dbexec_k gidb, "CREATE TABLE IF NOT EXISTS analysis (time FLOAT, rms FLOAT, freq FLOAT)", -1 + kdone2 dbexec_k gidb, "TRUNCATE TABLE analysis", kdone1 + + ; schedule next steps + if (kdone2 == 1) then + schedule "db_analyse", 0, 3 + schedule "db_play", 3.5, 3.5 + turnoff + endif +endin + + +instr db_analyse + + ; the oscillator + a1 oscil abs(oscil(1, 0.6)), linseg(440, p3*0.2, 800, p3*0.2, 220, p3*0.2, 220, p3*0.2, 350, p3*0.2, 440) + + ; pitch/rms and time tracking + kcps, krms pitchamdf a1, 220, 800, 0, 0 + ktime timeinsts + + ; listen back to the pitch track output + a1 oscil krms, kcps + + ; insert the time, rms and frequency values as fast as the database will accept + kdone init 1 + kdone dbexec_k gidb, sprintfk("INSERT INTO analysis (time, rms, freq) VALUES (%f, %f, %f)", ktime, krms, kcps), 1 + + ; declick end + aout = a1 * linseg(1, p3*0.99, 1, p3*0.01, 0) + outs aout, aout +endin + + +instr db_play + + ; get all of the values + idata[][] dbarray gidb, "SELECT time, rms, freq FROM analysis" + + ; loop through + index = 0 + while (index < lenarray(idata)) do + + ; set the duration to be the time to the next row multiplied by an overlap + if (index == lenarray(idata) - 1) then + iduration = 1 + else + iduration = (idata[index+1][0] - idata[index][0]) * 3.2 + endif + + ; create the event accordingly + event_i "i", "oscillator", idata[index][0]*2, iduration, idata[index][1], idata[index][2] + index += 1 + od +endin + + +instr oscillator + + ; basic oscillator + iamp = p4 + ifreq = p5 + a1 oscil iamp * 0.5, ifreq + + ; envelope to try and take away the quantised type sound + aout = a1 * linseg(0, p3*0.45, 1, p3*0.1, 1, p3*0.45, 0) + outs aout, aout +endin + + + +i "start_example" 0 7 + + + + \ No newline at end of file diff --git a/examples/5-mysql-basic.csd b/examples/5-mysql-basic.csd new file mode 100644 index 0000000..bf8e857 --- /dev/null +++ b/examples/5-mysql-basic.csd @@ -0,0 +1,110 @@ + + +-odac + + +/* + EXAMPLE 3 + + Run some queries on a MySQL database using just inbuilt functions and system tables + + +*/ + +sr = 44100 +kr = 4410 +nchnls = 2 +0dbfs = 1 +seed 0 + + +; connect: type, hostname or IP, database name, username, password +gidb dbconnect "mysql", "hostname", "databasename", "user", "password" + + +; print a random float from the database +instr execscalar + ires dbscalar gidb, "SELECT RAND()" + print ires +endin + + +; print the current_timestamp from the database +instr execscalarstr + Sres dbscalar gidb, "SELECT CONCAT(NOW(), '\n')" + prints Sres +endin + + +; print some float columns from the database activity statistics table +instr execarray + Sql = {{ + SELECT INDEX_LENGTH, AVG_ROW_LENGTH, TABLE_ROWS + FROM INFORMATION_SCHEMA.TABLES + LIMIT 10 + }} + ires[][] dbarray gidb, Sql + printarray ires +endin + + +; print some string columns from the database activity table +instr execarraystr + Sql = {{ + SELECT TABLE_NAME, TABLE_COMMENT, ROW_FORMAT + FROM INFORMATION_SCHEMA.TABLES + LIMIT 10 + }} + Sres[][] dbarray gidb, Sql + irow = 0 + + ; loop through as printarray does not support multidimensional string arrays + while (irow < lenarray(Sres)) do + icol = 0 + while (icol < 3) do + Sitem sprintf "%d, %d : %s\n", irow, icol, Sres[irow][icol] + prints Sitem + icol += 1 + od + irow += 1 + od + +endin + + +; print the current_timestamp from the database server twice per second, and print when the query has been executed +instr execscalar_k + ktrigger metro 2 + kdone, Sres dbscalar_k gidb, "SELECT CONCAT('now = ', NOW(), '\n')", ktrigger + if (kdone == 1) then + printks "%s", 0, Sres + endif +endin + + +; print 2x2 random floats from the database every second +instr execarray_k + ktrigger metro 1 + kdone, kres[][] dbarray_k gidb, "SELECT RAND(), RAND() UNION SELECT RAND(), RAND()", ktrigger + if (kdone == 1) then + printk2 kres[0][0] + printk2 kres[0][1] + printk2 kres[1][0] + printk2 kres[1][1] + endif + +endin + + + + + +i "execscalar" 0 1 +i "execscalarstr" 2 1 +i "execarray" 4 1 +i "execarraystr" 6 1 +i "execscalar_k" 7 5 +i "execarray_k" 12 5 + + + \ No newline at end of file diff --git a/examples/6-mysql-randomnotes.csd b/examples/6-mysql-randomnotes.csd new file mode 100644 index 0000000..036b63a --- /dev/null +++ b/examples/6-mysql-randomnotes.csd @@ -0,0 +1,99 @@ + + +-odac + + +/* + EXAMPLE 3 + + Insert some frequencies and durations to a MySQL database + then query/play random pairs + + +*/ + +sr = 44100 +kr = 4410 +nchnls = 2 +0dbfs = 1 +seed 0 + + +; connect: type, hostname or IP, database name, username, password +gidb dbconnect "mysql", "localhost", "databasename", "username", "password" + + +; initialise the example +instr start_example + + ; create tables if not existing/truncate if existing and fill with frequency and duration data + dbexec gidb, "CREATE TABLE IF NOT EXISTS frequencies (freq FLOAT)" + dbexec gidb, "TRUNCATE TABLE frequencies" + dbexec gidb, "CREATE TABLE IF NOT EXISTS durations (dur FLOAT)" + dbexec gidb, "TRUNCATE TABLE durations" + dbexec gidb, "INSERT INTO frequencies (freq) VALUES (277.2), (349.272), (415.24559), (523.35359), (391.96079)" + dbexec gidb, "INSERT INTO frequencies (freq) SELECT freq*2 FROM frequencies" + dbexec gidb, "INSERT INTO durations (dur) VALUES (0.1), (0.2), (0.4), (0.8), (1), (1.2)" + + ; run the sequencer instrument for 30 seconds + event_i "i", "sequence", 0, 30 +endin + + +; random sequencer instrument +instr sequence + + ; query to return random frequency/duration pair + Sql = {{ + SELECT f.freq, d.dur + FROM frequencies f + JOIN (SELECT dur FROM durations ORDER BY RAND() LIMIT 1) d + ORDER BY RAND() + LIMIT 1 + }} + + ; array needs to be initialised or schedkwhen complains + kevent[][] init 1, 2 + + ; query twice per second + ktrig metro 3 + + ; query on metro returning the frequency/duration pair + kdone, kevent[][] dbarray_k gidb, Sql, ktrig + + ; schedule the note + schedkwhen kdone, 0, 0, "osc", 0, kevent[0][1], kevent[0][0] + +endin + + +; play a note +instr osc + + ; pick a random waveform + ifn = int(random(1, 4)) + + ; set frequency and envelope + ifreq = p4 + kamp line 0.5, p3, 0 + + ; play it + a1 oscil kamp, ifreq, ifn + outs a1, a1 +endin + + + + + + +f1 0 16384 10 1 +f2 0 16384 10 1 0.5 0.3 0.25 0.2 0.167 0.14 0.125 .11 +f3 0 16384 10 1 0 0.3 0 0.2 0 0.14 0 .111 +f4 0 16384 10 1 1 1 1 0.7 0.5 0.3 0.1 + +; begin example +i "start_example" 0 1 + + + \ No newline at end of file diff --git a/examples/7-violsqlite.csd b/examples/7-violsqlite.csd new file mode 100644 index 0000000..cabc753 --- /dev/null +++ b/examples/7-violsqlite.csd @@ -0,0 +1,172 @@ + + +-odac + + +/* + EXAMPLE 7 + + A rudimentary pitch tracking concatenative resynthesizer as such + + This creates a sqlite database in memory, and then uses the opcode getpitches to scan through a + sound file in non-realtime, storing detected pitches and the relevant offset time of the pitch in + the database. The example file is a descending violin glissando. + + When done, the instrument "playmatches" is scheduled twice which plays an oscillator varying in pitch, + which is pitch tracked and the nearest frequency is found in the database, prompting the "segment" + instrument to be scheduled with the relevant offset. + + + 1. for 20s in which nearest matches are played only if the detected pitch has changed outside of a threshold + 2. as above but with matches played continuously + + The result is that the violin segments picked should moreorless match what the oscillator is doing. + +*/ + +sr = 44100 +kr = 4410 +nchnls = 2 +0dbfs = 1 + + +; create an in-memory sqlite database and create a table +gidb dbconnect "sqlite", ":memory:" +dbexec gidb, "CREATE TABLE pitches (time REAL, cps REAL)" + +; file of ascending piano pitches +gSfile = "sounds/violin.wav" +gifn ftgen 0, 0, 0, 1, gSfile, 0, 0, 0 + +; detect pitches and insert time/cps to database given a filename, in non-realtime +opcode getpitches, 0, S + Sfile xin + ktimek timeinstk + ktime timeinsts + klast init -1 + kcount init 0 + + ; run in the first single k-rate cycle + if (ktimek == 0) then + + ; get file length in k-cycles + ilen filelen Sfile + kcycles = ilen * kr +loop: + ; read file and track pitch + ain diskin2 Sfile, 1 + ;ain butterbp ain, 500, 250 + koct, kamp pitch ain, 0.01, 6, 12, 6, 12, 60 + + ; only take action if pitch has changed + kchanged changed2 koct + if (kchanged == 1) then + + ; only store if cps is reasonably different from the last value + kcps = cpsoct(koct) + + if (1==1) then + + ; insert to database: the dbexec_kb opcode is k-rate but blocking/synchronous. + ; simpler to use for the non-realtime operation as regular _k opcodes are threaded/asynchronous + ktime = kcount / kr + Squery sprintfk "INSERT INTO pitches (time, cps) VALUES (%f, %f)", ktime, kcps + dbexec_kb gidb, Squery + klast = kcps + endif + endif + loop_lt kcount, 1, kcycles, loop + + endif +endop + + + +; begin the example: find pitches and then schedule the next step +instr start_example + getpitches gSfile + schedkwhen 1, 0, 0, "playmatches", 0, 20, 0 + schedkwhen 1, 0, 0, "playmatches", 20, 20, 1 + turnoff + +endin + + + +; pitch follow a descending oscillator and attempt to find a similar cps in the database, then schedule segment accordingly +instr playmatches + kdone init 0 ; for when the select query is done + klast init 0 ; last pitch played, in order to avoid repeats + + + ; oscillator + k1 linseg 400, p3, 200 + ktime linseg 0.001, p3, 2 + k2 oscil k1, ktime + ain oscil 1, abs(k2)+550, 1 + + ; track it + koct, kamp pitch ain, 0.01, 5, 10, 6, 12 + + ; only take action when the tracked pitch has changed + kchanged changed2 koct + if (kchanged == 1) then + + ; (very roughly) get a near frequency match from the database + kcps = cpsoct(koct) + + ; fairly nasty looking query for obtaining the nearest value + SquerySource = {{ + SELECT time FROM ( + SELECT time, cps FROM ( + SELECT time, cps FROM pitches WHERE cps >= %f ORDER BY cps ASC LIMIT 1 + ) + UNION SELECT time, cps FROM ( + SELECT time, cps FROM pitches WHERE cps < %f ORDER BY cps DESC LIMIT 1 + ) + ) x ORDER BY ABS(cps - %f) ASC LIMIT 1 + }} + + Squery sprintfk SquerySource, kcps, kcps, kcps + kdone, kpos dbscalar_k gidb, Squery, kchanged + + ;schedule the notes + if (p4 == 1) then + schedkwhen kdone, 0, 0, "segment", 0, 0.2, kpos + else + if (kpos < klast*0.8 || kpos > klast*1.2) then + schedkwhen kdone, 0, 0, "segment", 0, 0.2, kpos + klast = kpos + endif + endif + endif + + + ; uncomment to hear the oscillator as well as pitch matched output + ;outs ain*0.01, ain*0.01 +endin + + + +; play part of the sound file given a skip time with a basic envelope +instr segment + il = ftlen(gifn) + isec = il/sr + ist = sr*p4 + icps = 1/isec + aphs phasor icps + andx = aphs * il + aout tablei andx+ist, gifn + kamp linseg 0, p3*0.3, 1, p3*0.4, 1, p3*0.3, 0 + outs aout*0.1*kamp, aout*0.1*kamp +endin + + + + +f1 0 16384 10 1 0 0.3 0 0.2 0 0.14 0 .111 ; square wave + +i"start_example" 0 1 + + + \ No newline at end of file diff --git a/examples/sounds/violin.wav b/examples/sounds/violin.wav new file mode 100644 index 0000000..c490e1c Binary files /dev/null and b/examples/sounds/violin.wav differ diff --git a/examples/toCheck/7-sqlite-pitchmatcher.csd b/examples/toCheck/7-sqlite-pitchmatcher.csd new file mode 100644 index 0000000..1d45234 --- /dev/null +++ b/examples/toCheck/7-sqlite-pitchmatcher.csd @@ -0,0 +1,140 @@ + + +-odac + + +/* + EXAMPLE 9 + + A rudimentary pitch tracking concatenative resynthesizer + + This creates a sqlite database in memory, and then uses the opcode getpitches to scan through a + sound file in non-realtime, storing detected pitches and the relevant offset time of the pitch in + the database. The example file is a series of ascending piano notes. + + When done, the instrument "playmatches" is scheduled. This plays a descending oscillator + which is pitch tracked and then a similar pitch is found from the database, prompting the "segment" + instrument to be scheduled with the relevant offset. + The result is that the piano notes/sound file segments picked should moreorless match what the + oscillator is doing. + +*/ + +sr = 44100 +kr = 4410 +nchnls = 2 +0dbfs = 1 + + +; create an in-memory sqlite database and create a table +gidb dbconnect "sqlite", ":memory:" +dbexec gidb, "CREATE TABLE pitches (time REAL, cps REAL)" + +; file of ascending piano pitches +gSfile = "sounds/piano.wav" + + +; detect pitches and insert time/cps to database given a filename, in non-realtime +opcode getpitches, 0, S + Sfile xin + ktimek timeinstk + ktime timeinsts + klast init -1 + kcount init 0 + + ; run in the first single k-rate cycle + if (ktimek == 0) then + + ; get file length in k-cycles + ilen filelen Sfile + kcycles = ilen * kr +loop: + ; read file and track pitch + ain diskin2 Sfile, 1 + koct, kamp pitch ain, 0.01, 7, 11, 6, 12, 10, 8 + + ; only take action if pitch has changed + kchanged changed2 koct + if (kchanged == 1) then + + ; only store if cps is reasonably different from the last value + kcps = cpsoct(koct) + if (kcps > klast*1.1 || kcps < klast*0.9) then + + ; insert to database: the dbexec_kb opcode is k-rate but blocking/synchronous. + ; simpler to use for the non-realtime operation as regular _k opcodes are threaded/asynchronous + ktime = kcount / kr + Squery sprintfk "INSERT INTO pitches (time, cps) VALUES (%f, %f)", ktime, kcps + dbexec_kb gidb, Squery + klast = kcps + endif + endif + loop_lt kcount, 1, kcycles, loop + + endif +endop + + + +; begin the example: find pitches and then schedule the next step +instr start_example + getpitches gSfile + schedkwhen 1, 0, 0, "playmatches", 0, 20 + turnoff + +endin + + + +; pitch follow a descending oscillator and attempt to find a similar cps in the database, then schedule segment accordingly +instr playmatches + kdone init 0 ; for when the select query is done + klast init 0 ; last pitch played, in order to avoid repeats + + ; descending oscillator + k1 linseg 2000, p3, 200 + ain oscil 1, k1, 1 + + ; track it + koct, kamp pitch ain, 0.01, 7, 11, 6, 12, 10, 8 + + ; only take action when the tracked pitch has changed + kchanged changed2 koct + if (kchanged == 1) then + + ; (very roughly) get a near frequency match from the database + kcps = cpsoct(koct) + Squery sprintfk "SELECT time FROM pitches WHERE cps >= %f LIMIT 1", kcps + kdone, kpos dbscalar_k gidb, Squery, kchanged + + ; don't repeat notes (try the schedkwhen outside of the if block for continuous play) + if (kpos != klast) then + schedkwhen kdone, 0, 0, "segment", 0, 0.2, kpos + klast = kpos + endif + endif + + ; uncomment to hear the oscillator as well as pitch matched output + ;outs ain*0.01, ain*0.01 +endin + + + +; play part of the sound file given a skip time with a basic fade in/out +instr segment + iskip = p4 + kamp linseg 0, p3*0.1, 1, p3*0.8, 1, p3*0.1, 0 + a1 diskin2 gSfile, 1, iskip + aout = a1*kamp * 0.1 + outs aout, aout +endin + + + + +f1 0 16384 10 1 0 0.3 0 0.2 0 0.14 0 .111 ; square wave + +i"start_example" 0 1 + + + \ No newline at end of file -- cgit v1.2.3