PCSX2 Documentation/Reverb Engine: Difference between revisions

no edit summary
No edit summary
No edit summary
Line 1: Line 1:
{{DocTabs|Section=2}}
==Introduction==
Introduction
I will try to explain here what I know of the SPU2's Reverb, which is practically identical to the one in the PS1. All my knowledge comes mostly form the great (but not quite accurate) document by Neill Corlett, and some pages I found online about reverberation and impulse responses.
I will try to explain here what I know of the SPU2's Reverb, which is practically identical to the one in the PS1.


All my knowledge comes mostly form the great (but not quite accurate) document by Neill Corlett, and some pages I found online about reverberation and impulse responses.
==The Reverb Engine==
The basis of the reverb engine is a standard Schroeder Reverberator. This reverberator is formed by four parallel Comb filters, taking data form four sample queues which are fed from the input. These filters are the source of the main echos, the first reflections of the sound waves coming from the walls of the virtual room. The mixed output from the four Comb filters passes through a pair of All-pass filters, which contain a sample queue each, and they feed themselves the data, causing a controlled feedback loop which multiplies the density of the echos, but reduces them in volume over time.


The Reverb Engine
==The SPU2 Reverb Engine==
The basis of the reverb engine is a standard Schroeder Reverberator.
 
This reverberator is formed by four parallel Comb filters, taking data form four sample queues which are fed from the input.
 
These filters are the source of the main echos, the first reflections of the sound waves coming from the walls of the virtual room.
 
The mixed output from the four Comb filters passes through a pair of All-pass filters, which contain a sample queue each, and they feed themselves the data, causing a controlled feedback loop which multiplies the density of the echos, but reduces them in volume over time.
 
The SPU2 Reverb Engine
Instead of having a series of separate queues, the SPU2 has a single rotating buffer and uses offsets to split this buffer into the queues it will require. The different blocks of the reverb engine will write to different locations of the buffer, which will advance on each processing cycle, and then data will be read from locations some samples away.
Instead of having a series of separate queues, the SPU2 has a single rotating buffer and uses offsets to split this buffer into the queues it will require. The different blocks of the reverb engine will write to different locations of the buffer, which will advance on each processing cycle, and then data will be read from locations some samples away.


While the data is eventually overwritten by other queues, it does not matter because the readers have already used the data while it was available.
While the data is eventually overwritten by other queues, it does not matter because the readers have already used the data while it was available. The reverb engine takes the data from the input lines (stereo), passes it through a configurable IIR filter, and puts it in the input queue. At the same time, the four comb filters take data from different points of the input queue, which is shared for all of them. The All-pass filters have their own queue each, and seem to match the standard design.
 
The reverb engine takes the data from the input lines (stereo), passes it through a configurable IIR filter, and puts it in the input queue.
 
At the same time, the four comb filters take data from different points of the input queue, which is shared for all of them.
 
The All-pass filters have their own queue each, and seem to match the standard design.


Pseudo-C Implementation
==Pseudo-C Implementation==
In the following code, Buffer represents the rotating buffer, which will be used using something similar to
In the following code, Buffer represents the rotating buffer, which will be used using something similar to


<source lang="cpp">
Buffer[x] === Spu2_Memory[ EffectsBufferBase + (EffectsBufferPosition + offset) % EffectsBufferSize ]
Buffer[x] === Spu2_Memory[ EffectsBufferBase + (EffectsBufferPosition + offset) % EffectsBufferSize ]
</source>
The Revb structure contains all the (wrong) register names currently used. If this implementation turns out to work correctly, I will change the names of those registers so they represent their actual usage.
The Revb structure contains all the (wrong) register names currently used. If this implementation turns out to work correctly, I will change the names of those registers so they represent their actual usage.


This is the current state of the reference implementation I used in an Impulse Response Analyzer I wrote:
This is the current state of the reference implementation I used in an Impulse Response Analyzer I wrote:


<source lang="cpp">
// Input filter
// Input filter
// Writes the data to the input queues for the echos below
// Writes the data to the input queues for the echos below
Line 111: Line 99:


return new StereoOut32( ACC0 >> 16, ACC1 >> 16);
return new StereoOut32( ACC0 >> 16, ACC1 >> 16);
</source>


{{PCSX2 Main Documentation Navbox}}
{{PCSX2 Documentation Navbox}}
ninja
782

edits