Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

While mixAllInOneSound how to repeat second file until first File duration. #67

Open
knowamit opened this issue Nov 30, 2017 · 30 comments
Assignees
Labels

Comments

@knowamit
Copy link

knowamit commented Nov 30, 2017

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.

@libetl
Copy link
Owner

libetl commented Nov 30, 2017

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)

@knowamit
Copy link
Author

knowamit commented Nov 30, 2017

@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 :-)

@knowamit
Copy link
Author

knowamit commented Nov 30, 2017

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?

@libetl
Copy link
Owner

libetl commented Nov 30, 2017

Sorry commuting from work.

@libetl
Copy link
Owner

libetl commented Nov 30, 2017

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 !

@knowamit
Copy link
Author

knowamit commented Dec 1, 2017

@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 👍

@knowamit
Copy link
Author

knowamit commented Dec 1, 2017

@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

@libetl
Copy link
Owner

libetl commented Dec 1, 2017

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 !

@knowamit
Copy link
Author

knowamit commented Dec 1, 2017

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.

@knowamit
Copy link
Author

knowamit commented Dec 1, 2017

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 👍

@libetl
Copy link
Owner

libetl commented Dec 1, 2017 via email

@knowamit
Copy link
Author

knowamit commented Dec 1, 2017

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.

@libetl
Copy link
Owner

libetl commented Dec 1, 2017 via email

@knowamit
Copy link
Author

knowamit commented Dec 1, 2017

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"

@libetl
Copy link
Owner

libetl commented Dec 1, 2017

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 libetl self-assigned this Dec 1, 2017
@libetl libetl added the support label Dec 1, 2017
@knowamit
Copy link
Author

knowamit commented Dec 1, 2017

@libetl
I tried my Luck in Noise Reduction but it just not happening. Can't we mix two audios without Noise? Please help.

@libetl
Copy link
Owner

libetl commented Dec 3, 2017

🤔 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.

@libetl
Copy link
Owner

libetl commented Dec 3, 2017

here is a working configuration with gradle (2.3.3) :

    compile('org.toile-libre.libe:soundtransform:1.0.23'){
        exclude group:'junit', module:'junit'
    }

@libetl
Copy link
Owner

libetl commented Dec 3, 2017

I don't know why junit 3.8.2 is exported from my lib. Weird.

@knowamit
Copy link
Author

knowamit commented Dec 4, 2017

@libetl Applying ReduceNoiseSoundTransform(0.1f) but it becomes noisy after that. What else I need to do?

@libetl
Copy link
Owner

libetl commented Dec 4, 2017

no luck :(

You should send me your sample so I can understand more the trouble with it.

@knowamit
Copy link
Author

knowamit commented Dec 5, 2017

@libetl Hey,

I have sent you the sample Sound Zip file on your mail Id -

[email protected]

Also attaching the same over here

  1. LoopSound - Background Music in loop
  2. VoiceRecordSound - Recorded Voice to mixing
  3. FinalMixed Sound - Final Mixed Sound

SoundTransform.zip

It would be great if you can look into the issue and help me, I am stuck on this part for very long. 👍

@libetl
Copy link
Owner

libetl commented Dec 6, 2017

mixWith operation seems to have a bug. I am sorry.
I don't know yet how to fix this.

@knowamit
Copy link
Author

knowamit commented Dec 6, 2017

@libetl Any Chance to fix this issue?? I really need this Please

@libetl
Copy link
Owner

libetl commented Dec 6, 2017

spent the whole evening yesterday, will try again to understand this evening, no promise yet.

@libetl
Copy link
Owner

libetl commented Dec 6, 2017

looking for some documentation about how to reduce noise efficiently

@knowamit
Copy link
Author

knowamit commented Dec 6, 2017

@libetl Thank you So much 💯

@libetl
Copy link
Owner

libetl commented Dec 7, 2017

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.

@knowamit
Copy link
Author

knowamit commented Dec 8, 2017

@libetl That would be a great help :-)

@libetl
Copy link
Owner

libetl commented Dec 11, 2017

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants