While mixAllInOneSound how to repeat second file until first File duration.
Opened this issue · 30 comments
Thank you so this Awesome Lib for SoundTransform -
I am trying something like this.
try { start().inParallel(prepare().convertIntoSound().build() , 5, file1, file2) .mixAllInOneSound().exportToFile(outPutFile); } catch (SoundTransformException e) { e.printStackTrace(); }
the Output file is of duration 25 sec, I want to convert as complete 55sec by repeat second file for at least two times. How can achieve this, I am doing this for adding background Guitar sound in any recorded file in Android.
Please help, Thank you.
Hi Amit,
Probably what you want is the LoopSoundTransform.
I don't know if it works, I hope it will !
Sound sound1 = start().withFile(new File("file1.wav")).convertIntoSound().apply(new LoopSoundTransform(300000)).stopWithSound();
Sound sound2 = start().withFile(new File("file2.wav")).convertIntoSound().stopWithSound();
start().inParallel(
prepare().mixAllInOneSound().build(),
5,
sound1, sound2
);
Please note that 300000 is a random value, you should compute how much samples you need (yes the unit is in samples, not in milliseconds)
@libetl Hey I think its working but the problem is I didn't get regarding samples, first time working on Sound programming So Can you help, how can I get the idea or calculate sample for any Audio file?
Big Thanks
It would be great help you can give me an example :-)
Sound soundOrgination = start().withFile(file1).convertIntoSound().stopWithSound();
int SampleLength = soundOrgination.getSamplesLength();
// System.out.println("Sample Legth " + SampleLength);
Sound backgroundSound = start().withFile(file2).convertIntoSound().apply(new LoopSoundTransform(SampleLength)).stopWithSound();
start().withSound(backgroundSound ).exportToStream().playIt();
start().withSound(soundOrgination).exportToStream().playIt();```
> _I have done something like this But Both Sound not playing completely but stuck in between, any idea where I am doing this wrong?_
** Is there any limit on file duration? like 20 or 30 seconds only?
Sorry commuting from work.
Hello again !
I just tried to implement your task and maybe you forgot to compare the sound formats before looping.
If your sounds use different formats, your work should also consist in calculating a ratio.
Here is a snippet that worked for me :
import org.toilelibre.libe.soundtransform.model.converted.FormatInfo;
import org.toilelibre.libe.soundtransform.model.converted.sound.Sound;
import org.toilelibre.libe.soundtransform.model.exception.SoundTransformException;
import java.io.File;
import static org.toilelibre.libe.soundtransform.actions.fluent.FluentClient.start;
public class TestLoop {
public static void main(String[] args) throws SoundTransformException {
File longFile = new File("/mnt/data/lionel/aLongSound.wav");
File shortFile = new File("/mnt/data/lionel/aShortSound.wav");
Sound longSound = start().withFile(longFile).convertIntoSound().stopWithSound();
Sound shortSound = start().withFile(shortFile).convertIntoSound().stopWithSound();
FormatInfo longSoundFormat = longSound.getFormatInfo();
FormatInfo shortSoundFormat = shortSound.getFormatInfo();
float ratio = (shortSoundFormat.getSampleSize() * shortSoundFormat.getSampleRate()) /
(longSoundFormat.getSampleSize() * longSoundFormat.getSampleRate());
Sound repeatedSound = start().withSound(shortSound)
.loop((int)(longSound.getSamplesLength() * ratio)).stopWithSound();
start().withSound(longSound).mixWith(repeatedSound).exportToFile(new File("/mnt/data/lionel/output.wav"));
}
}
Good luck !
@libetl Hey Thank you So much it's working like charm.
Some white noise after mixing can we do something to reduce the noise in the final Sound??
And how can I get the progress data of converting in android?
Well thanks for the above example 👍
@libetl Hey
Whie compiling the lib in my final Project I am getting following build error
Error:Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'. java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex
I am using compile 'org.toile-libre.libe:soundtransform:1.0.23'
for Compiling in my project
Try the ReduceNoiseSoundTransform to lower the noise.
If you want to bundle the lib, use it as an AAR.
If you need an example, go to my repository 'Singin'
Good luck !
Hey
I didn't get much help from Singin for compiling your Lib. What I need to add in gradle file to use it properly.
I build it Successfully if I use classpath 'com.android.tools.build:gradle:2.3.3'
but not with classpath 'com.android.tools.build:gradle:3.0.0'
Please help if possible
Thanks You 👍
Ok, Thank you So much for this and I want to ask that Can we make the final Converted Sound as valid m4a file. Trying to do that but having some problem while merging same m4a audio with video.
How Can I use ReduceNoiseSoundTransform on Sound
Sound backgroundSound = start().withFile(backgroundFile).convertIntoSound().stopWithSound();
FormatInfo voiceFormatInfo = voiceSound.getFormatInfo();
FormatInfo backgroundFormatInfo = backgroundSound.getFormatInfo();
float ratio = (backgroundFormatInfo.getSampleSize() * backgroundFormatInfo.getSampleRate()) /
(voiceFormatInfo.getSampleSize() * voiceFormatInfo.getSampleRate());
Sound repeatBackgroundSound = start().withSound(backgroundSound).loop((int) (voiceSound.getSamplesLength() * ratio)).stopWithSound();
// start().withSound(voiceSound).mixWith(repeatBackgroundSound).exportToFile(outputFile);
start().withSound(voiceSound).mixWith(repeatBackgroundSound).apply(new ReduceNoiseSoundTransform(10)).exportToFile(outputFile);
How to calculate the "percentOfMaxVolumeThreshold"
That is a good question, there is no obvious way to compute dynamically a percentage to reduce the noise.
It should be a static value. Try different values.
If your need is to get a sound with a normalized volume in decibels,
you should do that afterwards :
Sound normalizedSound = start().withSound(mixedSound).apply(new NormalizeSoundTransform(0.9f)).stopWithSound();
@libetl
I tried my Luck in Noise Reduction but it just not happening. Can't we mix two audios without Noise? Please help.
🤔 Try to apply the noise filter (ReduceNoiseSoundTransform) on the voice sound alone.
Doing it on the mixed sound will not work accurately, or will not work fine.
here is a working configuration with gradle (2.3.3) :
compile('org.toile-libre.libe:soundtransform:1.0.23'){
exclude group:'junit', module:'junit'
}
I don't know why junit 3.8.2 is exported from my lib. Weird.
@libetl Applying ReduceNoiseSoundTransform(0.1f) but it becomes noisy after that. What else I need to do?
no luck :(
You should send me your sample so I can understand more the trouble with it.
@libetl Hey,
I have sent you the sample Sound Zip file on your mail Id -
Also attaching the same over here
- LoopSound - Background Music in loop
- VoiceRecordSound - Recorded Voice to mixing
- FinalMixed Sound - Final Mixed Sound
It would be great if you can look into the issue and help me, I am stuck on this part for very long. 👍
mixWith operation seems to have a bug. I am sorry.
I don't know yet how to fix this.
spent the whole evening yesterday, will try again to understand this evening, no promise yet.
looking for some documentation about how to reduce noise efficiently
Hi Amit,
I am sorry I was too tired to work yesterday but I had a good idea to improve the noise reduction filter.
I should try to implement it.
Hi,
That is not good, but it still contributes to reducing the noise level :
Create this SoundTransform class :
package org.toilelibre.libe.soundtransform.infrastructure.service.converted.sound.transforms;
import org.apache.commons.math3.complex.Complex;
import org.toilelibre.libe.soundtransform.model.converted.FormatInfo;
import org.toilelibre.libe.soundtransform.model.converted.sound.transform.SimpleFrequencySoundTransform;
import org.toilelibre.libe.soundtransform.model.converted.spectrum.Spectrum;
public class BlurSoundTransform extends SimpleFrequencySoundTransform<Complex []> {
@Override
public Spectrum<Complex[]> transformFrequencies (final Spectrum<Complex[]> fs, final int offset, final int powOf2NearestLength, final int length) {
double averageReal = 0f;
double averageImaginary = 0f;
Complex[] newArray = new Complex[powOf2NearestLength];
for (int j = 0 ; j < length ; j++) {
averageReal = averageReal + Math.abs(fs.getState()[j].getReal());
averageImaginary = averageImaginary + Math.abs(fs.getState()[j].getImaginary());
}
averageReal = averageReal / length;
averageImaginary = averageImaginary / length;
final double averageAbs = Math.pow(averageReal, 2) + Math.pow(averageImaginary, 2);
for (int j = 0 ; j < length ; j++) {
double difference = Math.abs(averageAbs -
(Math.pow(fs.getState()[j].getReal(), 2) + Math.pow(fs.getState()[j].getImaginary(), 2)));
newArray[j] = difference > averageAbs / 1f ? fs.getState()[j] : new Complex(0);
}
for (int j = length ; j < powOf2NearestLength ; j++) {
newArray[j] = new Complex(0);
}
return new Spectrum<Complex []> (newArray, new FormatInfo(fs.getSampleSize (), fs.getSampleRate ()));
}
}
Call it from your example, this is what I tried:
public class TestLoop {
public static void main(String[] args) throws SoundTransformException {
Sound sampleSound = start().withFile(new File("/mnt/data/lionel/LoopSound.wav")).convertIntoSound()
.apply(new BlurSoundTransform()).apply(new NormalizeSoundTransform(0.5f)).stopWithSound();
Sound voiceSound = start().withFile(new File("/mnt/data/lionel/VoiceRecordSound.wav")).convertIntoSound()
.apply(new BlurSoundTransform()).apply(new NormalizeSoundTransform(1f)).stopWithSound();
Sound repeatedSound = start().withSound(sampleSound).changeFormat(voiceSound.getFormatInfo())
.apply(new LoopSoundTransform(voiceSound.getSamplesLength())).stopWithSound();
final Object stopMonitor = new Object();
synchronized (stopMonitor) {
start().withSound(voiceSound).mixWith(repeatedSound).playIt(stopMonitor);
try {stopMonitor.wait();} catch (InterruptedException e) {}
}
}
}
No miracle to hear, the noise level is reduced slightly, maybe there should be a better filter than this one.
It removes the frequencies too close to the average (those supposed to create the unbearable white noise)