-
Notifications
You must be signed in to change notification settings - Fork 404
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request: .scl / .tun Retuning #828
Comments
Oh that’s a really cool idea. The key to frequency code is fairly well isolated so it wouldn’t even be that tough Question : surge modulates pitch by semitones like with an lfo or whatever. Wonder if other synths bind their modulation to the scale or use base note in scale space and frequency modulation in even temper space. Obviously base note in scale space and frequency modulation in even temper space is way way easier! |
The synths I've worked with keep modulations by semitones. |
One other question: do you think we should have tuning per osc, per scene, or per patch? I can make all the arguments but interested how other synths do this. |
I'd go by scene or patch; loading somethings for each oscillator seems tedious. |
So OK here's some notes on this issue
So to do this the work is basically
The tricky part is the moving of the table. Sort of a moderately nasty code refactor. But I kinda want to do this since I would learn a lot... so let me keep pondering a bit when and how to do that refactor. |
Makes sense, best of luck with the refactor. |
Thanks! And yea it would! But doing it accidentally because memory is shared is not the way to do it :) |
Huh that refactor wasn’t as bad as I thought. Just managed to make it work on a branch. I’m interested in understanding this so may add this to my list for Sooner rather than later Thanks for raising it |
By "this" do you mean the refactor/that part of the synth's inner workings? or the possibilities of retuning? |
The thing that was easy was the refactor The thing I am interested - and have been interested in for a while - is the inner working of alternate tuning systems So your issue has the wonderful combination of being code which isn’t a huge pita while also letting me learn about one of the things I want to know more about So basically: it sounds fun to add retuning to surge. And it also sounds tractable. So I will do it this spring. But probably not this afternoon :) |
So @bit-101010 I could use a favor. I worked on this tonight some with SCL files. The headless app can actually play one of the goldberg variations to a wav file no problem so I don't have to deal with UI and streaming patch stuff. And I got it working with alternate scales. (I only tried 12 note scales) Anyway this .zip file contains a standard midi file, a .scl tuning file, and the wav file that surge renders if it plays that midi file back with that tuning attached in my current branch. Is it possible for you to take a synth that you know to be a good renderer of midi with scl files and render out an audio file of it to see if we are doing the same tunings? I'm not quite sure how to test this but have been doing things like "printing velocities at the retune moment" and have confirmed that an .scl file with uniform tuning (so 100.0 200.0 etc...) doesn't change pitches and so on. Would very much appreciate anything you can do to confirm that other synths with this .scl file render properly though The branch is |
Hmmm one other thing you made me think. One of my rack modules is a quantizer. Now I know how this works I can make a VCV Rack module that quantizes CV to a .scl file step set also. |
I've had some ideas about that myself, but I've had trouble getting my Rack plugins to build. There is a whole world of tuning stuff that would make VCV rack even more powerful in my opinion. |
Ha! Well I linked the BaconPlugs issue to this one. Happy to chat on that issue tracker about ideas. It would be very very easy though to do something like my polygnome where you have a CV input and you output that CV plus A/B. So if you want like the dodacahedral scale I used above you could just dial in the 19/12, 1732/1874 and so on. Basically an in-rack .scl editor for N tones. But lets not spam up surge issue tracker with ideas for rack. Like I said happy to beat around ideas for those plugins. |
Just a note to self the table_pitch is calibrated as follows table_pitch[0] = 1 you get the idea. These are the distances in multiplier from 0 which is why my tuning worked. But which is the 'center' note. Well in a couple of places it is assumed the frequency is 16.3519783 * the table pitch. That means we are tuned such that 1 = C0. So if we want to tune to a 440 A constant and work our scales from there we need to make sure that note_to_pitch(57) = 26.9087 and then calibrate from there. Similarly if we want C3 constant then we need to make sure that well you get the idea. This explains why my tuning works but my offsets are off. Not fixing it now just writing down my research for myself. |
Your comments on slack were super handy; I've now fixed up my tuning and have it working. My current choice is to keep C3 = 261.626hz a constant and use that as note 0. How do other synths do it in absence of a KBM file? Is it an option (so "hold A3=440; hold C4; hold C3")? It gets weird when you chose a non-12-note scale too. Fun stuff. |
Probably not the best option given that multiple places assume a 16.3519783hz reference, but if you could make that value a variable, then you could just set it equal to the reference specified by the .kbm file. Then the fractions in a .scl file would translate directly to the values in the table. Start from the reference note and multiply up / divide down by the scale's formal octave (last degree in the scale) to fill it out. The cents-to-decimal calculations wouldn't be too bad to implement either. Without a .kbm file, you could just assume a reference note and pitch, but the implementations that I like let the user define those. For example, Zyn has parts in the GUI where you can set a reference even if you don't load a .kbm file. |
Great Seems that 48 constant selection is what I need to let people pick absent a Kbm file But what I really need to do is make it so you can try this and let me know if my implementation is ok! Maybe next week! |
Groovy! |
Yeah I will look at kbm files next now I have scl working. Fun! |
I'm now subscribed to this thread and happy to help test the .scl/.kbm implementation when it's available. @baconpaul do you still need someone to test that tuning.zip above? |
I think he has Tuning.zip testing under control (that conversation happened on the Surge Slack Channel). Whenever it does happen, it would be nice to have a tester with a good deal of retuning experience. Nice to have you on board, @SeanArchibald ! |
Yeah I ran out of time last week for other reasons the. Spent the weekend screwing around with vcv - this branch is mostly done. I’ll bring it back up the stack and try and get a beta into the nightlies |
Just a reminder to myself from slack: http://sevish.com/scaleworkshop/ |
This was super useful. I was just incorrectly transferring ratios to cents (duh), and also assuming a 2.0. So with my push if you use the sin oscillator I think it is tuned correctly. And if you choose a non-sci file you don't get a core. About 45 minutes until there's a new nightly. If you want to give a whirl next week that would be great. When I'm back I will look at the other oscillators and persisting the scale in the patch. |
1: The tuning file was mis-interpreting fractions to cents convrersion 2: The tuning file wrapping assumed 2/1 as a last note in one place 3: If you choose a non-scl file you pine for the fjords This addresses those, and moves us further along #828
Oh another feature we will need, when we save .scl in patches, is a menu item to "show current tuning file" |
Alright I don't have a fix but I have a diagnosis on the mistuned classic oscillator In the ::convolute method there's this code
where t is used to set the rate of the voice. In normal operation when this is called, detune and sync are 0; so this is reading the "note 0" which is the "pitch 1" point in standard tuning. Basically this allows the entire tuning to shift by a bit and tune across the keyboard. But this works remarkably poorly when you have a tiny scale like Q4.scl; at that point the "0" point (since the "48" point is held firm at 16) - then you read the super duper low frequency of the 0 point and apply that to your phase. I can fix this by assuming the '0' point is 48 and the 'pitch' value there is 16 as follows
You can see that re-centers the time to 48 as 16 rather than 0 as 1. And then the square wave oscillator on Q4 works just like the sin. but I am totally not ready to commit that right now. There's so much testing I would have to do that it's not prudent this morning. So I'll leave this comment here so I don't forget. |
1. The concept of "48" being the center and "16" being its pitch were hardcoded. Make those inline functions in storage (which right now just return 48 and 16) and use those in the retuneToScale 2. The Classic oscillator convoultion for Square and Triangle assumed that note 0 was pitch 1; whereas we know note 48 is pitch 16 and in regular tuning that is 2^(-48/12) lower. So adjust to use the center note as the convlution period time. All of this is a no-op if you are in standard tuning. Addresses surge-synthesizer#828
1. The concept of "48" being the center and "16" being its pitch were hardcoded. Make those inline functions in storage (which right now just return 48 and 16) and use those in the retuneToScale 2. The Classic oscillator convoultion for Square and Triangle assumed that note 0 was pitch 1; whereas we know note 48 is pitch 16 and in regular tuning that is 2^(-48/12) lower. So adjust to use the center note as the convlution period time. All of this is a no-op if you are in standard tuning. Addresses #828
As part of the feature request in surge-synthesizer#828, this begins to add alternate non-uniform tunings to surge. This commit is a good step along the way to the final feature set but is incomplete. With this commit, you can return a surge to an .scl file of your chosing, but you cannot load a kbm, cannot choose a center note other than C4/261hz, and the scl file you choose does not save into either the patch or the DAW and is transient. I am adding this commit, though, so that (1) users more experienced with tuning can test this in the nightlies, (2) I don't have to keep rebasing it forward and (3) I am guaranteed to get this feature properly into 1.6.2 Former-commit-id: 179cdb6686a9c9c123e3cc7cdf7fd642b496c647 [formerly ba855b9] Former-commit-id: 970e82d8eb4e17990bbd66a3d396829aa269e870 Former-commit-id: a895b7d0e107a76a6c7035071cd1768a5df1859c
1: The tuning file was mis-interpreting fractions to cents convrersion 2: The tuning file wrapping assumed 2/1 as a last note in one place 3: If you choose a non-scl file you pine for the fjords This addresses those, and moves us further along surge-synthesizer#828 Former-commit-id: da475014cda92b2b27bc919aeb56bdfb8529bc32 [formerly e8f992b] Former-commit-id: 10485a067909e3ba49e17e89cccb985acf1cdd31 Former-commit-id: a87946dde013c3c23a5fcb15b8f2086569db376c
1. The concept of "48" being the center and "16" being its pitch were hardcoded. Make those inline functions in storage (which right now just return 48 and 16) and use those in the retuneToScale 2. The Classic oscillator convoultion for Square and Triangle assumed that note 0 was pitch 1; whereas we know note 48 is pitch 16 and in regular tuning that is 2^(-48/12) lower. So adjust to use the center note as the convlution period time. All of this is a no-op if you are in standard tuning. Addresses surge-synthesizer#828 Former-commit-id: eb68e33df158bae9df35cbff3f8dc69e8c406748 [formerly 4ed615c] Former-commit-id: 021a547900483225cdb6a37e67e0756fa3560112 Former-commit-id: 582f2f327546cfa1cc1c7345d6f16e37b109baa9
Another “note to self” style comment as I get my part time summer music hacking organized. OK I think the actual tuning in the nightly is correct so here’s a note to myself on what needs to happen to have this be finished
If that all works then I will call “.scl file tuning done”. At that point I would open two more issues
Those 3 may get tagged 1.6.n not 1.6.2. I’ll see! |
1. The system knows if it is in tuning mode 2. You can see the tuning details (opens in a browser) 3. Menus work based on tuning state 4. Remove the experimental tag Addresses surge-synthesizer#828
1. The system knows if it is in tuning mode 2. You can see the tuning details (opens in a browser) 3. Menus work based on tuning state 4. Remove the experimental tag Addresses #828
Some features of the synth - notably, zoom, MPE Enablement, and Tuning - are features of the DAW environment you are working in and were not persisted. This fixes that by adding a dawExtraState section to the streaming protocol which is only populated and read at DAW time not at general patch time. Closes surge-synthesizer#890 Closes surge-synthesizer#914 CLoses surge-synthesizer#915 Mostly wraps up surge-synthesizer#828
Some features of the synth - notably, zoom, MPE Enablement, and Tuning - are features of the DAW environment you are working in and were not persisted. This fixes that by adding a dawExtraState section to the streaming protocol which is only populated and read at DAW time not at general patch time. Closes #890 Closes #914 CLoses #915 Mostly wraps up #828
This commit sets up a display of statuses in the synth so we can bring to the front thigns like MPE and Tuning and bind the menus more comprehensively. It also brings to bear the ability (optionally) to store a tuning in a patch and the correct state machine for what to do when loading a patch with tuning with tuning active. It almost completely addresses the remainder of surge-synthesizer#828 Addresses the streaming incompatability in surge-synthesizer#1035 Still outstanding is optionally a "lock" and to apply the streaming version option to FX (which is surge-synthesizer#1037) Handle streaming revision parameter set changes in OSCes. Deals with
This commit sets up a display of statuses in the synth so we can bring to the front thigns like MPE and Tuning and bind the menus more comprehensively. It also brings to bear the ability (optionally) to store a tuning in a patch and the correct state machine for what to do when loading a patch with tuning with tuning active. It almost completely addresses the remainder of #828 Addresses the streaming incompatability in #1035 Still outstanding is optionally a "lock" and to apply the streaming version option to FX (which is #1037) Handle streaming revision parameter set changes in OSCes. Deals with
OK with the push I did tonight .scl support works, is stored in the DAW, is optionally stored in a patch, has reasonable override semantics, shows its status in the UI, and tunes the keyboard properly, which was sort of the minimal viable tuning implementation. So to keep the 1.6.2 milestone chugging along, I added 4 issues with a “tuning” tag which are the work I would add in 1.6.3 probably, and am closing this one, since I think it’s now done! What a cool thing to add to surge. Thanks for suggesting it and thanks for all the help testing and designing the feature. |
I would like to see alternate tuning options for oscillators, and perhaps everytihng that does key-tracking.
The most common standards for retuning are the AnaMark (.tun) and Scala (.scl / .kbm) formats. loading these should change the frequencies of each MIDI note.
There are some open tools for doing this already:
There is some C++ source code provided by Mark Henning (creator of the AnaMark standard) for using both formats of tuning files, but it handles .scl files incorrectly.
ZynAddSubFx handles .scl files as expected, but doesn't load TUN files. Microtonal.h/.cpp handles this function.
In addition (this is a stretch goal, and maybe beyond the scope of this initial request) being able to load and blend between multiple scales would open up a world of harmonic possibilities.
The text was updated successfully, but these errors were encountered: