Changelog¶
[UNRELEASED] - 2026-09-20¶
Added
Adding
!as a synonym forstutter.d1 >> pluck().sometimes('!', [2,3])
Adding methods in the Player to wait n beats/bars before releasing the sound.
An alternative to the
@nextBar/@futureBar/Clock.schedulefunctions..wait(n=0)waitnbeats
d0 >> play('.-.-', sample=0, pan=-1).wait() d1 >> play('x...', sample=0, pan=-1).wait(8) d2 >> play('..o.', sample=0, pan=-1).wait(16)
.wait_bars(n=0)waitnbars
Clock.meter = 4,4 # is used by wait_bars/futureBar e0 >> play('.-.-', sample=2, pan=1).wait_bars() e1 >> play('x...', sample=2, pan=1).wait_bars(2) e2 >> play('..o.', sample=2, pan=1).wait_bars(4)
Adding namespace variables as autocomplete options
Adding the
Player.setmethod to set multiple attributes at once.What allows you to go from this:
p1.slide = 2 p1.slidedelay = .2 p1.cut = .5 p1.delay = .5
To this:
p1.set(slide=2, slidedelay=.2, cut=.5, delay=.5)
Converting set objects, such as
{1,2}, intoPRand
Changed
Move FoxDotQuark to this repository and remove the interaction with the SuperCollider IDE. (#36)
Fixed
SyntaxWarningin Python 3.14 (#16)Boot SuperCollider via configuration, command line, or code.
With the CLI:
FoxDot -b # or FoxDot --boot
With a python module:
python -m FoxDot -b # or python -m FoxDot --boot
With the environment variable:
export BOOT_ON_STARTUP=True
With settings file:
# FoxDot/lib/Settings/conf.txt BOOT_ON_STARTUP=True
With code:
Server.boot()
With IDE:
Type
Ctrl-b(#34)
Adjusting
NameError: name '_' is not defined(#48)Adjusting
Samples.loopsto reflect theSamples.addPathAdjusting and documenting the
Player.mapmethodAdjusting visual feedback, with
Player.bang()Fix to load startupfile even with
RECOVER_WORK=False(In the FoxDot IDE)Mapping unused samples
Now the characters
,_;` point to samples.d0 >> play('_...') # Hangdrum d1 >> play('..;.') # Perc d2 >> play(',', dur=4) # I Love You
Updating and correcting Sonic Pi extension.
0.9.0 - 2025-06-07¶
Added support for Python >3.11, dropping support for earlier versions.
0.8.*¶
Added
stretchsynth for timestretching samples, similar toloopbut better and only plays the whole file. Stretches the audio’s duration to thesusattribute without affecting pitch and does not require the tempo to be known.# Stretches the audio to 4 beats without affecting pitch p1 >> stretch("Basic_Rock_135", dur=4)
0.7.*¶
Add
.reload()method forloopplayer to reload the file used, in case it has been overwritten.Update
PlayerKeyclass (things likep1.degreeetc) to behave better withmapandtransformAdded
transformmethod to PatternsFixed
.pycfiles showing in the tutorials menu - you may have to uninstall and reinstall to see the benefitImproved in-house synchronisation between FoxDot instances.
Add
PDeltapattern; user supplies the step sizes between each value.Negative
offbeatfix (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--startupflag like so:python -m FoxDot --startup path/to/my_startup.py
Fix
MidiInmissing Synth bugImproved clock timing. If the user is not using a
varfor 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 by simply usingClock.sync_to_espgrid()(experimental).Added
Go()function to run FoxDot code from within normal Python programs.Added
infvariable, which can be used as a duration in anyvarobject to continually use a value once it has been reached e.g.var([0,1],[4,inf]). This can be combined usefully with a specialvarobject callednowwhich starts the timing cycle for avarat the current time in the clock:d1 >> play("x-o-", amp=linvar([0,1],[8,inf], start=now))
(Experimental) Added
Cyclepattern type, which can be used in conjunction witheveryto more effectively iterate over different values used for different calls to the same method. For example, you spreadstutterover 3 beats in one call, then 2 beats in the other, you would have to use avarlike so: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:
d1 >> play("x-o-").sometimes("stutter", dur=Cycle([2,3]))
Fix
Pattern.offlayerwhich is similar tooffaddbut 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.# 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
.versionfile insetup.pyand add extension packagesVRenderandSonicPi.Update
Sonic-Piextension to work with Python 2.Change
Clocktime measure data type tofloatinstead ofFractionto improve efficiency but sacrificing accuracy.Add
RandomGenerator.set_override_seedthat 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)andDefaultServer.stopRecording()to record audio from SuperCollider. Files are recorded intoFoxDot/FoxDot/rec/directory. Iffnis 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 PyPIFixed attribute access for
Pvarwhich allows for operations combining other patterns.Fixed bug caused when using Python 2 and slicing
Patternwith no supplied end value e.g.PDur(3, 8)[1:]that would create giant arrays and raise aMemoryError.Added autocomplete prompt (work in progress).
v0.7.1 fixes and updates¶
Improved
PlayerKey.mapmethod e.g.p1.pitchto only return one value instead of a PatternImproved
Clock.clearto make sure Players don’t reset and continue playing, which sometimes happenedUse
floatinstead ofFractionfor 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
VRenderextension, thanks to mathigatti, that allows users to add synthesised vocals. Requires Python modules MIDIUtil and urllib and musescore (Linux/Mac only). See the README 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
susandblurissues when using a different tempo.Improved timing on
Playermethod calls that send extra OSC messages, such asstutterandjump.Renamed
Patternmethodpipetoconcat. Also improved efficiency of this method as well as makingPattern.append()much more efficient (useful to adding items to aPatternfrom a loop.
v0.6.9 fixes and updates¶
Changed the behaviour for composing events sent to SuperCollider. When several
PGroups with different sizes are used, events are now the size of the largestPGroupas 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:# 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
blurto SuperCollider such that using an effect such aschopthat makes use of the sustain value no longer relies onbluras well:# 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 runFoxDot.startin 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, andrarelymethods that wrap theeverymethod but use random durations to decide when to call a method:# 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
quantiseto start playing as soon as possible when set toTrue. Defaults toFalsesuch 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
drivekeyword
v0.6.6 fixes and updates¶
Added
jumpmethod toPlayerclass: plays an event one step early (can be specifed by usingaheadkeyword) using keyword arguments to specify how the event is played.d1 >> play("x-o-").every(7.5, "jump", cycle=8, sample=2, delay=var([-0.25, 0],8))
Added
pentamethod toPlayerfor quickly switching between pentatonic scales. No arguments turns it on, 0 orFalseturns it off.Added
alt_durmethod toPlayer. This is an alternative way to set the duration of a player, mostly useful if using alinvaras a duration. When durations change, the clock position is recalcalculated - so using alinvarcauses many of these calculations to be made and can lead to delayed messages to SuperCollider. This method manipulates thebpmattribute 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, andextendmethods forPatternclass. These can be looped and used with theeverymethod.Experimental - Added CPU usage menu. Going to
Language->CPU Usageyou can choose low, medium, or high (default) level of CPU usage which is derived from the number of cycles theClockmakes each second. Each CPU usage step is 10x more than the previous. Currently this value resets between uses of FoxDot.Fixed
setup.pyto load description from the README.md file
v0.6.5 fixes and updates¶
Added option to duplicate a line of text using
Ctrl+Dshortcut.Added
Ctrl+Shift+Directionshortcut 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 for these.
Add ability to add “swing” to the
Clockusing avarobject 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
FoxDotcommand.
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=4means 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
MidiOutSynthDef (to be re-namedmidiin future) and aClock.midi_nudgevalue that can be set to help synchronise FoxDot with an external MIDI synth. A value of around 0.15 - 0.25 is typical.# 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
playSynthDef. This can be done from the play string by using the bar character in the form|<char><sample>|. These can also be patterns: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
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: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
cyclekeyword:# 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
TimeVaralgorithm and addedsinvarclass, which is a subclass oflinvarbut 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
TimeVarefficiency and can correctly handle the use ofGeneratorPatternas 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
linvarfor 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:
p1.reset() >> pads([0,2,4], dur=1/2) ~p1 >> pads([0,2,4], dur=1/2)
The
resetalso 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
GeneratorPatternindex behaviour.Improve
Playerefficiency; 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
stuttermethod no longer updates the internal “key” so improves efficiency when using it.Better handling of delays in
offaddandofflayerpattern methods
v0.5.8 fixes and updates¶
Fixed panning issues on many SynthDefs so
fmodspreads a signal across 2 channels effectively.Added the ability to use
Patternmethods on player attributes when using theeverymethod:d1 >> play("x-o-o", dur=PDur(5,8)).every(4, "rate.offadd", 2)
Improved
everyto 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
--pipeflag is compatible with Python 2Updated the “pads” SynthDef
Old unidirectional server manager class can be used by editing config file.
v0.5.5 fixes and updates¶
Fix
TimeVarclass so it no longer inherits fromRepeatablei.e. no longer has access to the “every” method.Fix pattern bug when creating a pattern using the
Pgenerator;P[P(0,2)]no longer returnsP[0, 2]. However,P[(0,2)]is interpreted exactly asP[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)
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
--pipeflag (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
pitchandcharwill return a player’sdegreeattribute.Player Key behaviour improved. Using multiple conditions e.g.
4 < p1.pitch < 7will hold the value 1 whilep1.pitchis between 4 and 7, and a 0 otherwise. These conditions can be “mapped” to values other than 1 by using themapmethod to map values, or results of functions, to other values/functions (which are applied to the values):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.everymethod can now takePatternmethods, which affect the degree of thePlayer(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.p1 >> play("x-i-").every(6, "amen").every(8, "palindrome")
v0.5.2 fixes and updates¶
Improved behaviour of
TimeVar,Pvar, andPvarGeneratorclasses when created via mathematical operators.SynthDefs can be read loaded into FoxDot from SuperCollider using the
FileSynthDefandCompiledSynthDefclasses (seeSynthDef.py).DefaultServerinstance has aforwardattribute that, when notNone, sends any outgoing OSC message to. Example:# 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
PGroupwithin a sequence is extended when zipped with another instead of nesting it. e.g.# 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.# 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:
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.nudgevalue to a small value (+-0.01) until the clocks are in sync. Now whenever you change theClock.bpmvalue, 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.degreein this example).Added
futuremethod. Likescheduleit 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
stopmethod properly removes the player fromClock.playinglist.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.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.
GeneratorPatternnewmethod converts theotherargument to a Pattern so you can use lists/tuples as opposed to just Patterns/PGroups when performing operations e.g.PWalk() + (0,4).Fixed
newlinemethod 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_callingis nowPlayer.never. If aPlayeris calling its own method (implemented by theeverymethod e.g.p1 >> pads().every(4, "reverse")you can now stop the repeated call by usingp1.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
everymethod with the same method name can be used together by specifying anidentkeyword, which can be any hashable value i.e. a string or integer.# 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_modifunction to test forTimeVarinstances instead of trying and failing to index their contents so thatTimeVar’s with strings in their contents don’t get into an infinite recursive call.
v0.4.11 fixes and updates¶
Removed
sys.maxintto conform with Python 3
v0.4.10 fixes and updates¶
Fixed negative pitch bug
PGroupModreplacesPGroupStarwhen using square brackets in a “play” string. This “flattens” the values so that many nestedPGroupsdon’t create exponentially larger loops when sending events to SuperCollider.Fixed
stutterso that delays caused byPGroupsare no longer lost.PRand,PwRand, andPxRandchoose from a random index instead of a random element so that any “nested”GeneratorPatternsgenerate a new item instead of returning the same one i.e. at index 0.Fixed
Player.degradeslidedelaydefault value changed from 0.75 to 0Replaced “Control” with “Command” for menu short-cuts on Mac OS (Thanks ianb)
Improved documentation layout
Player methods such
shuffleno longer affect the text of aplayPlayer 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
GeneratorPatternand usingvarin Player methods.Random
GeneratorPatternobjects, such asPRandcan take aseedkeyword 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
delayargument but works with the following event)# 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
PRhythmtakes a list of single durations and tuples that contain values that can be supplied to thePDure.g.# 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
audioinSynthDef for processing audio from the default recording device.Fixed bugs relating to chaining multiple
everymethods and ending their call cycle when the parent player is stoppedImproved 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:# 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,pshiftinto 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_delayandfunc_delayclasses.Using a
TimeVarin a pattern function, such asPDur, now creates a time-varying pattern as opposed to a pattern that uses theTimeVar’s current value. e.g.>>> 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
TimeVars as it only creates a new onceTimeVarwhen the addition is done.Improved usability of
PlayerKeyclass, 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
everymethod more consistent rather than just starting the cycle at the next bar.
v0.3.5 fixes and updates¶
In addition to
P*,P+,P/, andP**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, andP**shuffles the order the values are delayed.Added
PWalkgenerator pattern.TimeVars are easier to update once created.
# 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
sleepfrom 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 soClock.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 useScale.default.semitones()to generate semitones from the current scale.
v0.3.3 fixes and updates¶
Added a new
Patterntype data structure called a P-Star orP*. It is a subclass ofPGroupbut 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.# 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
stuttermethod like so: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
linvaras the Clock tempo will no longer crash the Clock.New effects have been added;
shapewhich is a value between 0 and 1 (can be higher) that relates to a level of distortion, andformantwhich is a value between 0 and 8 and applies different formant filters to the audio.hpfandlpfhave resonance values now:hprandlprYou 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¶
PlayerKeydata type can handlePGrouptransformations without crashing, which improves performance when usingfollowPlayerKeydata type greater than and less than functions fixed and now works with amplitudes.Better handling of scheduled functions that are “late”
Experimental:
playSynthDef can have a rate of -1 to be played in reverse and also uses a keywordcoarsesimilar in function tochopAdded
Patternmethod, 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¶
TempoClockuses astart_timevalue that, when used on multiple instances of FoxDot, should synchronise the timings. This is a work in progressAdded a “use SC3 Plugins” tick-box on the “Code” drop down menu to allow for easier configuration
pianoSynthDef added using th SC3 Plugin “MdaPiano”
v0.3 fixes and update¶
vartype can be used with Playerdelayand nested groups in theoctattribute.Increased
TempoClocklatency to 0.2 seconds for improved performance.Better handling for auto-completed quotation marks
v0.2.11 fixes and updates¶
Caught
ImportErrorif the user does not havertmidiinstalled.Improved
Player.stutter
v0.2.10 fixes and updates¶
New SynthDefs added. Use
print(SynthDefs)to view.Improved timing in the
TempoClockclass 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 Samplesfor more information.Sample Player argument,
scrubremoved. You can now useslide/slidefromandvibas you would do with a normal Player object to manipulate playback rate.Patternclass now has alayermethod that takes a name of aPatternmethod as its first argument and then arguments and keyword arguments for that method and creates a pattern ofPGroupswith their values zipped together.>>> 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
PGroupbehaviour added for players. Each value in eachPGroupin an event relates to the values in any otherPGroupin the same index, even if that value is also aPGroup. This concept is better described through an example: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.
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
cycleargument 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"andRoot.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¶
PDuradded: a pattern that implements Euclidean RhythmsPlayer attributes can be manipulated using the
Player.everymethodErrors caught and displayed in FoxDot console instead of crashing
Can set different tempi for Players using the
bpmkeywordSample 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, androtatemethods forplaySynthDefSC3 Plugins disabled by default
Player Object dictionaries shallow copied before iteration to stop
RunTimeErrorsoccurring
v0.2.0 fixes and updates (4/12/16)¶
Reorganised project structure. Samples and code are kept separate.
SuperCollider
OSCFunc.scdnow found in/osc/foldersetup.pynow included for an easier install(in progress) characters can have more than one sample attached to them. These are accessed by supplying a
bufkeyword argument.Python lists can be interpreted as FoxDot pattern when attached with a P prefix e.g.
P[1, 2, 3] + [0,2]will returnP[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
bangmethod and take Tkinter tag_config keyword arguments.Consolas now default font
Fixed
Pvarandlinvarbugs
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
varobjects for Player durations no longer crashesNew Pattern types added
FoxDot can be run using
python -m FoxDotif FoxDot is in your PATH
v0.1.6 fixes and updates¶
Decimator (a.k.a. bitcrush) added to default SynthDef behaviour
SynthDefsandBufferManagercan be reloadedRemoved 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_playerSynthDef
v0.1.3 fixes and updates¶
Key bindings for Linux, Mac, and Windows 10 fixed
Fixed freeze on keyboard interrupt exit