The programme note becomes short:
'This piece is an exercise in reconfiguration. It reworks a previous piece, Writing Machine from 2011, first reducing it to its physical arrangement: A circular tableau of petri-dishes, sonically excited by small piezo speakers placed inside the dishes. An algorithm performs a continuous gesture, where sound fragments are rewritten based on the particular movements of a similarity search in a real-time sound data base. In this new instance, the monolithic and centralised machine has been replaced by a decentralised structure, spreading the algorithm over several small computers each of which has a certain autonomy. A radio antenna serves as a source of sonic material, tapped in an “uninterested” attitude.'
Before reimplementing, I was trying (171009) to read and understand the old source code again:
- the algorithm is decomposed into sub-functions, e.g. the overall is `DifferanceAlgorithm` that takes `DifferanceDatabaseThinner`, `DifferanceDatabaseFiller`, etc.
- the algorithms have a `step` method that produce a `Future` of something
- there is no clear model/view separation as in the new SP
- parameters are formalised as `Motion` which are stateful stepping functions
- `Phrase` has a length, a real-time `player` method and an off-line `reader` method
# (Main) Algorithm
- `overwriteSelector.selectParts`
- run filler
- for each part, `databaseQuery.find`
- for the matches, flat-map `overwriter.perform`
- run thinner
- add to phase-trace
## Motion
- constant(value: Double)
- linrand(lo: Double, hi: Double)
- exprand(lo: Double, hi: Double)
- sine (lo: Double, hi: Double, period: Int)
- walk (lo: Double, hi: Double, maxStep: Double)
- linlin (in: Motion, inLo: Double, inHi: Double, outLo: Double, outHi: Double)
- linexp (in: Motion, inLo: Double, inHi: Double, outLo: Double, outHi: Double)
- coin (prob: Double, a: Motion, b: Motion)
It's striking that this is very similar to patterns!
An alternative for the non-stateful motions would be to evaluate a function (expr) with time index. It would avoid the awkward
position sensitivity of patterns (e.g. imagine `linlin` where bounds are also motions/patterns/streams).
## OverwriteSelector
- `val num = frequencyMotion.step.toInt`
- iterate over `bestPart`
- a breaking point is found as max dissim
- some weird 'centering' is performed, whereby a region between minLen/maxLen around the breaking point is moved to include a centre position
## Filler
- `perform`
- `television.capture(dur)`
- `database.append(file, off, dur)`
- `latency` - "Latency in capture result in seconds" (zero for file, live = 0.2sec); it's probably an offset into the _captured_ file,
such that initial silence due to limiter is skipped
# gqrx
Remote control protocol.
Supported commands:
f - Get frequency (Hz)
F - Set frequency (Hz)
m - Get demodulator mode
M - Set demodulator mode (OFF, RAW, AM, FM, WFM, WFM_ST, WFM_ST_OIRT, LSB, USB, CW, CWL, CWU)
l STRENGTH - Get signal strength (dBFS)
l SQL - Get squelch threshold (dBFS)
L SQL <sql> - Set squelch threshold to <sql> (dBFS)
u RECORD - Get status of audio recorder
U RECORD <status> - Set status of audio recorder to <status>
c - Close connection
AOS - Acquisition of signal (AOS) event, start audio recording
LOS - Loss of signal (LOS) event, stop audio recording
\dump_state - Dump state (only usable for compatibility)
Reply:
RPRT 0 - Command successful
RPRT 1 - Command failed
link to software repository