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 ()
android.permission.READ_EXTERNAL_STORAGE
permission) :
With Android, you do (with the 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"));
android.permission.WRITE_EXTERNAL_STORAGE
permission):
With Android, you do (with the //... fluentClientWithSoundImported.exportToFile (new File (Environment.getExternalStorageDirectory () + "/file.wav"));
FluentClient Javadoc
Four steps can be identified when using the FluentClient SPI :
- static init (optional) : the observers subscribe to the future invocations of the FluentClient
- start of the flow : a call to
start ()
, followed by one or more calls to awith... ()
method - operations (optional) : several chained method calls to transform the data in a "one-lined" way
- 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