-
Notifications
You must be signed in to change notification settings - Fork 137
/
changelog
675 lines (505 loc) · 36.1 KB
/
changelog
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
### 0.8.*
- Added `stretch` synth for timestretching samples, similar to `loop` but better and only plays the whole file. Stretches the audio's duration to the `sus` attribute without affecting pitch and does not require the tempo to be known.
```python
# Stretches the audio to 4 beats without affecting pitch
p1 >> stretch("Basic_Rock_135", dur=4)
```
### 0.7.*
- Add `.reload()` method for `loop` player to reload the file used, in case it has been overwritten.
- Update `PlayerKey` class (things like `p1.degree` etc) to behave better with `map` and `transform`
- Added `transform` method to Patterns
- Fixed `.pyc` files showing in the tutorials menu - you may have to uninstall and reinstall to see the benefit
- Improved in-house synchronisation between FoxDot instances.
- Add `PDelta` pattern; user supplies the step sizes between each value.
- Negative `offbeat` fix (thanks zdbm).
- Added startup file that loads on boot. Found in `path/to/FoxDot/lib/Custom/startup.py`. To use another startup file, you can run FoxDot with a `--startup` flag like so:
```bash
$ python -m FoxDot --startup path/to/my_startup.py
```
- Fix `MidiIn` missing Synth bug
- Improved clock timing. If the user is not using a `var` for the tempo, it will be far more accurate and synchronising with other FoxDot instances will be less likely to drift out of time. Also added the function to sync with instances of [EspGrid](https://github.com/d0kt0r0/EspGrid) by simply using `Clock.sync_to_espgrid()` (experimental).
- Added `Go()` function to run FoxDot code from within normal Python programs.
- Added `inf` variable, which can be used as a duration in any `var` object to continually use a value once it has been reached e.g. `var([0,1],[4,inf])`. This can be combined usefully with a special `var` object called `now` which starts the timing cycle for a `var` at the current time in the clock:
```python
d1 >> play("x-o-", amp=linvar([0,1],[8,inf], start=now))
```
- (Experimental) Added `Cycle` pattern type, which can be used in conjunction with `every` to more effectively iterate over different values used for different calls to the same method. For example, you spread `stutter` over 3 beats in one call, then 2 beats in the other, you would have to use a `var` like so:
```python
d1 >> play("x-o-").every(4, "stutter", dur=var([3,2],4))
```
This became problematic when introducting `sometimes` as you would not know the frequency of the call in advance. Now you can just use `Cycle` which will be converted to a `var` with appropriate timing values when used with `every`. Any other use of `Cycle` will be treated as a regular `Pattern` object. Example of how to use `Cycle`:
```python
d1 >> play("x-o-").sometimes("stutter", dur=Cycle([2,3]))
```
- Fix `Pattern.offlayer` which is similar to `offadd` but requires a second argument specifying a method apply to the second layer as a string *then* the duration to delay the layer before specifying the arguments and keyword arguments to be supplied to the given methods. E.g.
```python
# Layer with the pattern trimmed to length 3 with a delay of 0.75 beats
P[0, 1, 2, 3].offlayer("trim", 0.75, 3)
```
- Include `.version` file in `setup.py` and add extension packages `VRender` and `SonicPi`.
- Update `Sonic-Pi` extension to work with Python 2.
- Change `Clock` time measure data type to `float` instead of `Fraction` to improve efficiency but sacrificing accuracy.
- Add `RandomGenerator.set_override_seed` that forces all random number generator patterns to use the same seed - useful if you want to play the same sequences across multiple machines.
- Added `DefaultServer.record(fn)` and `DefaultServer.stopRecording()` to record audio from SuperCollider. Files are recorded into `FoxDot/FoxDot/rec/` directory. If `fn` is not given, a filename is created automatically from a timestamp.
- Added nested directories to extension modules that were missing, e.g. `VRender/tmp`, to the manifest for PyPI
- Fixed attribute access for `Pvar` which allows for operations combining other patterns.
- Fixed bug caused when using Python 2 and slicing `Pattern` with no supplied end value e.g. `PDur(3, 8)[1:]` that would create giant arrays and raise a `MemoryError`.
- Added autocomplete prompt (work in progress).
### v0.7.1 fixes and updates
- Improved `PlayerKey.map` method e.g. `p1.pitch` to only return one value instead of a Pattern
- Improved `Clock.clear` to make sure Players don't reset and continue playing, which sometimes happened
- Use `float` instead of `Fraction` for timing to reduce computation time in the main clock loop. So far this hasn't had any impact on timing but please get in contact if it does. It has improved performance on low spec machines such as a Raspberry Pi.
- Improve bracket finding in the main interface so it only checks visible portion of the screen so it no longer lags if there is a large amount of text in the editor.
- Added the `VRender` extension, thanks to [mathigatti](https://github.com/mathigatti), that allows users to add synthesised vocals. Requires Python modules MIDIUtil and urllib and musescore (Linux/Mac only). See the [README](https://github.com/Qirky/FoxDot/blob/master/FoxDot/lib/Extensions/VRender/README.md) for more information.
### v0.6.10 fixes and updates
- Continued work on improving efficiency across the board. Now works fine on Raspberry Pi machines (be careful when using lots of a effects though!).
- Fixed the `sus` and `blur` issues when using a different tempo.
- Improved timing on `Player` method calls that send extra OSC messages, such as `stutter` and `jump`.
- Renamed `Pattern` method `pipe` to `concat`. Also improved efficiency of this method as well as making `Pattern.append()` much more efficient (useful to adding items to a `Pattern` from a loop.
### v0.6.9 fixes and updates
- Changed the behaviour for composing events sent to SuperCollider. When several `PGroup`s with different sizes are used, events are now the size of the largest `PGroup` as opposed to the lowest common multiple of all of their lengths. This is best demonstrated by the following example. Using a pitch of `(0, 2, 4)` and delay of `(0, 0.5)` would play the whole chord twice whereas now it only delays the second value:
```python
# Old behaviour using lowest common multiple
p1 >> pluck((0, 2, 4), dur=PDur(3, 8), delay=(0, 0.5, 0, 0.5, 0, 0.5))
# New behaviour
p1 >> pluck((0, 2, 4), dur=PDur(3, 8), delay=(0, 0.5))
```
- Improved efficiency of OSC message composition which should improve performance on lower-spec machines i.e. it can run reasonably well on a Rasberry Pi using a high clock latency value.
- Move the calculation of sustain using `blur` to SuperCollider such that using an effect such as `chop` that makes use of the sustain value no longer relies on `blur` as well:
```python
# Old behaviour required adjusting for the blur
p1 >> pluck(dur=PDur(3, 8), sus=2, blur=1.5, chop=4 * 1.5)
# New behaviour still 'chops' the sound into 4 parts
p1 >> pluck(dur=PDur(3, 8), sus=2, blur=1.5, chop=4)
```
### v0.6.8 fixes and updates
- Added `FoxDot.reload()` function to reload SynthDefs and samples in SuperCollider if FoxDot was started after having run `FoxDot.start` in SuperCollider. No longer requires you to close and re-open FoxDot.
- If SuperCollider is not open and a user tries to send a message from FoxDot, an error message is displayed. This now only happens once instead of after every message. This is to stop the console buffer filling up memory if the user is purposely not using SuperCollider.
- On bootup, check for newer versions of FoxDot available on PyPI and let the user know that they should update if so.
### v0.6.7 fixes and updates
- Added `often`, `sometimes`, and `rarely` methods that wrap the `every` method but use random durations to decide when to call a method:
```python
# Stutter frequently
d1 >> play("x-o-").often("stutter", 4, dur=1)
# Reverse sometimes
p1 >> pads([0, 1, 2, 3]).sometimes("reverse")
# Call the solo method, but not frequently
p2 >> pluck((0,2,4), dur=PDur(3,8)).rarely("solo")
```
- Added Player keyword `quantise` to start playing as soon as possible when set to `True`. Defaults to `False` such that Players start playing at the next bar.
- Added menu options to allow users to set the CPU usage and Clock latency for better performance on individual systems.
- Fixed links to webpages from help menu for Linux and Mac OS.
- Added overdrive effect, which can be added using `drive` keyword
### v0.6.6 fixes and updates
- Added `jump` method to `Player` class: plays an event one step early (can be specifed by using `ahead` keyword) using keyword arguments to specify how the event is played.
```python
d1 >> play("x-o-").every(7.5, "jump", cycle=8, sample=2, delay=var([-0.25, 0],8))
```
- Added `penta` method to `Player` for quickly switching between pentatonic scales. No arguments turns it on, 0 or `False` turns it off.
- Added `alt_dur` method to `Player`. This is an alternative way to set the duration of a player, mostly useful if using a `linvar` as a duration. When durations change, the clock position is recalcalculated - so using a `linvar` causes many of these calculations to be made and can lead to delayed messages to SuperCollider. This method manipulates the `bpm` attribute of the player to set the duration which does not require recalculating the clock position and is more efficient but less accurate.
- Update `trim`, `ltrim`, and `extend` methods for `Pattern` class. These can be looped and used with the `every` method.
- \* Experimental \* - Added CPU usage menu. Going to `Language` -> `CPU Usage` you can choose low, medium, or high (default) level of CPU usage which is derived from the number of cycles the `Clock` makes each second. Each CPU usage step is 10x more than the previous. Currently this value resets between uses of FoxDot.
- Fixed `setup.py` to load description from the README.md file
### v0.6.5 fixes and updates
- Added option to duplicate a line of text using `Ctrl+D` shortcut.
- Added `Ctrl+Shift+Direction` shortcut to select a word of text.
- Set menu text for Linux to OS default
- More config options (transparency / menu / load on startup) added - thanks to [fgonzalez-cespi](https://github.com/fgonzalez-cespi) for these.
- Add ability to add "swing" to the `Clock` using a `var` object at the clock's "nudge" attribute e.g. `Clock.nudge = var([0,0.1],1/2)` will delay every other half beat by 0.1 seconds.
- Improve right-click behaviour
### v0.6.4 fixes and updates
- Fix Tkinter issues with "KP" events and added selection using shift + numpad usage
- Update setup.py to allow FoxDot to be started from the CLI just using a simple `FoxDot` command.
### v0.6.3 fixes and updates
- Fixed bug stopping pentatonic versions of scales being updated
- Moved a few samples around - notably the default "o" snare drum was replaced with the default snare drum assigned to "u"
- Echo effect now relates to number of beats instead of the value of sustain such that `echo=0.5, sus=4` means you hear the echoed sound after half a beat, not after 2 beats.
- Added navigation using the numpad
### v0.6.2 fixes and updates
- Fixed play string error when using random characters and random sample numbers
- Added timestamping to `MidiOut` SynthDef (to be re-named `midi` in future) and a `Clock.midi_nudge` value that can be set to help synchronise FoxDot with an external MIDI synth. A value of around 0.15 - 0.25 is typical.
```python
# Set up two simple loops and adjust Clock.midi_nudge until they are synchronised
p1 >> MidiOut([0,7])
p2 >> play("x * ")
Clock.midi_nudge = 0.175
```
### v0.6.1 fixes and updates
- Fixed bugs found in Python 2
### v0.6.0 fixes and updates
- Added functionality to specify samples when using the `play` SynthDef. This can be done from the play string by using the bar character in the form `|<char><sample>|`. These can also be patterns:
```python
p1 >> play("|x2|-u-")
p1 >> play("(x )( |x[23]|)u ")
p1 >> play("|x{0123}| u ")
p1 >> play("|[xxxx][23]| u ")
```
- Improved timing of musical events slightly
- Added ability to set tunings for scales
```python
Scale.default.set("major", tuning=Tuning.just)
Scale.default.set("minor", tuning=Tuning.ET12)
Scale.default.set("mixolyidian", tuning=[0, 1, 2, 3, 4, 5, 6, 7 ,8, 9, 10, 11])
```
- You no longer need to specify pattern types in functions used in `PlayerKey.map`. Previously this would have thrown an exception but now does not:
```python
p1 >> pluck([0,1])
p2 >> pluck(p1.pitch.map({1: lambda x: x + (0,2)}))
```
### v0.5.14 fixes and updates
- Improved the behaviour of repeatedly calling methods when using the `cycle` keyword:
```python
# Calls "stutter" on the 6th beat of an 8 beat cycle
p1 >> pads().every(6, "stutter", cycle=8)
```
### v0.5.13 fixes and updates
- Improved `TimeVar` algorithm and added `sinvar` class, which is a subclass of `linvar` but calculates it's values using a sinewave as opposed a linear scale.
- General refactoring and improvement on efficiency.
### v0.5.12 fixes and updates
- Improved `TimeVar` efficiency and can correctly handle the use of `GeneratorPattern` as an argument for duration.
- Slight re-ordering of samples with better descriptions when using `print(Samples)` (which is now a command in the help message).
- Added "pasha" SynthDef
- Experimental: you can use a `linvar` for tempo e.g. `Clock.bpm=linvar([40,120],16)`
### v0.5.11 fixes and updates
- The Player reset method can be called using a preceding ~ character such that the two lines below are equivalent:
```python
p1.reset() >> pads([0,2,4], dur=1/2)
~p1 >> pads([0,2,4], dur=1/2)
```
- The `reset` also stops calling repeat methods now.
- Fixed welcome message display size bug for Mac and Linux.
- Updated synths and samples.
### v0.5.10 fixes and updates
- Fix `GeneratorPattern` index behaviour.
- Improve `Player` efficiency; only update player keys that are being accessed.
- Use "alpha" transparency when single value transparency doesn't work.
### v0.5.9 fixes and updates
- Player `stutter` method no longer updates the internal "key" so improves efficiency when using it.
- Better handling of delays in `offadd` and `offlayer` pattern methods
### v0.5.8 fixes and updates
- Fixed panning issues on many SynthDefs so `fmod` spreads a signal across 2 channels effectively.
- Added the ability to use `Pattern` methods on player attributes when using the `every` method:
```python
d1 >> play("x-o-o", dur=PDur(5,8)).every(4, "rate.offadd", 2)
```
- Improved `every` to switch pattern methods on/off at the correct time when using a list of durations.
- FoxDot UI no longer crashes when saving / closing after using a lambda character.
### v0.5.6 fixes and updates
- Running FoxDot with a `--pipe` flag is compatible with Python 2
- Updated the "pads" SynthDef
- Old unidirectional server manager class can be used by editing config file.
### v0.5.5 fixes and updates
- Fix `TimeVar` class so it no longer inherits from `Repeatable` i.e. no longer has access to the "every" method.
- Fix pattern bug when creating a pattern using the `P` generator; `P[P(0,2)]` no longer returns `P[0, 2]`. However, `P[(0,2)]` is interpreted exactly as `P[0, 2]` and will return that instead.
- Added more variation to the "formantFilter" effect
- "loop" samples are added "on-the-fly" as opposed to loaded at start up. These can be loaded by filepath (with or without extension)
```python
a1 >> loop("/path/to/sample.wav")
a2 >> loop("/path/to/sample")
a1 >> loop("yeah") # Searches recursively for yeah.(wav|wave|aif|aiff|flac)
a1 >> loop("perc/kick") # Supports directories in the path
a1 >> loop("*kick*", sample=2) # Supports * ? [chars] and [!chars]
a1 >> loop("**/*_Em") # Supports ** as 'recursively all subdirectories'
```
### v0.5.4 fixes and updates
- Better communication from external processes. Running FoxDot with a `--pipe` flag (e.g. `python -m FoxDot --pipe`) allows commands to be written via the stdin. Each command should end with a blank line.
### v0.5.3 fixes and updates
- Player attribute aliases added. Using `pitch` and `char` will return a player's `degree` attribute.
- Player Key behaviour improved. Using multiple conditions e.g. `4 < p1.pitch < 7` will hold the value 1 while `p1.pitch` is between 4 and 7, and a 0 otherwise. These conditions can be "mapped" to values other than 1 by using the `map` method to map values, or results of functions, to other values/functions (which are applied to the values):
```python
b1 >> bass(var([0,4,5,3]))
# Takes a dictionary of values / functions
p1 >> pads(b1.pitch.map(
{ 0: 2,
4: lambda x: x + P(0,2),
lambda x: x in (5,3): lambda y: y + PRand([0,2,4,7])
}))
```
- Known issue: mapping to a pattern of values for a Player's duration does not work as expected so be careful.
- The `Player.every` method can now take `Pattern` methods, which affect the degree of the `Player` (specifying attributes will be added later). Instead of applying the function every time it is called, it has a switch that applies the function then "un-applies" the function.
```python
p1 >> play("x-i-").every(6, "amen").every(8, "palindrome")
```
### v0.5.2 fixes and updates
- Improved behaviour of `TimeVar`, `Pvar`, and `PvarGenerator` classes when created via mathematical operators.
- SynthDefs can be read loaded into FoxDot from SuperCollider using the `FileSynthDef` and `CompiledSynthDef` classes (see `SynthDef.py`).
- `DefaultServer` instance has a `forward` attribute that, when not `None`, sends any outgoing OSC message to. Example:
```python
# Sends any OSC message going to SuperCollider to the address
DefaultServer.forward = OSCClient(("localhost", 57890))
```
### v0.5.0 fixes and updates
- Pattern "zipping" behaviour changed. A `PGroup` within a sequence is extended when zipped with another instead of nesting it. e.g.
```python
# Old style
>>> P[(0,1),(2,3)].zip([(4,5)])
P[P(0, 1, P(4, 5)), P(2, 3, P(4, 5))]
# New style
>>> P[(0,1),(2,3)].zip([(4,5)])
P[P(0, 1, 4, 5), P(2, 3, 4, 5)]
```
- Consequently, sample player strings can use the `<>` arrows to play multiple sequences together using one string.
```python
# This plays three patterns together
d1 >> play("<x >< o[ o]>< -(-=)>", sample=(0,1,2))
```
- To use a different sample value for each pattern use a group of values as in the example above. Each value in relates to each pattern e.g. the "x" used sample 0, the "o" pattern uses sample 1 and the "-" pattern uses sample 2. If you want to use multiple values just use a group within a group:
```
# Plays the snare drum in both channels at different rates
d1 >> play("<x x>< o >", pan=(0, (-1,1)), rate=(1, (1,.9))
```
- Network synchronisation introduced! This is still quite a beta feature and feedback would be appreciated if you come across any issues. Here's how to do it:
To connect to another instance of FoxDot over the network you need one user to be the master clock. The master clock user needs to go from the menu to "Language" then "Listen for connections". This will start listening for connections from other FoxDot instances. It will print the IP address and port number to the console; give this information to your live coding partner. They need to run the following code using the IP address on the master clock machine:
```python
Clock.connect("<ip address>")
```
This will copy some data, e.g. tempo, from the master clock and also adjust for the differences in local machine time (if your clocks are out of sync). The latter will depend on the latency of the connection between your machines. If you are out of time slightly, set the `Clock.nudge` value to a small value (+-0.01) until the clocks are in sync. Now whenever you change the `Clock.bpm` value, the change will propagate to everyone on the next bar.
### v0.4.14 fixes and updates
- Pattern getitem method now allows Patterns to be indexed using a Player Key e.g. `P[0,1,2,3][p1.degree]` that will return the item in the Pattern based on the integer values of the key (`p1.degree` in this example).
- Added `future` method. Like `schedule` it adds a callable object to the queue but doesn't need the exact beat occurrence, just how many beats in the future from "now". First argument is time, followed by the object, arguments, and keyword arguments.
- Player object `stop` method properly removes the player from `Clock.playing` list.
- Using Player Key `__getitem__` returns a player key whose calculation function is `__getitem__`. This is useful if you want to use just one of the values of another player if they are in a group. e.g.
```python
p1 >> pads((0,2,4) + var([0,4,5,3]))
b1 >> bass(p1.degree[0]) # Only plays the "root" note of the chord
```
- SuperCollider bus number resets to 4 instead of 1 to prevent feedback loops when using reverb.
- Changed "verb" keyword to "mix" for reverb effect. Default is changed from 0.25 to 0.1.
- `GeneratorPattern` `new` method converts the `other` argument to a Pattern so you can use lists/tuples as opposed to just Patterns/PGroups when performing operations e.g. `PWalk() + (0,4)`.
- Fixed `newline` method to only add an indent if the INSERT index was in brackets or following a colon instead of doing so if the line had open brackets / colon. Evaluated code no longer highlights any empty preceeding lines.
- Python 3 uses xrange as range
### v0.4.13 fixes and updates
- Moved demo files into main package to fix install from pip.
### v0.4.12 fixes and updates
- `Player.stop_calling` is now `Player.never`. If a `Player` is calling its own method (implemented by the `every` method e.g. `p1 >> pads().every(4, "reverse")` you can now stop the repeated call by using `p1.never("reverse")`.
- Fixed circular referencing bug when using PGroups e.g. `p1 >> pads(p1.degree + (0,4))`
- Window transparency can now be toggled from the "Edit" menu
- Added Tutorial files that can be loaded from the menu
- Multiple uses of the `every` method with the same method name can be used together by specifying an `ident` keyword, which can be any hashable value i.e. a string or integer.
```python
# The second "stutter" no longer overrides the first
d1 >> play("x-u-").every(8, "stutter", 8).every(3, "stutter", 4, dur=1, degree="y", ident=1)
```
- Fix `group_modi` function to test for `TimeVar` instances instead of trying and failing to index their contents so that `TimeVar`s with strings in their contents don't get into an infinite recursive call.
### v0.4.11 fixes and updates
- Removed `sys.maxint` to conform with Python 3
### v0.4.10 fixes and updates
- Fixed negative pitch bug
- `PGroupMod` replaces `PGroupStar` when using square brackets in a "play" string. This "flattens" the values so that many nested `PGroups` don't create exponentially larger loops when sending events to SuperCollider.
- Fixed `stutter` so that delays caused by `PGroups` are no longer lost.
- `PRand`, `PwRand`, and `PxRand` choose from a random index instead of a random element so that any "nested" `GeneratorPatterns` generate a new item instead of returning the same one i.e. at index 0.
- Fixed `Player.degrade`
- `slidedelay` default value changed from 0.75 to 0
- Replaced "Control" with "Command" for menu short-cuts on Mac OS (Thanks ianb)
- Improved documentation layout
- Player methods such `shuffle` no longer affect the text of a `play` Player as it would overload the undo heap. This may be added back in at a layer date.
- Infinite recursion errors caused by circular referencing no longer seem to occur.
- Improved printing of Players to include identifier e.g. `<p1 - pluck>`.
### v0.4.9 fixes and updates
- Fixed issues with indexing `GeneratorPattern` and using `var` in Player methods.
- Random `GeneratorPattern` objects, such as `PRand` can take a `seed` keyword that will give you the same sequence of values for the same value of seed (must be an integer).
### v0.4.8 fixes and updates
- Unsaved work is stored in a temporary filed that can be loaded on the next startup.
- Player objects can now take tuples as an argument, which delays the next event (similar to the `delay` argument but works with the following event)
```python
# The Player object uses the smallest duration in the tuple to move to the next event
p1 >> pluck([0,1,2], dur=[1,1,(0.5,1)])
```
- Pattern function `PRhythm` takes a list of single durations and tuples that contain values that can be supplied to the `PDur` e.g.
```python
# The following plays the hi hat with a Euclidean Rhythm of 3 pulses in 8 steps
d1 >> play("x-o-", dur=PRhythm([2,(3,8)]))
```
### v0.4.7 fixes and updates
- FoxDot is now Python 3 compatible, so make sure you treat your print statements as functions i.e. use `print("Hello, World!")`
- Added `audioin` SynthDef for processing audio from the default recording device.
- Fixed bugs relating to chaining multiple `every` methods and ending their call cycle when the parent player is stopped
- Improved flexibility of referencing player attributes e.g.
```
p1 >> pads([0,1,2,3], dur=2).every(8, "stutter", 4, degree=p1.degree+[2,4,7])
```
### v0.4 fixes and updates
- FoxDot is now Python 3 compatible, so make sure you treat your print statements as functions i.e. use `print("Hello, World!")`
### v0.3.7 fixes and updates
- Nested pattern bug fixed so that they no longer cause patterns to loop
- Improved clock scheduling after proper "latency" implementation
- Added a new SynthDef, `loop`, to play longer samples:
```python
# First argument is the name of the file minus the extension
p1 >> loop("billions")
# Use the dur keyword to specify when to loop the file
p1 >> loop("billions", dur=8)
# The second argument is the starting point in beats such that the following 2 lines are equivalent
p1 >> loop("billions", dur=16)
p1 >> loop("billions", [0,8], dur=8)
```
- Added ability to use the lambda symbol in place of the word lambda. Insert it by using `Ctrl+L`.
- Put `slide`, `slidefrom`, `coarse`, `pshift` into their own effects
### v0.3.6 fixes and updates
- Any delay or stutter behaviour in Players is now handed over to SuperCollider by timestamping the OSCBundle, which should make FoxDot a lot more efficient & removed `send_delay` and `func_delay` classes.
- Using a `TimeVar` in a pattern function, such as `PDur`, now creates a time-varying pattern as opposed to a pattern that uses the `TimeVar`'s current value. e.g.
``` python
>>> test = PDur(var([3,5], 4), 8)
>>> print test # time is 0
P[0.75, 0.75, 0.5]
>>> print test # time is 4
P[0.5, 0.25, 0.5, 0.25, 0.5]
```
- Adding values to a player performs the whole operation as opposed to adding each value in turn when the Player is called. This improves efficiency when using data structures such as `TimeVar`s as it only creates a new once `TimeVar` when the addition is done.
- Improved usability of `PlayerKey` class, accessed when get the attribute of a Player e.g. `p1.degree`.
- Sleep time set to small value. 0 sleep time would crash FoxDot on startup on some systems.
- Made the behaviour of the `every` method more consistent rather than just starting the cycle at the next bar.
### v0.3.5 fixes and updates
- In addition to P\*, P+, P/, and P\** have been added. P+ refers uses the sustain values in a player to derive its delay. P/ delays the events every other time it is accessed, and P\** shuffles the order the values are delayed.
- Added `PWalk` generator pattern.
- TimeVars are easier to update once created.
```python
# Creates a named instance called foo
var.foo = var([0,1],4)
# Reassigning a var to a named var updates the values instead of creating a new var
var.foo = var([2,3,4,5],2)
```
- Removed `sleep` from scheduling clock loop to increase performance. If you want to decrease the amount of CPU FoxDot uses, change the sleep duration to a small number around 0.001 like so
```python
Clock.sleep_time = 0.001
```
- Added pitch shift (`pshift`) to Sample Players, which increases the pitch of a sample by the number of semitones. You can use `Scale.default.semitones()` to generate semitones from the current scale.
### v0.3.3 fixes and updates
- Added a new `Pattern` type data structure called a P-Star or `P*`. It is a subclass of `PGroup` but it has a "behaviour" that effects the current event of Player object, which, in this instance, adds a delay to each value based on the current Player's duration. e.g.
```python
# Plays the first note, 0, for 4 beats then the pitches 2, 4, and 6 at 4/3 beats each.
p1 >> pluck([0, P*(2,4,6)], dur=4)
# The can be nested
p1 >> pluck([0, P*(2,4,P*(6,7)], dur=4)
# Work in the same way that a SamplePlayer uses square brackets
p2 >> play("x[--]o[-o]")
```
- Frequency and buffer number calculation is done per OSCmessage which means these values can be modified in any delayed message i.e. when using the Player `stutter` method like so:
```python
p1 >> pluck([0,1,2,3], dur=1).every(4, 'stutter', 4, degree=[10,12], pan=[-1,1] )
d1 >> play("x-o-").every(5, 'stutter', 2, cycle=8, degree="S")
```
- Using as `linvar` as the Clock tempo will no longer crash the Clock.
- New effects have been added; `shape` which is a value between 0 and 1 (can be higher) that relates to a level of distortion, and `formant` which is a value between 0 and 8 and applies different formant filters to the audio.
- `hpf` and `lpf` have resonance values now: `hpr` and `lpr`
- You can open the config file directly from FoxDot by using the "Help & Settings" menu. Likewise you can open the directory that holds where your samples are kept. This can be changed in the config file.
### v0.3.2 fixes and updates
- `PlayerKey` data type can handle `PGroup` transformations without crashing, which improves performance when using `follow`
- `PlayerKey` data type greater than and less than functions fixed and now works with amplitudes.
- Better handling of scheduled functions that are "late"
- Experimental: `play` SynthDef can have a rate of -1 to be played in reverse and also uses a keyword `coarse` similar in function to `chop`
- Added `Pattern` method, palindrome that appends a mirrored version of the pattern to itself.
- Removed visual feedback for shuffling, rotating, etc patterns in Players as it did not work correctly with nested patterns.
### v0.3.1 fixes and updates
- `TempoClock` uses a `start_time` value that, when used on multiple instances of FoxDot, should synchronise the timings. This is a work in progress
- Added a "use SC3 Plugins" tick-box on the "Code" drop down menu to allow for easier configuration
- `piano` SynthDef added using th SC3 Plugin "MdaPiano"
### v0.3 fixes and update
- `var` type can be used with Player `delay` and nested groups in the `oct` attribute.
- Increased `TempoClock` latency to 0.2 seconds for improved performance.
- Better handling for auto-completed quotation marks
### v0.2.11 fixes and updates
- Caught `ImportError` if the user does not have `rtmidi` installed.
- Improved `Player.stutter
### v0.2.10 fixes and updates
- New SynthDefs added. Use `print SynthDefs` to view.
- Improved timing in the `TempoClock` class through use of threading and a latency value. Thanks to Yaxu and Charlie Roberts for the help.
- Dubstep samples added to the 'K' character.
- Sample banks re-arranged. Use `print Samples` for more information.
- Sample Player argument, `scrub` removed. You can now use `slide`/`slidefrom` and `vib` as you would do with a normal Player object to manipulate playback rate.
- `Pattern` class now has a `layer` method that takes a name of a `Pattern` method as its first argument and then arguments and keyword arguments for that method and creates a pattern of `PGroups` with their values zipped together.
```python
>>> print P[1,2,3,4].layer("reverse")
P[P(1, 4), P(2, 3), P(3, 2), P(4, 1)]
>>> print P[1,2,3,4].layer("rotate", 2)
P[P(1, 3), P(2, 4), P(3, 1), P(4, 2)]
```
- New nested `PGroup` behaviour added for players. Each value in each `PGroup` in an event relates to the values in any other `PGroup` in the same index, even if that value is also a `PGroup`. This concept is better described through an example:
```python
p1 >> pluck((0,2), pan=(0,(-1,1)), vib=(0,(0,12)), dur=4, chop=(0,4))
```
The first note, 0, is played with a pan of 0, chop of 0, and with no vibrator added. The second note, 2, is played with a chop of 4 and with no vibrato with a pan of -1 (left) but with a vibrato value of 12 with a pan of 1 (right).
- Experimental: Players can "follow" other Players' attributes over time by referencing their attributes.
```python
p1 >> pads([4,5,6,7], dur=2, chop=4)
p2 >> pluck(p1.degree + 2, vib=p1.chop*3)
```
### v0.2.9 fixes and updates
- Improved automatic bracket handling and formatting
- Colour scheme update
- "Upper-case" samples now read properly
- `cycle` argument added to the `.every()` player method to denote the cycle length of which to execute the specified method, e.g.
```
# Shuffles the samples on the 5th beat of each 8 beat cycle
bd >> play("x-o-").every(5, 'shuffle', cycle=8)
```
### v0.2.8 fixes and updates
- Minor bug fixes
- Improved automatic bracket handling and formatting
- Console is now resizable
- Scale and root can be assigned using the equals operator e.g. `Scale.default = "minor"` and `Root.default = var([0,4])`
### v0.2.7 fixes and updates
- Rest class added
- Undo and Redo functions fixed
- Infinite loop caused by empty brackets in PlayStrings fixed
- Menu bar added with several short-cuts
- Player follow method improved
- Improved documentation
- "style" keyword argument changed to "sample"
### v0.2.6 fixes and updates
- OSC Communication is now done through a dedicated SuperCollider Quark
### v0.2.3 fixes and updates
- Effects are now implemented using busses on SuperCollider, which uses less CPU
- Effects can be customised and defined
- Sample Player behaviour (i.e. how the string of characters relates to playback) has been altered. Square brackets refer to a single event even though two samples are played.
- SuperCollider is booted on startup with a compiled startup file.
### v0.2.2 fixes and updates
- `PDur` added: a pattern that implements Euclidean Rhythms
- Player attributes can be manipulated using the `Player.every` method
- Errors caught and displayed in FoxDot console instead of crashing
- Can set different tempi for Players using the `bpm` keyword
- Sample Player objects can play multiple samples together by grouping them as a PGroup but cannot feature square brackets
### v0.2.1 fixes and updates
- Syntax highlighting bugs fixed
- Visual feedback for `shuffle`, `mirror`, and `rotate` methods for `play` SynthDef
- SC3 Plugins disabled by default
- Player Object dictionaries shallow copied before iteration to stop `RunTimeErrors` occurring
### v0.2.0 fixes and updates (4/12/16)
- Reorganised project structure. Samples and code are kept separate.
- SuperCollider `OSCFunc.scd` now found in `/osc/` folder
- `setup.py` now included for an easier install
- (in progress) characters can have more than one sample attached to them. These are accessed by supplying a `buf` keyword argument.
- Python lists can be interpreted as FoxDot pattern when attached with a P prefix e.g. `P[1, 2, 3] + [0,2]` will return `P[1,4,3,3,2,5]` not `[1,2,3,0,2]`.
---
### v0.1.9 fixes and updates
- PSparse renamed to PBin
- Loading the icon now works on Linux
- Upheaval of SCLang API
- Player Objects now have visual feedback behaviour via the `bang` method and take Tkinter tag_config keyword arguments.
- Consolas now default font
- Fixed `Pvar` and `linvar` bugs
### v0.1.8 fixes and updates
- PSparse pattern type added (all Pattern names can be seen by executing `print(PatternTypes)`
- Major overhaul of Pattern nesting/lacing behaviour. Patterns can now be nested to multiple levels.
- Player object attributes now 'follow' one another and their current values are examined instead of the Pattern value
### v0.1.7 fixes and updates
- "Chop" added to default SynthDef behaviour
- GUI icon updated
- Using `var` objects for Player durations no longer crashes
- New Pattern types added
- FoxDot can be run using `python -m FoxDot` if FoxDot is in your PATH
### v0.1.6 fixes and updates
- Decimator (a.k.a. bitcrush) added to default SynthDef behaviour
- `SynthDefs` and `BufferManager` can be reloaded
- Removed automatic bootup of sclang as default behaviour
- Added new SynthDefs
### v0.1.5 fixes and updates
- Removed RegEx find and replace `>>` and `$` syntax. FoxDot now uses pure Python code and saved files can be run by themselves.
### v0.1.4 fixes and updates
- Save/Open file feature added
- Console can now be toggled
- Reduced CPU usage when the TempoClock queue is empty
- Added a 'grain' attribute to the `sample_player` SynthDef
### v0.1.3 fixes and updates
- Key bindings for Linux, Mac, and Windows 10 fixed
- Fixed freeze on keyboard interrupt exit