Question about analyzing/emulating a specific sound.

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

First of all I think I should say that don't know much about DSP development, I just find it so darn interesting - so please be gentle with me if stupid questions occur :-)

I'm wondering about how to analyze and simulate specific characters of a sound. Let's say I want to make a plugin that emulates a specific old preamp ( :-o how original :roll: ), I run some testtones through that unit and then compare the result to the original sounds. This seems to be a process suggested a few places. How is that done?

- what's the process?
- What tools are used?
- What to analyze exactly?
- How to translate that analasys to an effect.

I know this is probably not something that can be answered easily, and there's probably many ways of doing it. I'm just trying to get some kind of overall idea....right now I'm just plain clueless. :help:
|| Less is more than more less - I'm not sure whether less is less than less more ||

Post

The simplest way to start is by measuring impulse responses. If you don't know what an impulse response is, I would suggest reading up on FIR filters before continuing.

Anyway, here's some good first steps.

Set up your recording rig without the pre-amp. Send a bandlimited impulse down the line (a sinc wave - sin(x)/x)) and measure the impulse at the other end. This will give you a baseline measurement.

Hook up the pre-amp. Set the gain fairly low so that you're not clipping (I know, I know - the clipping is what gives it good sound. but we're trying to avoid non-linearity). Measure the impulse response. Deconvolute with the baseline impulse reponse to get the impulse reponse of just the pre-amp.

Make an FIR filter with the impulse response as its coefficients.

From here on - it's all intuition and luck. You could try upsampling the signal, run the gain up high and then clip it, then run it through the FIR filter (you'll have to adjust your coefficients for the higher sample rate!) and then downsample.

Good luck!

Post

Yeah, what benski said :)
Karel Bassez
Software Engineer
Vienna Symphonic Library GmbH

Post

Another simper way is to use an impulse, which is one sample at full volume. You probably won't get as good results by using this method compared to using the method that Benski suggests, but it is perhaps easier to understand.

If you have a system (e.g. an EQ), you can analyse it and characterise it. The system is, to all intents and purposes, a black box that gets input signals and transforms them into output signals.

Think about the most basic signal you can have - a perfect sine wave. A sine wave occupies a single frequency. This is a very useful property, since we can use it to probe a system and find out what it does at different, specific frequencies.

Some (perfect) systems have special properies. In the DSP world, a the most useful properties to discover about a system are if it has:

> linearity
> time invariance
> sinusoiodal fidelity

If a system has sinusoidal fidelity, it means that a sinusoidal input of a specific frequency will give an output at exactly the same frequency. An example of a system that violates this rule is a distortion module (which tend to add harmonics and are non-linear). Another example is a pitch shifter.

If a system has time invariance, it means that no matter what time you apply a signal to the system, the output will always be the same for the given signal. An example of a system that violates this rule is a phaser that incorporates an LFO.

Linearity of a system means that if you modify an input signal by a specific volume, the output would correspondingly be adjusted by the same percentage adjustment (assuming that the system has had time to settle since the volume adjustment).

You have to admit that these properties are quite unique amongst the range of possibilites of modification that our hypothetical black box could perform.

Why are these properties important?

Convolution!

Convolution is a mathematical function, represented by *. This symbol means multiply on a computer, but in mathematics is actually the symbol for convolution, and represents a number of operations. Convolving a single number with another is simply multiplication. If more numbers are involved, it is a lille bit more complicated, but not much.

What the hell is it?

Think about the special properties of a sytem that I mentioned earlier. What happens if you put one sample of data through the system? what can happen to it? it might change volume (positive or negative) and it might be shifted by a FIXED interval in time.

It may do this a multitude of times for the one sample. If you record this response by the system, you have the IMPULSE RESPONSE. As the name suggests, the response from the system to an impulse. Because of the property of LINEARITY, we can apply this response to ANY sample that we may have - it will simply be a SCALED version of the impulse response.

An example of this is a reverb - you wouldn't expect the response to get louder as the impulse got quieter, would you? It would also sound th same, but at a different voulme, regardless of when the impulse was fired.

As it happens, this is fantastic news, as each sample in the input can be treated totally independent from any other sample in the input! i.e. we have decomposed the problem into a number of smaller parts.

For example, imagine the sum 345 + 789. I bet you added each digit individually to get the answer, 1134. This is essentially what convolution does. you add together all the impulse responses that you would get from each individual sample, to get a replica of the system you recorded the impulse response from.

So, basically, if you know what the impulse respone of a linear, time invariant system is, you know EVERYTHING about that system, and can replicate it exactly!

Of course things are not that easy. In the real world, things are not perfect (which is partly why they sound good). Many systems have regions of input level where they are roughly linear, so we can make a reasonable approximation with convolution. Some systems like compressors are hopelessly non-linear.

For these systems, there are dynamic convolution techniques. I don't know how they work, but I reckon they can only be interpolated approximations, covereing only a small propotion of the possible state space for the systems.

The other problem is that convolution requires a rediculously large amount of CPU power - if you can imagine how many multiply-add instructions are required if you are multiplying each samle in an input by, say, 4096 impulse response samples. For a 44.1KHz wave, that would be 180,633,600 multiply-adds a second! not to mention the time it takes to load registers etc.

FFT convolution is one solution, since the convolution is done in the frequncy domain. This vastly reduces the CPU time required for large impulse responses (e.g. reverb), but increases latency somewhat because of the FFT block size.

Partitioned FFT convolution improves latency, but unfortunatley Microsoft have patented it. I don't know how, since it is virtually as fundamental as multiplication, and people were already doing it! Imagine patenting the Add operation? Insane.

Post

:-o Holy moly! :hail:
I must say....i really appreciate your replies Benski & Texture. (And your important confirmation Antipro :-)) This is heavy stuff, and I think i need some time to read this a few times before making any futher questions. Still think its darn interesting though.

I'll be reading up on your answers, but please do post again if you have anything to add. I'll be here for some time.

The doctor now returns to his studies.
|| Less is more than more less - I'm not sure whether less is less than less more ||

Post

here is a very simple (and unoptimised) brute force convolution algorithm:

Code: Select all

/*-----------------------------------------------------------------------------------------
** Function:  doProcess
** Returns :  Nothing
**
** Notes:
** Buffer must be of a size that is a number packed with 1's from the most 
** significant to the least - i.e. is a base of 2 raised to a power, minus 1. e.g. 0x7F
** The buffer size is used as a mask for its rolling counter. 
**
*/

inline void
ConvolverFX::doProcess(const float* in, float* out)
{
	uint32 i;
	
	old_inputs_buf[m_uiBufpos++] = *in;

	*out = 0.f;
	
	for(i = 0; i < BUFSIZE; i++) {

		*out += impulse_buf[i] * old_inputs_buf[(m_uiBufpos - i) & BUF_MASK];	
	}

	m_uiBufpos &= BUF_MASK;
}
This should only be used for very short impulses!

Post

Feelgood -

texture's & my approach are basically identically. An FIR filter is a form of convolution.

texture's explanation is dead-on perfect. However, I'll try to add some simplifications since it appears you're just getting started into DSP.

Convolution is a process that takes two signals and outputs the common portions of both. If a frequency component is present in both signals, it appears at the output. If a frequency component only appears in one signal, it does not appear at the output.

Because white noise contains all frequencies, it is the "identity" signal for convolution. If you convolute any signal with white noise, you get the original signal back. Even better, if you process white noise, and convolute a signal with the processed white noise, the "processing" gets transferred onto original signal.

An "impulse" is just a shot of white noise. It is the shortest burst of white noise that is possible to make. In the digital world, this is one sample at 1 followed by many samples at 0. In the analog world, you can think of an impulse as the noise your speakers make when you turn off the amp (or turn off the mixer, or other peice of equipment). I'm sure you've experienced this noise. It's sort of a "pop".

So when we take the "impulse response", we are basically inputting a pop of white noise and then measuring what comes out. What comes out is the "processed" white noise, which as I mentioned above will transfer the processing onto the other signal during convolution.

An FIR Filter is a common/easy way to implement convolution. If you've taken math classes, an FIR Filter is the dot-product of the impulse samples and the samples of the signal you want to process. You treat the stream of signals like a vector. If you sample the impulse, the digital samples become the "coefficients" of the FIR Filter.

Don't know if this explanation is any clearer - just trying to take another shot at things =)

Post

hey benski
I'll try to add some simplifications since it appears you're just getting started into DSP.
... :oops: its that obvious? :D well, im glad its out in the open i think i really needed the simplifications. Your last post speaks more to my current level of understanding, and gave me some good starting pointers. So thats exactly the kind of duh! :roll: beginner stuff im looking for. thanks a lot.

im a bit short of time right now. so no futher from me right now, but I'll be back.

To you texture - also a lot of thanks :) . Nice that you bother to take the time to demonstrate some code. It's been copyed and pasted to my future home studies. it's still a bit to complicated for me to grasp at this point.
|| Less is more than more less - I'm not sure whether less is less than less more ||

Post

bear in mind that the code is not a prime example of well coded dsp.

Post Reply

Return to “DSP and Plugin Development”