farbrausch demo tools open source
category: code [glöplog]
so the basic idea to optimize the thread safety is to find and capsule/modify absolute structs and make them use relative offsets for the instances instead? is that right?
i think i got it...
i think i got it...
v2 has lots of global variables.
never mind thread safety, even if you have just one thread you can't (easily) have multiple instances of it at the same time.
never mind thread safety, even if you have just one thread you can't (easily) have multiple instances of it at the same time.
global variables. absolute data. isn't it the same? doesn't it work if i'd make them relative for the instance and you have?
nonetheless... the greatest joy you'll have is running that 16 multitimbral channels as one instance.
this where i am. :D
nonetheless... the greatest joy you'll have is running that 16 multitimbral channels as one instance.
this where i am. :D
http://en.wikipedia.org/wiki/Global_variable : all about global variables. And some points of why they *can* be bad.
As ryg said, synth.asm has them in spades, which is part of the problem.
Rewriting libv2 removes that problem of extensive global var use, as it can then be redesigned to be more portable and usable in multiple instances of use. For instance, in my example, I can encapsulate libv2 in a C++ class, which alllocates its own memory, structures, variables and things, so it doesn't interfere with any others.
As ryg said, synth.asm has them in spades, which is part of the problem.
Rewriting libv2 removes that problem of extensive global var use, as it can then be redesigned to be more portable and usable in multiple instances of use. For instance, in my example, I can encapsulate libv2 in a C++ class, which alllocates its own memory, structures, variables and things, so it doesn't interfere with any others.
raizor_ : progress has been slow, namely due to me being working on and off on it, as well as other things. Not much has changed since I made a V2MConvertor class, since I remember working on my Flashback demos at the time.
All the global variables V2 uses are defined at the very beginning of the source file:
this resd 1
- Instance pointer. Used throughout the source. Needs to go into TLS or into a spare register (haha).
temp resd 16
- Temporary workspace. Can be put into instance memory
oldfpcw resd 1
- only used in synthRender and synthProcessMIDI. Can go onto stack.
todo resd 2
outptr resd 2
addflg resd 1
- only used in synthRender. Can all go onto stack, too
So the "this" variable is the only problem if you want to make V2 fully thread safe. Running multiple instances in one thread already works (disregard what ryg said, I rewrote that bit), and for "thread safety" the current workaround is wrapping all synth* calls into the same critical section. Hardly optimal, I know, but considering that V2 is taking about zero CPU nowadays it should work. :)
this resd 1
- Instance pointer. Used throughout the source. Needs to go into TLS or into a spare register (haha).
temp resd 16
- Temporary workspace. Can be put into instance memory
oldfpcw resd 1
- only used in synthRender and synthProcessMIDI. Can go onto stack.
todo resd 2
outptr resd 2
addflg resd 1
- only used in synthRender. Can all go onto stack, too
So the "this" variable is the only problem if you want to make V2 fully thread safe. Running multiple instances in one thread already works (disregard what ryg said, I rewrote that bit), and for "thread safety" the current workaround is wrapping all synth* calls into the same critical section. Hardly optimal, I know, but considering that V2 is taking about zero CPU nowadays it should work. :)
Also, I forgot the V2PERF module but you can safely turn that off. :) Oh, and patches welcome.
Quote:
So the "this" variable is the only problem if you want to make V2 fully thread safe. Running multiple instances in one thread already works (disregard what ryg said, I rewrote that bit)
at the very least the SR* stuff needs to go into instance memory too :)
what the hell, let's get this party started:
https://github.com/farbrausch/fr_public/blob/4e058e9c2a9784d4bec6cb94963a5ea775fbd768/v2/synth_core.cpp
contributions and/or patches welcome! :)
https://github.com/farbrausch/fr_public/blob/4e058e9c2a9784d4bec6cb94963a5ea775fbd768/v2/synth_core.cpp
contributions and/or patches welcome! :)
Quick patch:
line 25
should be
and line 32
should be
more patches welcome!
line 25
Code:
static sF32 float2bits(sF32 f)
should be
Code:
static sU32 float2bits(sF32 f)
and line 32
Code:
static sU32 bits2float(sU32 u)
should be
Code:
static sF32 bits2float(sU32 u)
more patches welcome!
ahem. touché!
;]
Oh I see ryg already ported the most difficult part :P - but seriously, throw these custom math functions away, they're mere optimizations and don't really affect the sound. Just use sin() and atan2(). Worrying about performance can always come later. :)
Also, don't try to emulate the weird bit/flag shiftery in the osc code. Find out what it actually _does_ (hint: there's a vid of my ASM2005 seminar somewhere) and replace it with a nice switch statement, as well as all the other jump table based code.
There's also a lot of custom float2int and int2float code around. Rule of thumb there is "the int value gets converted into a float between 1 and 2, or between 2 and 4". The formulas in the oscillator code actually make use of this; most other places are followed by a subtraction that pushes the value into the more convenient [0,1[ or [-1,1[ interval. So just ditch the weird conversion style, too, and replace it by casts. CPUs are fast enough at this now. :)
Also, don't try to emulate the weird bit/flag shiftery in the osc code. Find out what it actually _does_ (hint: there's a vid of my ASM2005 seminar somewhere) and replace it with a nice switch statement, as well as all the other jump table based code.
There's also a lot of custom float2int and int2float code around. Rule of thumb there is "the int value gets converted into a float between 1 and 2, or between 2 and 4". The formulas in the oscillator code actually make use of this; most other places are followed by a subtraction that pushes the value into the more convenient [0,1[ or [-1,1[ interval. So just ditch the weird conversion style, too, and replace it by casts. CPUs are fast enough at this now. :)
well i don't know about you but i'd like to make this thing bit-exact (on the 16-bit samples, not the intermediate floats, that would get tricky in C++), so i'm keeping all the ratty approximations :)
oh, posted the wrong link. this is the current working state :)
https://github.com/farbrausch/fr_public/blob/master/v2/synth_core.cpp
https://github.com/farbrausch/fr_public/blob/master/v2/synth_core.cpp
Ok, that's, uh... a "bit" more. o.O :)
Looks good so far after a cursory glance... but check syFltRender.process - the LRC filter is using 2x oversampling, too.
Looks good so far after a cursory glance... but check syFltRender.process - the LRC filter is using 2x oversampling, too.
thanks, fixed :)
I've been closely following Ryg's cpp conversion of V2 on GitHub. Looks like it's almost done :)
what does it bring? portability?
raizor, big caveat: as of yet completely untested. :)
my goals with this: (in rough priority order)
- get a more readable/easily hackable version of the v2 - kind of executable documentation. :)
- finally figure out how much of a win (if any) writing it in ASM actually was, in terms of size and performance.
- find out how much SSE(2) would've helped. :)
- be able to use v2 even in 64-bit builds. (this still needs some fix-ups though, there's some raw 32-bit pointers in the data, like the patchmap for instance)
- portability (hey, why not?) :)
my goals with this: (in rough priority order)
- get a more readable/easily hackable version of the v2 - kind of executable documentation. :)
- finally figure out how much of a win (if any) writing it in ASM actually was, in terms of size and performance.
- find out how much SSE(2) would've helped. :)
- be able to use v2 even in 64-bit builds. (this still needs some fix-ups though, there's some raw 32-bit pointers in the data, like the patchmap for instance)
- portability (hey, why not?) :)
ryg, quite a caveat indeed :)
I'm intrigued about the size difference too. A portable/hackable codebase will be great. Hopefully people will now extend V2 to add sample support and the other features that have been talked about for years.
I'm certain interesting things will surface from this. It will be an excellent resource for understanding the inner working of a synth and hopefully get a few more people involved in synth coding. If you ever decide to write a blog post about any of this, that would be fanstastic :)
I'm intrigued about the size difference too. A portable/hackable codebase will be great. Hopefully people will now extend V2 to add sample support and the other features that have been talked about for years.
I'm certain interesting things will surface from this. It will be an excellent resource for understanding the inner working of a synth and hopefully get a few more people involved in synth coding. If you ever decide to write a blog post about any of this, that would be fanstastic :)
hey guys... what about adding the "generator" and fr-08 file , to your pack?
IIRC generator contains code that we don't own the rights to (GUI/tool code that belonged to VCC Entertainment). that company is inactive (and has been for the past decade) but I believe it still exists and still holds the rights to that codebase.
hm... vcc?
http://www.sega-dc.de/dreamcast/VCC_Entertainment
that studio?
http://www.sega-dc.de/dreamcast/VCC_Entertainment
that studio?
Yep, that studio...