CamillaDSP - Cross-platform IIR and FIR engine for crossovers, room correction etc.

I've been into just following and looking mode for a while :)
Using CDSP on my main stereo for quite some time now.
There have been some update's, and following the github mailinglist is allway's interesting.

Thank's for having my SuperPlayer-v8.0.0 on your'e README Henrik, appreciate that.

When i was driving (well at bicycel) from work today, i was thinking if it is possible to add "controlled" harmonic distortion to the CDSP pipeline somehow?
Would be very interesting to have this possiblilty, well at least for me it would be.
I've been reading about it, and it seems to be doable, adding say 1% 2H distortion on digital domain... could be veeery cool :cool:

Jesper.

(I know that @phofman allready did some stuff adding "anti" harmonic to make his testgear go lower dB wise, cancheling out the soundcard's own distortion) But this is another story.
 
I'm not really against adding a tube emulation filter, could be a fun thing to have. I already have the compressor which isn't exactly transparent ;)

I have read that a little bit of "nice" distortion can help to make the sound less full when listening at lower volume levels. I spent a few hours exploring this a few years ago. It was a very simple test, adding a little x^2 and x^3 to the original signal x. The results were very disappointing! I never got anything that sounded nice. Too little and I couldn't hear any difference. Adding more until I could hear it just made it sound bad.

My conclusion then was that it takes a much more complicated model to emulate the tube sound. I haven't investigated further, but if someone finds something on how to build a suitable model I would appreciate a link :)
 
Hi...

I was not thinking of a dedicated "Tube" sound filter before @TNT mentioned this :)
I think this would be a very tricky thing to do, and you are right it seems that there are none models out there? (easy to find that is)
I have my 300B amplifier, and my speaker's have a dedicated impedance filter to use with tubeamps. - But i dont use this amp. much as i like my AlephJ scaled down amplifier better (Well sound is not better Tubeamp. / AlephJ, but different)
I also read somewhere that it's not just the harmonics, but also the impedance vs. speakers who gives the tubey sound, i donno, but sound right to me.

If it's a good idea or not to have a harmonic "plugin" in CDSP i can't tell, but anyway @HenrikEnquist - Is it easy to create such harmonic generator you mention ? - Or can you tell me how you did your'e test ?
I would like to try it out!

Jesper.
 
As Henrik mentioned static harmonics are generated by tweaking the transfer function from a linear line to polynomial. sin^2(x) yields cos(2x) component, sin^3(x) yields sin(3x) etc - multiples of x are the created higher harmonics. Good examples are Chebyshev polynomials, e.g. https://en.wikipedia.org/wiki/Chebyshev_polynomials#First_kind which add exact harmonics for exact sine signal normalized to 1.

A simple octave/matlab code for adding specific harmonics to single-tone sines are at my distortion compensation POC https://github.com/pavhofman/nonlinear-compensation/blob/master/octave/run_distortion.m https://github.com/pavhofman/nonlinear-compensation/blob/master/octave/genDistortPoly.m . But the distortions are added at correct scale only for single-tone signals, that's how the Chebyshev polynomials are defined.

Another option is creating static harmonic (anti) distortions with a piecewise polynomial applicable to range <-1, 1> https://github.com/pavhofman/nonlinear-compensation/blob/master/octave/run_polycompensation.m where the piecewise polynomial is calculated by nonlinear regression between distorted and non-distorted signal https://github.com/pavhofman/nonlinear-compensation/blob/master/octave/ctrl/clbkPolyCompensate.m#L75 - that generates the piecewise polynomial pieces and their coefficients. So the code for applying the static distortion is simple, the (much) more complicated question is determining the polynomial itself.

BTW ESS chips use the very same principle for their distortion compensation - the DACs allow configuring coeffs related to second and third polynomial terms, the ADCs allow to define 64 interpolation points in range of <-1, 1> which construct a new static transfer function (these points must be pre-calculated in advance, many methods possible).

A filter in CDSP could easily replace any compensation in ESS chips, or offer the same feature for any DAC/ADC.
 
Last edited:
  • Like
Reactions: 1 user
@phofman ... Nice !
I did read some of the threads, regarding the harmonics cancellation some time ago, very interesting stuff. Well not understanding all of it through.
I only suggested to have a harmonics filter possibility, inserting this in the pipeline as usual to see/hear if it could be an idea?
I also had the thd cancellation in mind when i posted this to be honest.
The CamillaDSP engine could then be a part of my measurement chain :)

But okay maybe this is better to keep seperated i see ofcause.

Anyway, not to spoil the thread anymore, are there some hints or links where to start if i want to try adding distortion to some music/sines or like?
I really dont know howto or where to start?

Jesper.
 
Anyway, not to spoil the thread anymore, are there some hints or links where to start if i want to try adding distortion to some music/sines or like?
I really dont know howto or where to start?
I'll check if I still have my old script. I simply read a .wav, added some x^2 and x^3, and then saved to a new .wav. I don't remember if I used python or Matlab. Give me a few days, my computer is in a moving box at the moment..
 
  • Like
Reactions: 1 users
Adding a x^2 or x^4 harmonic will in many cases "improve" the sound, there is research done proving this but MIND THE PHASE!!
Imagine you have a midrange with x^2 harmonics, AND you have a tube pre amp with x^2 distortion.. either the distortion adds upp or they cancel out!!

So if you are doing listening tests with even order harmonics you have to be aware of the phase.
Nelson Pass has a cheap H2 generator that can be equipped with an inverting stage. So depending on the distortion from the waste amount of recording equipment, your own gear and the speakers ,it may be good a idea to do some own evaluation here, if positive or negative phase of distortion is needed...
 
The computer that maybe has the old script is still in a box, but I made a new Python script. I have only checked that 16-bit files work. I think that 32 bit files should work too, but I suspect that if will fail badly on 24-bit files.

Modify the "nonlinear" function to add change the type and amount of distortion it adds. Python uses ** instead of ^ for power, so data**3 means the data cubed.

The script needs python 3.x with numpy. Just save the attached file, remove the .txt file ending, and run it with
Code:
python add_dist.py infile.wav outfile.wav
.
 

Attachments

  • add_dist.py.txt
    1.6 KB · Views: 60
A note on tube amulation and waveshaping
http://www.simulanalog.org/tubestage.pdf shows how a tube not only generate harmonic distortion due to compression of steady state signals, but also introduce harmonics on transients due to shift i bias point. So the tube data model is quite comlicated.
There is also a warning on aliasing when generating harmonics digitally on other websites

But of cource, nothing wrong with experimenting with harmonics;)
 
So the ESS compensation just wrk for one tone? THD bragging rights but not really relevant to music?
Look at ESS H2 compensation measurements https://cdn.shopify.com/s/files/1/0321/7609/files/DAC3_-_2nd_Harmonic_Compensation.GIF?v=1478880997, and at my results for a different DAC/ADC
https://www.diyaudio.com/community/...ion-for-measurement-setup.328871/post-6532409
https://www.diyaudio.com/community/...ion-for-measurement-setup.328871/post-6536105


They show the level of distortion improvement over frequency and level ranges for static-distortion compensation (using a polynomial). The coeffs must be calculated at some level and frequency - if you compare charts for compensation calibrated at 211Hz and 911Hz https://www.diyaudio.com/community/...ion-for-measurement-setup.328871/post-6536105 , they are not very different. That's the characteristics of static distortion - it is not very dependent on frequency within some reasonable range. At higher frequencies dynamic distortions take over and the effectiveness of subtracting harmonics at fixed phases produced by the polynomial (H2: sin^2(x) => -cos(2x) = -90deg, H3: sin^3(x) => -sin(3x) = -180 deg, etc.). IMO the static distortion compensation calibrated at some reasonable frequency and level is relevant to any signal. Clearly seen e.g. on the improvement of multitone at https://www.diyaudio.com/community/...ion-for-measurement-setup.328871/post-6536105 .

It is audible? Not me to answer :)
 
  • Like
Reactions: 1 user
Hi all...

To see if it was working, i created some sine's with "no", "low" and "high" distortion to see what would happen.
Script is working for sure :)

Something to play with is allway's nice to have!
Will listning to some tune's eventually.

NO or less dist. as @HenrikEnquist had in the script default.
def nonlinear(data):
result = data + 0.01 * data**2 - 0.01 * data**3
return result

Sine_NO_DISTORTION.png



LOW dist.
DIST-LOW.png



HIGH dist.
def nonlinear(data):
result = data + 0.2 * data**2 - 0.2 * data**3
return result

DIST_HIGH.png


Jesper.
 

TNT

Member
Joined 2003
Paid Member
How do I start a new clean (empty) config file using the GUI?

//
No one?

Syat hat I have a running configuration with a lot of filters etc and wanted to prepare a new simple config for later. I could modify the existing and do a save under a new name but it would require a lot of deleting of filters etc..

How do I in this situation start off with a clean configuration?

//
 
No one?

Syat hat I have a running configuration with a lot of filters etc and wanted to prepare a new simple config for later. I could modify the existing and do a save under a new name but it would require a lot of deleting of filters etc..

How do I in this situation start off with a clean configuration?

//

Make an empty config. Load it. Then add to it?