更好地更改音频的优化
正在测试一个新系统,以使用淡入淡出和淡出效果来增加我的Javaswing应用程序中的音频。一方面,通过进行我自己的研究,这并不像希望的那样最佳,因为它利用thread.sleep(x);
而不是使用timer(); 来自Javaswing。
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
value = (value <= 0.0) ? 0.0001 : ((value > 1.0) ? 1.0 : value);
try {
float db = (float) (Math.log(percent) / Math.log(10.0) * 20.0);
gainControl.setValue(db);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void shiftVolumeTo(double value) {
value = (value <= 0.0) ? 0.0001 : ((value > 1.0) ? 1.0 : value);
targetDB = (float)(Math.log(value)/Math.log(10.0)*20.0);
if (!fading) {
Thread t = new Thread();
t.start();
}
}
public static void run() {
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
fading = true;
if(currDB > targetDB) {
while (currDB > targetDB) {
currDB -= fadePerStep;
gainControl.setValue(currDB);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} else if (currDB < targetDB) {
while(currDB < targetDB) {
currDB += fadePerStep;
gainControl.setValue(currDB);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
fading = false;
currDB = targetDB;
}
public static void volTest() {
setVolume(1);
shiftVolumeTo(.2);
run();
}
同样,当调用run();
时,这可以正常工作,但它使整个应用程序在的时间内入睡
loop的运行时。这就是我遇到的问题。我尝试在代码中设置Javaswing timer();
,尽管我无法弄清楚如何正确设置它以使延迟运行如thread.sleep.sleep(x) );
方法。是将代码从run();
添加到actionListener
中,还是由计时器创建或使用,还是仅具有run();
; ActionListener
。与thread.sleep(x);
不同,该程序只会跳跃值而不需要时间减少音量,因为>环形。
在这种情况下,使用Javaswing Timer();
的最佳方法是什么?
Been testing a new system for increasing/decreasing the audio within my JavaSwing application using a fade in and fade out effect. This works on one hand though by doing my own research, it's not as optimal as one hoped to be since it utilizes Thread.sleep(x);
rather than using Timer();
from JavaSwing.
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
value = (value <= 0.0) ? 0.0001 : ((value > 1.0) ? 1.0 : value);
try {
float db = (float) (Math.log(percent) / Math.log(10.0) * 20.0);
gainControl.setValue(db);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void shiftVolumeTo(double value) {
value = (value <= 0.0) ? 0.0001 : ((value > 1.0) ? 1.0 : value);
targetDB = (float)(Math.log(value)/Math.log(10.0)*20.0);
if (!fading) {
Thread t = new Thread();
t.start();
}
}
public static void run() {
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
fading = true;
if(currDB > targetDB) {
while (currDB > targetDB) {
currDB -= fadePerStep;
gainControl.setValue(currDB);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} else if (currDB < targetDB) {
while(currDB < targetDB) {
currDB += fadePerStep;
gainControl.setValue(currDB);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
fading = false;
currDB = targetDB;
}
public static void volTest() {
setVolume(1);
shiftVolumeTo(.2);
run();
}
Again, this works properly when run();
is called, but it puts the entire application to sleep within the duration of the while
loop's runtime. Which is what I'm having an issue with. I've tried setting up a JavaSwing Timer();
within the code though I couldn't figure out how to set it up properly to make the delay run like the Thread.sleep(x);
method. Whether it is adding the code from run();
into the ActionListener
created or utilized by the timer or just having run();
within the ActionListener
. Unlike Thread.sleep(x);
, the program will just jump values without taking it's time to decrease the volume as there's no delay between the incremental increase/decrease of the while
loop.
What would be the optimal way to utilize a JavaSwing Timer();
that would work similar to a Thread.sleep(x);
in this situation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不清楚您在给定代码中正在做什么。我怀疑您正在将
util.timer
的方面与swing.timer
(并非罕见)混合在一起。使用
util.timer
,一个人扩展了timertask
,在此中,一个人覆盖 run()方法。run()
方法永远不会static
,afaik。使用
swing.timer
,要执行的代码位于actionperformed()
actionListener”>另一种选择,也可能是管理单独线程的更好方法是使用 scheduledthreadpoolexecutor 。
在这种情况下,我会考虑使用
util.timer
。我认为,如果您谨慎地将调用限制为单个声音,则可以设置floatControl
的值的电话。 (这是有关swing的 event dispatch thread )如果线程安全是问题,则有必要使用swing.timer
。但是您在这里了解到,您只能一次淡入或淡出单个声音,当时播放的所有声音也会受到影响吗?
floatcontrol.master_gain
控制所有播放声音。另外,我认为不能保证在给定的计算机上实现floatControls。我发现的文档中列出了许多列出的,这些文档没有在我拥有的各种PC上运行。另一个问题是,有时很难找到更新的最佳间隔,并相应的数量以改变音量。有时,如果单个体积的变化太大,则会像零合的声音一样柔软,快速的点击序列,例如在梳子上刮下缩略图的声音。
我想提及一个库供您考虑绕过
floatControl
的使用:视听。该类基本上是clip
的重写,但具有内置的动态,音量控制器。当您更改给定播放实例的卷时,它将仅影响该实例。 (该类支持播放并发实例。)所有振幅计算均在类的内部进行内部进行。该库可以作为Maven资源运行。该项目正在进行中:我刚刚添加了大量的测试代码,这些代码即将推向主人。我正在努力将其发布在Maven Central上。 (我去学习。)但是,如果您分配项目并运行Maven
install
命令,它将创建一个资源,您可以通过Maven POM文件在本地引用该资源。我正在考虑将可选的持续时间参数添加到动态控件中。然后(如果实现)可以指定应应用更改的框架或毫秒的框架或毫秒的数量。似乎是版本1.2的不错的补充(在Maven Central上升起1.1之后!),
audiocue
,每个单个框架都应用了更改。我不确定floatControl
和剪辑
的情况如何。这些变化的粒度可能会受到一些内部缓冲尺寸的限制。I'm not clear what you are doing from the given code. I suspect you are mixing up aspects of the
util.Timer
with theswing.Timer
(not uncommon).With the
util.Timer
, one extendsTimerTask
, and within that, one overrides the run() method. Therun()
method is neverstatic
, afaik.With the
swing.Timer
, the code to be executed resides in theactionPerformed()
method of the ActionListener.Another alternative, and likely a better way to manage the separate thread would be to use a ScheduledThreadPoolExecutor.
I'd consider using the
util.Timer
in this case. I think the calls to change the value of theFloatControl
could be set up to be thread safe if you are careful about limiting the calls to a single sound at a time. (Here is a link for more about Swing's Event Dispatch Thread) It would be necessary to use theswing.Timer
if thread safety is an issue.But you understand here that you can only fade in or out a single sound at a time, and ALL sounds playing at that moment will also be affected? The
FloatControl.MASTER_GAIN
controls all playing sounds. Also, I don't think there are no guarantees that the FloatControls are implemented on a given computer. There are many listed in the documentation that I have discovered do not function on various PCs I own.Another issue is that sometimes it can be difficult to find the best interval for the updates and corresponding amount to vary the volume. Sometimes we get as soft, fast sequence of clicks, like the sound of scraping a thumbnail over the tines of a comb, if the individual volume changes are too large.
I'd like to mention a library for you to consider that bypasses the use of the
FloatControl
: AudioCue. The class is basically a rewrite of theClip
but with a built in, dynamic, volume controller. When you alter the volume of a given playback instance, it will only affect that single instance. (The class supports playing back concurrent instances.) All the amplitude computations are done internally, within the code of the class.The library can be run as a Maven resource. The project is a work in progress: I've just added a lot of test code that I'm about to push to the master. I'm working to publish it on Maven Central. (Learning as I go.) But if you fork the project and run the Maven
install
command, it will create a resource that you can reference locally via the Maven pom file.I'm considering adding an optional duration argument to the dynamic controls. Then (if implemented) one could specify both the desired volume and the number of frames or milliseconds over which the change should be applied. Seems like a good addition for version 1.2 (after 1.1 is up on Maven central!)
With
AudioCue
, changes are applied per individual frames. I'm not sure what the situation is withFloatControl
andClips
. The changes might be limited in granularity to some internal buffer size.