Hi,
When the OnGetSongBuffer is used in a plugin, it modifies the "original" sound.
I create a simple plugin based on the example Audio Pluging (Buffer DSP). I cut the sound of the left channel.
I play a part of a song with the plugin activated, so the left channel is cutted. But when I replay the song without the plugin, the sound is cutted on the left channel exactly at the same place I activated the plugin before.
When I reload the song, the sound is "normal".
When the OnGetSongBuffer is used in a plugin, it modifies the "original" sound.
I create a simple plugin based on the example Audio Pluging (Buffer DSP). I cut the sound of the left channel.
I play a part of a song with the plugin activated, so the left channel is cutted. But when I replay the song without the plugin, the sound is cutted on the left channel exactly at the same place I activated the plugin before.
When I reload the song, the sound is "normal".
Posted Thu 01 Oct 20 @ 5:29 pm
If you want to modify the buffer your plugin should indeed create a buffer of it's own and copy the data it needs into it.
Posted Thu 01 Oct 20 @ 7:50 pm
a way to solve the problem :
//---------------------------------------------------------------------------
HRESULT VDJ_API CMyPlugin8::OnStart()
{
// ADD YOUR CODE HERE WHEN THE AUDIO PLUGIN IS STARTED
nbCompteur = 0;
return S_OK;
}
//---------------------------------------------------------------------------
short* VDJ_API CMyPlugin8::OnGetSongBuffer(int pos, int nb)
{
// ADD YOUR AUDIO TREATMENT CODE HERE USING THE AUDIO BUFFER *buffer OF 2*nb SHORT SAMPLES (STEREO SIGNAL)
HRESULT hr;
short* buffer;
hr = GetSongBuffer(pos, nb, (short**)&buffer);
for (int i = 0; i < nb; i++)
{
//bufferTemp declared in header file
if (nbCompteur > 0)
{
//Restore the original sound in the previous NB samples modified
buffer[2 * -nb + 2 * i] = bufferTemp[2 * i];
buffer[2 * -nb + 2 * i + 1] = bufferTemp[2 * i + 1];
}
//Store the current original sound before modification by the plugin
//will be use to restore the original sound in the next step
bufferTemp[2 * i] = buffer[2 * i];
bufferTemp[2 * i + 1] = buffer[2 * i + 1];
//modification of plugin
buffer[2 * i] = 0; //Cut the sound on the left channel
//buffer[2 * i + 1] = 0;
}
nbCompteur += nb;
return buffer;
}
Posted Fri 02 Oct 20 @ 9:36 pm
Hi,
Yes it's a start of a possibility but i think this may needs some deepest investigations
Questions:
it looks like "bufferTemp declared in header file" must be at least number of samples in track file * sizeof (short) * 2 else there are risk of buffer overflow
- how to know exactly the size needed to define the buffer ?
- the variable 'nb' used to write back samples is the number of samples in the new buffer, not necessary the same as previous buffer, can write more or less than needed
once again buffer overflow, both sides or buffer corruption (well, it is already, this is the reason on this workaround)
- if other plugins doe the same in chain... won't they write back things in wrong order ?
- scratching or other moves in track give buffer positions not in sequence, doesn't this overwrite wrong area ?
next ones are SDK related
- what if track using 24 or 32bit or float samples format ? does VDJ downsample to short for effects ? :'(
- as internal buffer for DSP8 plugins is an array of floats, this wanna say samples convert again and again between shorts and float for every plugins ?
Yes it's a start of a possibility but i think this may needs some deepest investigations
Questions:
it looks like "bufferTemp declared in header file" must be at least number of samples in track file * sizeof (short) * 2 else there are risk of buffer overflow
- how to know exactly the size needed to define the buffer ?
- the variable 'nb' used to write back samples is the number of samples in the new buffer, not necessary the same as previous buffer, can write more or less than needed
once again buffer overflow, both sides or buffer corruption (well, it is already, this is the reason on this workaround)
- if other plugins doe the same in chain... won't they write back things in wrong order ?
- scratching or other moves in track give buffer positions not in sequence, doesn't this overwrite wrong area ?
next ones are SDK related
- what if track using 24 or 32bit or float samples format ? does VDJ downsample to short for effects ? :'(
- as internal buffer for DSP8 plugins is an array of floats, this wanna say samples convert again and again between shorts and float for every plugins ?
Posted Fri 02 Oct 20 @ 10:57 pm
@deun you should not write to the buffer returned from getsongbuffer at all.
You can copy it to your temp buffer, do your processing and return temp buffer instead.
@nico buffer plugins operate on the song buffer that is kept in memory after decoding, before it is converted to float for processing other effects and mixing.
There is a small buffer after buffer plugins which is why you will see the block requests while scratching
You can copy it to your temp buffer, do your processing and return temp buffer instead.
@nico buffer plugins operate on the song buffer that is kept in memory after decoding, before it is converted to float for processing other effects and mixing.
There is a small buffer after buffer plugins which is why you will see the block requests while scratching
Posted Sat 03 Oct 20 @ 6:21 am
Thank you Adion.
You're right. I thought it was necessary to return to the buffer... Sorry.
It is that easy. Is there a way to set the length of bufferTemp ?
You're right. I thought it was necessary to return to the buffer... Sorry.
It is that easy. Is there a way to set the length of bufferTemp ?
//---------------------------------------------------------------------------
HRESULT VDJ_API CMyPlugin8::OnStart()
{
// ADD YOUR CODE HERE WHEN THE AUDIO PLUGIN IS STARTED
return S_OK;
}
//---------------------------------------------------------------------------
short* VDJ_API CMyPlugin8::OnGetSongBuffer(int pos, int nb)
{
// ADD YOUR AUDIO TREATMENT CODE HERE USING THE AUDIO BUFFER *buffer OF 2*nb SHORT SAMPLES (STEREO SIGNAL)
HRESULT hr;
short* buffer;
hr = GetSongBuffer(pos, nb, (short**)&buffer);
short bufferTemp[44100];
for (int i = 0; i < nb; i++)
{
bufferTemp[2 * i] = 0; //Cut the sound on the left channel
bufferTemp[2 * i + 1] = buffer[2 * i + 1];
}
return bufferTemp;
}
//---------------------------------------------------------------------------
Posted Sat 03 Oct 20 @ 11:29 am
The easiest is to use a dynamic buffer (can use vector in c++) and resize it when necessary.
So in CMyPlugin add a member variable
And in OnGetSongBuffer, check if the buffer is big enough at the start
And to return use
That way re-allocating the buffer is minimized, but it's still ensured that it is big enough.
So in CMyPlugin add a member variable
std::vector<short> bufferTemp;
And in OnGetSongBuffer, check if the buffer is big enough at the start
if (bufferTemp.size()<nb*2)
bufferTemp.resize(nb*2);
And to return use
return bufferTemp.data();
That way re-allocating the buffer is minimized, but it's still ensured that it is big enough.
Posted Sat 03 Oct 20 @ 12:07 pm
Really elegant solution !
Posted Sat 03 Oct 20 @ 2:30 pm
@adion : works well ! Thank you.
Posted Sun 11 Oct 20 @ 11:14 am