stereo delay plugin for ladspa
2015-10-30 14:21
204 查看
My latest music player project has an special demand which require to delay one channel of stereo a little than another, the supposedly applied scene is that listener is not sitting in the middle of speakers, As we all know sound also need time to arrive
the target,here your ear, since the distance between user and two speaks is different, theoretically user should has a bad music experience, in fact in most conditions the different is so little that ears can't discern it. But don't we should have an attractable
point . so do it. from point of technique, the process is really simple, buffer one channel till the wanted time reached. I thought there should be ready open source code can be used, it really does after search on the yahoo. ladspa has a lot of plugin and
can do almost everything you want to hack your audio. after try all the delay plugin integrated into that project, I have to say these plugins is really powerful but can't act what I want, all of them use complicated algorithm to achieve functions far more
what I needed. so I write my own , it is very simple but really work, the code is listed here for you refer.
Insert attached code into 'lcr_delay_1436.xml', between ' ]]></callback>' and '</ladspa>' and recompile the whole ladspa plugin.
usage:
for alsa user, the asound.conf should look like this:
pcm.ladspa {
type ladspa
slave.pcm "plughw:0,0";
path "/usr/lib/ladspa";
plugins [{
label lrDelay
id 1437
input {
controls [ 1000 2 ]
}
}]
}
pcm.!default{
type plug
slave.pcm ladspa
}
meaning of the controls parameters:
first one: delay time (ms) , range of value between 1 to 2700
second: channel you want to delay. 1 left,2 right.
code:
<plugin label="lrDelay" id="1437" class="DelayPlugin">
<name>L/R Delay</name>
<p>This is a very simple left/right delay .</p>
<callback event="instantiate"><![CDATA[
buffer_size = 32768;
buffer_offset=0;
fs = s_rate;
// printf("s_rate=%d\n",s_rate);
while (buffer_size < fs * 2.7f) {
buffer_size *= 2;
}
buffer = calloc(buffer_size, sizeof(LADSPA_Data));
plugin_data->buffer_pos_w=0;
plugin_data->buffer_pos_r=0;
]]></callback>
<callback event="activate"><![CDATA[
memset(buffer, 0, buffer_size * sizeof(LADSPA_Data));
]]></callback>
<callback event="connect_port"><![CDATA[
]]></callback>
<callback event="cleanup"><![CDATA[
free(plugin_data->buffer);
]]></callback>
<callback event="run"><![CDATA[
unsigned long pos;
unsigned int tmp;
LADSPA_Data * p;
tmp=(int)(del*fs/1000);
if(tmp!=buffer_offset)
{
plugin_data->buffer_pos_w=tmp>=plugin_data->buffer_size?plugin_data->buffer_size-1:tmp-1;
buffer_offset=tmp;
}
tmp=(int)(channel+0.1);
for (pos = 0; pos < sample_count; pos++) {
/*put the data into buf*/
p= tmp==1?in_l:in_r;
plugin_data->buffer[plugin_data->buffer_pos_w]=p[pos];
plugin_data->buffer_pos_w=plugin_data->buffer_pos_w>=plugin_data->buffer_size?0:plugin_data->buffer_pos_w+1;
/* Left and right channel outs */
if(p==in_l)
{
buffer_write(out_l[pos], plugin_data->buffer[plugin_data->buffer_pos_r]);
buffer_write(out_r[pos], in_r[pos] );
}
else{
buffer_write(out_l[pos], in_l[pos] );
buffer_write(out_r[pos], plugin_data->buffer[plugin_data->buffer_pos_r]);
}
plugin_data->buffer_pos_r=plugin_data->buffer_pos_r>=plugin_data->buffer_size?0:plugin_data->buffer_pos_r+1;
}
]]></callback>
<port label="del" dir="input" type="control" hint="default_low">
<name>delay (ms)</name>
<p>The delay of the left/right output in milliseconds.</p>
<range min="1" max="2700"/>
</port>
<port label="channel" dir="input" type="control" hint="default_low">
<name>channel to delay</name>
<p>The channel need to delay.</p>
<range min="1" max="2"/>
</port>
<port label="in_l" dir="input" type="audio">
<name>L input</name>
</port>
<port label="in_r" dir="input" type="audio">
<name>R input</name>
</port>
<port label="out_l" dir="output" type="audio">
<name>L output</name>
</port>
<port label="out_r" dir="output" type="audio">
<name>R output</name>
</port>
<instance-data label="buffer" type="LADSPA_Data *" />
<instance-data label="buffer_pos_w" type="unsigned int" />
<instance-data label="buffer_pos_r" type="unsigned int" />
<instance-data label="buffer_size" type="unsigned int" />
<instance-data label="fs" type="float" />
</plugin>
the target,here your ear, since the distance between user and two speaks is different, theoretically user should has a bad music experience, in fact in most conditions the different is so little that ears can't discern it. But don't we should have an attractable
point . so do it. from point of technique, the process is really simple, buffer one channel till the wanted time reached. I thought there should be ready open source code can be used, it really does after search on the yahoo. ladspa has a lot of plugin and
can do almost everything you want to hack your audio. after try all the delay plugin integrated into that project, I have to say these plugins is really powerful but can't act what I want, all of them use complicated algorithm to achieve functions far more
what I needed. so I write my own , it is very simple but really work, the code is listed here for you refer.
Insert attached code into 'lcr_delay_1436.xml', between ' ]]></callback>' and '</ladspa>' and recompile the whole ladspa plugin.
usage:
for alsa user, the asound.conf should look like this:
pcm.ladspa {
type ladspa
slave.pcm "plughw:0,0";
path "/usr/lib/ladspa";
plugins [{
label lrDelay
id 1437
input {
controls [ 1000 2 ]
}
}]
}
pcm.!default{
type plug
slave.pcm ladspa
}
meaning of the controls parameters:
first one: delay time (ms) , range of value between 1 to 2700
second: channel you want to delay. 1 left,2 right.
code:
<plugin label="lrDelay" id="1437" class="DelayPlugin">
<name>L/R Delay</name>
<p>This is a very simple left/right delay .</p>
<callback event="instantiate"><![CDATA[
buffer_size = 32768;
buffer_offset=0;
fs = s_rate;
// printf("s_rate=%d\n",s_rate);
while (buffer_size < fs * 2.7f) {
buffer_size *= 2;
}
buffer = calloc(buffer_size, sizeof(LADSPA_Data));
plugin_data->buffer_pos_w=0;
plugin_data->buffer_pos_r=0;
]]></callback>
<callback event="activate"><![CDATA[
memset(buffer, 0, buffer_size * sizeof(LADSPA_Data));
]]></callback>
<callback event="connect_port"><![CDATA[
]]></callback>
<callback event="cleanup"><![CDATA[
free(plugin_data->buffer);
]]></callback>
<callback event="run"><![CDATA[
unsigned long pos;
unsigned int tmp;
LADSPA_Data * p;
tmp=(int)(del*fs/1000);
if(tmp!=buffer_offset)
{
plugin_data->buffer_pos_w=tmp>=plugin_data->buffer_size?plugin_data->buffer_size-1:tmp-1;
buffer_offset=tmp;
}
tmp=(int)(channel+0.1);
for (pos = 0; pos < sample_count; pos++) {
/*put the data into buf*/
p= tmp==1?in_l:in_r;
plugin_data->buffer[plugin_data->buffer_pos_w]=p[pos];
plugin_data->buffer_pos_w=plugin_data->buffer_pos_w>=plugin_data->buffer_size?0:plugin_data->buffer_pos_w+1;
/* Left and right channel outs */
if(p==in_l)
{
buffer_write(out_l[pos], plugin_data->buffer[plugin_data->buffer_pos_r]);
buffer_write(out_r[pos], in_r[pos] );
}
else{
buffer_write(out_l[pos], in_l[pos] );
buffer_write(out_r[pos], plugin_data->buffer[plugin_data->buffer_pos_r]);
}
plugin_data->buffer_pos_r=plugin_data->buffer_pos_r>=plugin_data->buffer_size?0:plugin_data->buffer_pos_r+1;
}
]]></callback>
<port label="del" dir="input" type="control" hint="default_low">
<name>delay (ms)</name>
<p>The delay of the left/right output in milliseconds.</p>
<range min="1" max="2700"/>
</port>
<port label="channel" dir="input" type="control" hint="default_low">
<name>channel to delay</name>
<p>The channel need to delay.</p>
<range min="1" max="2"/>
</port>
<port label="in_l" dir="input" type="audio">
<name>L input</name>
</port>
<port label="in_r" dir="input" type="audio">
<name>R input</name>
</port>
<port label="out_l" dir="output" type="audio">
<name>L output</name>
</port>
<port label="out_r" dir="output" type="audio">
<name>R output</name>
</port>
<instance-data label="buffer" type="LADSPA_Data *" />
<instance-data label="buffer_pos_w" type="unsigned int" />
<instance-data label="buffer_pos_r" type="unsigned int" />
<instance-data label="buffer_size" type="unsigned int" />
<instance-data label="fs" type="float" />
</plugin>
相关文章推荐
- solr实战问题集合
- mybatis3源码研究-构建SqlSessionFactory(二)
- Kotlin: Java 6 废土中的一线希望
- Dubbo zookeeper 初探
- 腻子脚本
- POJ 2723 HDU 1816 Get Luffy Out
- Kudu – 在快数据上的进行快分析的存储
- 2015-10-30-Android手机屏幕相关知识点
- 四种方案解决ScrollView嵌套ListView问题(转)
- Inner join,outer join,left join,right join的区别
- Netty4.x中文教程系列 ChannelHandler
- JavaScript中的定时器之Item23的合理使用
- 一个APP两个程序主入口,两个图标,互不干扰
- fastjson其他常用方法
- SQL之T-sql 语句操作数据库
- .NET发送邮件
- Cisco useful feature and commands
- 禁用IOS9 https
- Java调用python
- Android:Activity之间跳转和参数传递