soundtransform


Source link: https://github.com/libetl/soundtransform

soundtransform

Android & Pure Java library to shape a voice with an instrument.

Table of Contents

How to use the library

  • Insert the jar into your project dependencies :
<dependency>  <groupId>org.toile-libre.libe</groupId>  <artifactId>soundtransform</artifactId>  <version>LATEST</version> </dependency>
  • Or as an android library :
<dependency>  <groupId>org.toile-libre.libe</groupId>  <artifactId>soundtransform</artifactId>  <version>LATEST</version>  <type>aar</type> </dependency>
  • It also works as a gradle dependency :
repositories {

mavenCentral()
  
}

dependencies {

  compile 'org.toile-libre.libe:soundtransform:LATEST' 
}
 
  • Make sure you have access to the FluentClient class in your project (try the autocompletion feature of your IDE if you have one)
  • Read the following documentation about the FluentClient facility
  • Have a look at the available SoundTransform classes
  • Use the lib by yourself

FluentClient

The FluentClient service provider interface is a simple class to give a shortcut to all the features of the lib without walking in the nested classes.

It helps you to proceed to the correct actions at each step, giving you the right programming interface during the pipeline.

To use it, it is only needed to chain the methods invocation. it will always start with a FluentClient.start(), can end with a stop method and can contain an andAfterStart call to chain two processes in the same instruction of code.

FluentClient samples

import static org.toilelibre.libe.soundtransform.actions.fluent.FluentClient.start; import static org.toilelibre.libe.soundtransform.actions.fluent.FluentClient.setDefaultObservers; import static org.toilelibre.libe.soundtransform.actions.fluent.FluentClientOperation.prepare;  //...  public void method (){

//Set the default Slf4J logger and the log threshold as "WARNING" (the only output will be the warning and error logs)
setDefaultObservers (new Slf4jObserver (LogLevel.WARN));

 //Apply a 8-bit transform on a wav and then export it to a wav
start ().withClasspathResource ("foo.wav").convertIntoSound ().apply (new EightBitsSoundTransform (25)).exportToClasspathResource ("bar.wav");

 //Create a var to use the CD format
FormatInfo cdFormatInfo = new FormatInfo (2, 44100.0);

 //Shape a wav with an instrument and then export it to a wav
start ().withAPack ("default", packInputStream).withClasspathResource ("foo.wav").convertIntoSound ().findLoudestFrequencies ().shapeIntoSound ("default", "simple_piano", cdFormatInfo).exportToClasspathResource ("bar.wav");

 //Play three times the same data, as a File, then as a sound, then as an inputStream
start ().withClasspathResource ("foo.wav").playIt ().convertIntoSound ().playIt ().exportToStream ().playIt ();

  //Transform a sound into a an array of spectrums
start ().withSound (sound).splitIntoSpectrums ().stopWithSpectrums ();

 //Transform a lowfi wav file into a cd format wavfile
start ().withClasspathResource ("lowfi.wav").convertIntoSound ().changeFormat (cdFormatInfo).exportToClasspathResource ("hifi.wav");

 //Mix of two sounds using two threads for the file-to-sound conversion
start ().inParallel (
  // operations
  prepare ().convertIntoSound ().build (),
  // timeout in seconds
  5,
  // classpath resources
  "foo.wav", "bar.wav")

  .mixAllInOneSound ().exportToClasspathResourceWithSiblingResource ("targetResource.wav", "existingSoundInSameDirectory.wav");
 
}

Please have a look at the many different actions that you can ask to the FluentClient in this JUnit Test

Android ? Pure Java ? Same code ?

It would be a great thing but unfortunately the Android SDK is made to be incompatible with the Java SDK. Because a lot of security features and facilities were (and are being) implemented to protect the users in Android, whereas the Java SDK is using the OS kernel features.

For example, you cannot read a resource on an Android device. Because it is considered as a security breach by the Android SDK.

It is preventing anyone from opening any file to steal data without a consent (a permission).

The soundtransform lib needs to adapt to these two contexts (Pure Java lib / android lib) to be able to proceed data in the same way. Only input and output processing are different as described below.

The Pure Java sample will be shown first because it is simpler.

Pack import

With Pure Java, you do :
 FluentClient.start ().withAPack ("default", Thread.currentThread ().getContextClassLoader ().getResourceAsStream ("yourpack.json"))
With Android, you do :
 FluentClient.start ().withAPack ("default", androidContext, yourpackage.R.raw.class, yourpackage.R.raw.yourpack)

Open a sound input

With Pure Java, you do :
 FluentClient.start ().withFile (new File ("/path/to/file.wav")).convertIntoSound ()
With Android, you do (with the android.permission.READ_EXTERNAL_STORAGE permission) :
 FluentClient.start ().withFile (new File (Environment.getExternalStorageDirectory ().getPath () + "/file.wav")).convertIntoSound ()

Save a sound output

With Pure Java, you do :
 //...  fluentClientWithSoundImported.exportToFile (new File ("/path/to/file.wav"));
With Android, you do (with the android.permission.WRITE_EXTERNAL_STORAGE permission):
 //...  fluentClientWithSoundImported.exportToFile (new File (Environment.getExternalStorageDirectory () + "/file.wav"));

FluentClient Javadoc

Four steps can be identified when using the FluentClient SPI :

  1. static init (optional) : the observers subscribe to the future invocations of the FluentClient
  2. start of the flow : a call to start (), followed by one or more calls to a with... () method
  3. operations (optional) : several chained method calls to transform the data in a "one-lined" way
  4. method flow stops (optional) : one call to stopWith... () to get the currently stored data

1. static init

FluentClient.setDefaultObserversValue
static void setDefaultObserversValue (Observer... defaultObservers)

Sets the passed observers as the default value when a FluentClient is started

It can be useful if you are going to use the FluentClient several times but you want to declare the subscribed observers only once

Parameters:
defaultObservers - one or more observer(s)

2. start of the flow

FluentClient.start ( only way to start a FluentClient)
static FluentClientReady start ()

Startup the client

Returns:
the client, ready to start

FluentClientReady.withAnObserver (before another with.. method)
FluentClientReady withAnObserver (Observer... observers)

Tells the client to add an observer that will be notified of different kind of updates from the library. It is ok to call withAnObserver several times. If the andAfterStart method is called, the subscribed observers are removed

Parameters:
observers - one or more observer (s)

Returns:
the client, ready to start

FluentClientReady.inParallel
<T extends FluentClientCommon> FluentClientWithParallelizedClients inParallel (FluentClientOperation op, int timeoutInSeconds, T... clients) throws SoundTransformException

Runs asynchronously the same operations on a varargs of started FluentClients

Parameters:
op - a list of operation to apply

timeoutInSeconds - a timeout value. After that, the operation will be stopped, even if it is still processing. You can choose Integer.MAX_VALUE as a value if you are convinced that it will finish.

clients - a list of started FluentClients

Returns:
the client, with a list of clients inside holding a value each

Throws:
SoundTransformException - can happen if there was a problem during the flow, or if the threads were interrupted

FluentClientReady.inParallel
FluentClientWithParallelizedClients inParallel (FluentClientOperation op, int timeoutInSeconds, Sound... sounds) throws SoundTransformException

Alias for the inParallel method using a list of sounds

Parameters:
op - a list of operation to apply

timeoutInSeconds - a timeout value. After that, the operation will be stopped, even if it is still processing. You can choose Integer.MAX_VALUE as a value if you are convinced that it will finish.

sounds - a vararg of sounds

Returns:
the client, with a list of clients inside holding a value each

Throws:
SoundTransformException - can happen if there was a problem during the flow, or if the threads were interrupted

FluentClientReady.inParallel
FluentClientWithParallelizedClients inParallel (FluentClientOperation op, int timeoutInSeconds, InputStream... inputStreams) throws SoundTransformException

Alias for the inParallel method using a list of inputStreams

Parameters:
op - a list of operation to apply

timeoutInSeconds - a timeout value. After that, the operation will be stopped, even if it is still processing. You can choose Integer.MAX_VALUE as a value if you are convinced that it will finish.

inputStreams - a list of inputStreams

Returns:
the client, with a list of clients inside holding a value each

Throws:
SoundTransformException - can happen if there was a problem during the flow, or if the threads were interrupted

FluentClientReady.inParallel
FluentClientWithParallelizedClients inParallel (FluentClientOperation op, int timeoutInSeconds, File... files) throws SoundTransformException

Alias for the inParallel method using a list of files

Parameters:
op - a list of operation to apply

timeoutInSeconds - a timeout value. After that, the operation will be stopped, even if it is still processing. You can choose Integer.MAX_VALUE as a value if you are convinced that it will finish.

files - a list of files

Returns:
the client, with a list of clients inside holding a value each

Throws:
SoundTransformException - can happen if there was a problem during the flow, or if the threads were interrupted

FluentClientReady.inParallel
FluentClientWithParallelizedClients inParallel (FluentClientOperation op, int timeoutInSeconds, float []... freqs) throws SoundTransformException

Alias for the inParallel method using a list of freqs

Parameters:
op - a list of operation to apply

timeoutInSeconds - a timeout value. After that, the operation will be stopped, even if it is still processing. You can choose Integer.MAX_VALUE as a value if you are convinced that it will finish.

freqs - loudest freqs arrays

Returns:
the client, with a list of clients inside holding a value each

Throws:
SoundTransformException - can happen if there was a problem during the flow, or if the threads were interrupted

FluentClientReady.inParallel
FluentClientWithParallelizedClients inParallel (FluentClientOperation op, int timeoutInSeconds, String... classpathResources) throws SoundTransformException

Alias for the inParallel method using a list of classpathResources

Parameters:
op - a list of operation to apply

timeoutInSeconds - a timeout value. After that, the operation will be stopped, even if it is still processing. You can choose Integer.MAX_VALUE as a value if you are convinced that it will finish.

classpathResources - a list of classpathResources

Returns:
the client, with a list of clients inside holding a value each

Throws:
SoundTransformException - can happen if there was a problem during the flow, or if the threads were interrupted

FluentClientReady.whileRecordingASound
FluentClientSoundImported whileRecordingASound (StreamInfo streamInfo, Object stop) throws SoundTransformException  FluentClientSoundImported whileRecordingASound (StreamInfo streamInfo, Object stop, AmplitudeObserver amplitudeObserver) throws SoundTransformException

Tells the client to open the microphone, to start recording a sound and to return in the pipeline The result will be a Segmented sound (a sound consisting of several mono sounds). The frameLength in the streamInfo will be ignored. The further actions are started just after the start of the recording.

  • /!\ : It is your responsibility to call stop.notifyAll () in another thread, else the recording will not finish
  • /!\ : This method should only be used if the next operation costs more time than the recording itself. In any other case, use the withRecordedInputStream method.

Parameters:
streamInfo - the future input stream info

stop - the method notifyAll must be called to stop the recording

amplitudeObserver - (optional) the update method will be called frequently to let the client code know what is the peak in DB. To be used for a VUmeter

Returns:
the client, with an imported sound (segmented)

Throws:
SoundTransformException - the mic could not be read, the recorder could not start, or the buffer did not record anything

FluentClientReady.withAMixedSound
FluentClientSoundImported withAMixedSound (Sound... sounds) throws SoundTransformException;

Tells the client to use the sounds passed in parameter by mixing them all into one

Parameters:
sounds - a var-arg value of sounds

Returns:
the client, with an imported sound

Throws:
SoundTransformException - the sound files are invalid

FluentClientReady.withAPack (Json InputStream) (before another with.. method)
FluentClientReady withAPack (String packName, InputStream jsonStream) throws SoundTransformException

Tells the client to work with a pack. Reads the whole inputStream. A pattern must be followed in the jsonStream to enable the import.

Parameters:
packName - the name of the pack

jsonStream - the input stream

Returns:
the client, ready to start

Throws:
SoundTransformException - the input stream cannot be read, or the json format is not correct, or some sound files are missing

FluentClientReady.withAPack (Android only) (before another with.. method)
FluentClientReady withAPack  (String packName, Object context, Class<?> rClass, int packJsonId) throws SoundTransformException

Tells the client to work with a pack. Uses the context object to find the resource from the R object passed in parameter

Parameters:
packName - the name of the pack

context - the Android context (should be an instance of android.content.Context, but left as Object so the FluentClient can be used in a non-android project)

rClass - R.raw.getClass () (either from soundtransform or from your pack) should be passed in parameter

packJsonId - the id value of your json pack file (should be a field inside R.raw)

Returns:
the client, ready to start

Throws:
SoundTransformException - the input stream cannot be read, or the json format is not correct, or some sound files are missing

FluentClientReady.withAPack (Json String) (before another with.. method)
FluentClientReady withAPack (String packName, String jsonContent) throws SoundTransformException

Tells the client to work with a pack. Reads the whole string content. A pattern must be followed in the jsonContent to enable the import.

Here is the format allowed in the file

{

"instrumentName" :
{

  {
"name" : "unknownDetailsFile"
}
,
  {
"name" : "knownDetailsFile.wav",

"frequency": 192.0,

"attack": 0,

"decay": 300,

"sustain": 500,

"release": 14732
}
,
 ...

}
,
... 
}

If a note (one of the records inside the instrumentName structure) does not own any detail, it will be obtained by digging in the file samples, and can take a really long time. It is advisable to fill in the details in each note.

Parameters:
packName - the name of the pack

jsonContent - a string containing the definition of the pack

Returns:
the client, ready to start

Throws:
SoundTransformException - the json content is invalid, the json format is not correct, or some sound files are missing

FluentClientReady.withAudioInputStream
FluentClientWithInputStream withAudioInputStream (InputStream ais)

Tells the client to work first with an InputStream. It will not be read yet The passed inputStream must own a format metadata object. Therefore it must be an AudioInputStream

Parameters:
ais - the input stream

Returns:
the client, with an input stream

FluentClientReady.withClasspathResource
FluentClientWithFile withClasspathResource (String resource) throws SoundTransformException

Tells the client to work first with a classpath resource. It will be converted in a File

Parameters:
resource - a classpath resource that must exist

Returns:
the client, with a file

Throws:
SoundTransformException - the classpath resource was not found

FluentClientReady.withFile
FluentClientWithFile withFile (File file)

Tells the client to work first with a file. It will not be read yet

Parameters:
file - source file

Returns:
the client, with a file

FluentClientReady.withFreqs
FluentClientWithFreqs withFreqs (float [] freqs)

Tells the client to work first with a loudest frequencies integer array. It will not be used yet

Parameters:
freqs - the loudest frequencies float array

Returns:
the client, with a loudest frequencies float array

FluentClientReady.withLimitedTimeRecordedInputStream
FluentClientWithInputStream withLimitedTimeRecordedInputStream (StreamInfo streamInfo) throws SoundTransformException

Tells the client to open the microphone and to record a sound The result will be of an InputStream type. The recording time will be the one passed in the streamInfo

Parameters:
streamInfo - the stream info

Returns:
the client, with an input stream

Throws:
SoundTransformException - the mic could not be read, the recorder could not start, or the buffer did not record anything

FluentClientReady.withRawInputStream
FluentClientWithInputStream withRawInputStream (InputStream is, StreamInfo isInfo) throws SoundTransformException

Tells the client to work first with a byte array InputStream or any readable DataInputStream. It will be read and transformed into an AudioInputStream The passed inputStream must not contain any metadata piece of information.

Parameters:
is - the input stream

isInfo - the stream info

Returns:
the client, with an input stream

Throws:
SoundTransformException - the input stream cannot be read, or the conversion did not work

FluentClientReady.withRecordedInputStream
FluentClientWithInputStream withRecordedInputStream (StreamInfo streamInfo, Object stop) throws SoundTransformException

Tells the client to open the microphone and to record a sound The result will be of an InputStream type. The frameLength in the streamInfo will be ignored

/!\ : blocking method, the stop.notifyAll () method must be called in another thread.

Parameters:
streamInfo - the future input stream info

stop - the method notifyAll must be called to stop the recording

Returns:
the client, with an input stream

Throws:
SoundTransformException - the mic could not be read, the recorder could not start, or the buffer did not record anything

FluentClientReady.withSound
FluentClientSoundImported withSound (Sound sound)

Tells the client to work first with a sound object

Parameters:
sound - the sound object

Returns:
the client, with an imported sound

FluentClientReady.withSpectrums
FluentClientWithSpectrums withSpectrums (List<Spectrum<Serializable> []> spectrums)

Tells the client to work first with a spectrum formatted sound. The spectrums inside must be in a list (each item must correspond to a channel) The spectrums are ordered in an array in chronological order

Parameters:
spectrums - the spectrums

Returns:
the client, with the spectrums

3. operations

FluentClientWithFreqs.adjust
FluentClientWithFreqs adjust ()

Adjusts the loudest freqs array to match exactly the piano notes frequencies

Returns:
the client, with a loudest frequencies float array

FluentClient*.andAfterStart
FluentClientReady andAfterStart ()

Start over the client : reset the state and the value objects nested in the client

Returns:
the client, ready to start

FluentClientSoundImported.append
FluentClientSoundImported append (Sound sound) throws SoundTransformException

Appends the sound passed in parameter to the current sound stored in the client

Parameters:
sound - the sound to append the current sound to

Returns:
the client, with a sound imported

Throws:
SoundTransformException - if the sound is null or if there is a problem with the appending please ensure that both sounds have the same number of channels

FluentClientSoundImported.apply
FluentClientSoundImported apply (SoundTransform<Channel, Channel> st) throws SoundTransformException

Applies one transform and continues with the result sound. The SoundTransform should have Channel as input and Channel as output. To apply another transform, use applyAndStop.

Parameters:
st - the SoundTransform to apply

Returns:
the client with a sound imported

Throws:
SoundTransformException - if the transform does not work

FluentClientSoundImported.changeFormat
FluentClientSoundImported changeFormat (FormatInfo formatInfo) throws SoundTransformException

Changes the current imported sound to fit the expected format

Parameters:
formatInfo - the new expected format

Returns:
the client, with a sound imported

Throws:
SoundTransformException - if the transform does not work

FluentClientWithFreqs.compress
FluentClientWithFreqs compress (float factor)

Compresses the loudest freq array (speedup or slowdown). When shaped into a sound, the result will have a different tempo than the original sound but will keep the same pitch

Parameters:
factor - the factor parameter quantifies how much the stretch or shrink will be. (i.e if factor = 0.5, then the result will be twice as long than the original)

Returns:
the client, with a loudest frequencies float array

FluentClientWithFile.convertIntoSound
FluentClientSoundImported convertIntoSound () throws SoundTransformException

Shortcut for importToStream ().importToSound () : Conversion from a File to a Sound

Returns:
the client, with a sound imported

Throws:
SoundTransformException - if one of the two import fails

FluentClientSoundImported.cutSubSound
FluentClientSoundImported cutSubSound (int start, int end) throws SoundTransformException

Splices a part of the sound between the sample #start and the sample #end

Parameters:
start - the first sample to cut

end - the last sample to cut

Returns:
the client, with a sound imported

Throws:
SoundTransformException - if the indexes are out of bound

FluentClientSoundImported.exportToClasspathResource
FluentClientWithFile exportToClasspathResource (String resource) throws SoundTransformException

Shortcut for exportToStream ().writeToClasspathResource (resource) : Conversion from a Sound to a File

Parameters:
resource - a resource that can be found in the classpath

Returns:
the client, with a file written

Throws:
SoundTransformException - if one of the two operations fails

FluentClientSoundImported.exportToClasspathResourceWithSiblingResource
FluentClientWithFile exportToClasspathResourceWithSiblingResource (String resource, String siblingResource) throws SoundTransformException

Shortcut for exportToStream ().writeToClasspathResourceWithSiblingResource (resource, siblingResource)

Parameters:
resource - a resource that may or may not exist in the classpath

siblingResource - a resource that can be found in the classpath.

Returns:
the client, with a file written

Throws:
SoundTransformException - if one of the two operations fails

FluentClientSoundImported.exportToFile
FluentClientWithFile exportToFile (File file)
throws SoundTransformException

Shortcut for exportToStream ().writeToFile (file)

Parameters:
file - the destination file

Returns:
the client, with a file written

Throws:
SoundTransformException - if one of the two operations fails

FluentClientSoundImported.exportToStream
FluentClientWithInputStream exportToStream () throws SoundTransformException

Uses the current imported sound and converts it into an InputStream, ready to be written to a file (or to be read again)

Returns:
the client, with an inputStream

Throws:
SoundTransformException - if the metadata format object is invalid, or if the sound cannot be converted

FluentClientWithSpectrums.extractSound
FluentClientSoundImported extractSound () throws SoundTransformException

Uses the current available spectrums objects to convert them into a sound (with one or more channels)

Returns:
the client, with a sound imported

Throws:
SoundTransformException - if the spectrums are in an invalid format, or if the transform to sound does not work

FluentClientSoundImported.extractSubSound
FluentClientSoundImported extractSubSound (int start, int end) throws SoundTransformException

Extracts a part of the sound between the sample #start and the sample #end

Parameters:
start - the first sample to extract

end - the last sample to extract

Returns:
the client, with a sound imported

Throws:
SoundTransformException - if the indexes are out of bound

FluentClientWithFreqs.filterRange
FluentClientWithFreqs filterRange (float low, float high)

Removes the values between low and high in the loudest freqs array (replace them by 0)

Parameters:
low - low frequency (first one to avoid)

high - high frequency (last one to avoid)

Returns:
the client, with a loudest frequencies float array

Throws:
SoundTransformException - can occur if low is greater than or equal to high

FluentClientSoundImported.findLoudestFrequencies
FluentClientWithFreqs findLoudestFrequencies () throws SoundTransformException  FluentClientWithFreqs findLoudestFrequencies (PeakFindSoundTransform<?, ?> peakFindSoundTransform) throws SoundTransformException

Parameter: (Optional) peakFindSoundTransform - a sound transform whose role is to find the loudest freqs array

Will invoke a soundtransform to find the loudest frequencies of the sound, chronologically Caution : the original sound will be lost, and it will be impossible to revert this conversion. When shaped into a sound, the new sound will only sound like the instrument you shaped the freqs with

Returns:
the client, with a loudest frequencies float array

Throws:
SoundTransformException - if the convert fails

FluentClientWithInputStream.importToSound
FluentClientSoundImported importToSound () throws SoundTransformException

Uses the current input stream object to convert it into a sound

Returns:
the client, with a sound imported

Throws:
SoundTransformException - the inputStream is invalid, or the convert did not work

FluentClientWithFile.importToStream
FluentClientWithInputStream importToStream () throws SoundTransformException

Opens the current file and converts it into an InputStream, ready to be read (or to be written to a file)

Returns:
the client, with an inputStream

Throws:
SoundTransformException - the current file is not valid, or the conversion did not work

FluentClientWithFreqs.insertPart
FluentClientWithFreqs insertPart (float [] subFreqs, int start)

Adds some new values in the loudest freqs array from the "start" index (add the values of subfreqs)

Parameters:
subFreqs - loudest freqs array to insert

start - index where to start the insert

Returns:
the client, with a loudest frequencies float array

FluentClientSoundImported.loop
FluentClientSoundImported loop (int length) throws SoundTransformException

Extracts a part of the sound between the sample #start and the sample #end

Parameters:
length - the number of samples of the result sound

Returns:
the client, with a sound imported

Throws:
SoundTransformException - if the length is not positive

FluentClientSoundImported.mergeChannels
FluentClientSoundImported mergeChannels () throws SoundTransformException

Converts a stereo sound into a mono sound with the channels mixed

Returns:
the client, with a sound imported

Throws:
SoundTransformException - if the sound is null or if the sound is already mono

FluentClientSoundImported.mixWith
FluentClientSoundImported mixWith (Sound sound) throws SoundTransformException

Combines the current sound with another sound. The operation is not reversible

Parameters:
sound - the sound to mix the current sound with

Returns:
the client, with a sound imported

Throws:
SoundTransformException - if the sound is null or if there is a problem with the mix

FluentClientWithParallelizedClients.mixAllInOneSound
FluentClientSoundImported mixAllInOneSound () throws SoundTransformException

Uses the sounds inside the nested clients to mix them all and to produce a single sound

Returns:
the client, with a sound imported

Throws:
SoundTransformException - if the nested clients are not in the Sound imported state

FluentClientWithFreqs.octaveDown
FluentClientWithFreqs octaveDown ()

Changes the loudest frequencies array to become one octave lower

Returns:
the client, with a loudest frequencies float array

FluentClientWithFreqs.octaveUp
FluentClientWithFreqs octaveUp ()

Changes the loudest frequencies array to become one octave upper

Returns:
the client, with a loudest frequencies float array

FluentClientSoundImported.playIt or FluentClientWithFile.playIt or FluentClientWithInputStream.playIt or FluentClientWithSpectrums.playIt
<T> T playIt () throws SoundTransformException  <T> T playIt (Object stopMonitor) throws SoundTransformException  <T> T playIt (Object stopMonitor, int skipMilliseconds) throws SoundTransformException

Parameters: (optional)
stopMonitor - calling notifyAll stops the player

skipMilliSeconds - starts playing at 'skipMilliSeconds' ms from the begining of the sound

Plays the current audio data

Returns:
the client, with the current data

Throws:
SoundTransformException - could not play the current audio data

FluentClientWithFreqs.replacePart
FluentClientWithFreqs replacePart (float [] subFreqs, int start)

Replaces some of the values of the loudest freqs array from t

Resources

ScratchView repo is UX Design involving scratch cards like views which are scratched to reveal the information they conceal.

Easy Video Player is a simple but powerful view that you can plugin to your apps to quickly get video playback working.

GIF library built with NDK.

Gradle plugin to optimize png files and reduce resultant apk size within an Android project.

PaperOnboarding is a material design slider.

Custom animated pull-to-refresh that can be easily added to RecyclerView.

Topics


2D Engines   3D Engines   9-Patch   Action Bars   Activities   ADB   Advertisements   Analytics   Animations   ANR   AOP   API   APK   APT   Architecture   Audio   Autocomplete   Background Processing   Backward Compatibility   Badges   Bar Codes   Benchmarking   Bitmaps   Bluetooth   Blur Effects   Bread Crumbs   BRMS   Browser Extensions   Build Systems   Bundles   Buttons   Caching   Camera   Canvas   Cards   Carousels   Changelog   Checkboxes   Cloud Storages   Color Analysis   Color Pickers   Colors   Comet/Push   Compass Sensors   Conferences   Content Providers   Continuous Integration   Crash Reports   Credit Cards   Credits   CSV   Curl/Flip   Data Binding   Data Generators   Data Structures   Database   Database Browsers   Date &   Debugging   Decompilers   Deep Links   Dependency Injections   Design   Design Patterns   Dex   Dialogs   Distributed Computing   Distribution Platforms   Download Managers   Drawables   Emoji   Emulators   EPUB   Equalizers &   Event Buses   Exception Handling   Face Recognition   Feedback &   File System   File/Directory   Fingerprint   Floating Action   Fonts   Forms   Fragments   FRP   FSM   Functional Programming   Gamepads   Games   Geocaching   Gestures   GIF   Glow Pad   Gradle Plugins   Graphics   Grid Views   Highlighting   HTML   HTTP Mocking   Icons   IDE   IDE Plugins   Image Croppers   Image Loaders   Image Pickers   Image Processing   Image Views   Instrumentation   Intents   Job Schedulers   JSON   Keyboard   Kotlin   Layouts   Library Demos   List View   List Views   Localization   Location   Lock Patterns   Logcat   Logging   Mails   Maps   Markdown   Mathematics   Maven Plugins   MBaaS   Media   Menus   Messaging   MIME   Mobile Web   Native Image   Navigation   NDK   Networking   NFC   NoSQL   Number Pickers   OAuth   Object Mocking   OCR Engines   OpenGL   ORM   Other Pickers   Parallax List   Parcelables   Particle Systems   Password Inputs   PDF   Permissions   Physics Engines   Platforms   Plugin Frameworks   Preferences   Progress Indicators   ProGuard   Properties   Protocol Buffer   Pull To   Purchases   Push/Pull   QR Codes   Quick Return   Radio Buttons   Range Bars   Ratings   Recycler Views   Resources   REST   Ripple Effects   RSS   Screenshots   Scripting   Scroll Views   SDK   Search Inputs   Security   Sensors   Services   Showcase Views   Signatures   Sliding Panels   Snackbars   SOAP   Social Networks   Spannable   Spinners   Splash Screens   SSH   Static Analysis   Status Bars   Styling   SVG   System   Tags   Task Managers   TDD &   Template Engines   Testing   Testing Tools   Text Formatting   Text Views   Text Watchers   Text-to   Toasts   Toolkits For   Tools   Tooltips   Trainings   TV   Twitter   Updaters   USB   User Stories   Utils   Validation   Video   View Adapters   View Pagers   Views   Watch Face   Wearable Data   Wearables   Weather   Web Tools   Web Views   WebRTC   WebSockets   Wheel Widgets   Wi-Fi   Widgets   Windows   Wizards   XML   XMPP   YAML   ZIP Codes