Change Clip using reflaction

A

Andrew Thompson

The javax.sound.sampled.Clip is a handy little class for small
clips, but it does not handle large clips (even if the JRE has
increased memory). I am trying* (and failing**) to alter the
returned clip to support a larger buffer.

Should this be possible, using reflection?

If so. How?

If not. Are there alternatives to this approach (short of
re-implementing Clip)?

*
<sscce>
import javax.sound.sampled.*;
import java.lang.reflect.*;

class TestClip {

static public String getBufferString(int size) {
return
"Clip buffer size " +
size +
". Enough buffer for " +
size/(44100.0*4) +
" sec of CD quality!";
}

public static void main(String[]args) throws Exception {
Clip clip = AudioSystem.getClip();

System.out.println( getBufferString(clip.getBufferSize()) );

Class clipClass = clip.getClass();

Method[] methods = clipClass.getMethods();
for (Method method : methods) {
if (method.getName().indexOf("setBufferSize")>-1) {
method.setAccessible(true);
method.invoke(clip, clip.getBufferSize()*8);
}
}

System.out.println( "After 1st attempt." );
System.out.println( getBufferString(clip.getBufferSize()) );

DataLine dl = (DataLine)clip;
Class dlClass = dl.getClass();
methods = dlClass.getMethods();
for (Method method : methods) {
if (method.getName().indexOf("setBufferSize")>-1) {
method.setAccessible(true);
method.invoke(dl, clip.getBufferSize()*8);
}
}

System.out.println( "After 2nd attempt." );
System.out.println( getBufferString(clip.getBufferSize()) );
}
}
</sscce>

**
<op>
andrew@pc1:/media/disk$ java TestClip
Clip buffer size 88200. Enough buffer for 0.5 sec of CD quality!
After 1st attempt.
Clip buffer size 88200. Enough buffer for 0.5 sec of CD quality!
After 2nd attempt.
Clip buffer size 88200. Enough buffer for 0.5 sec of CD quality!
andrew@pc1:/media/disk$
</op>
 
J

Joshua Cranmer

Andrew said:
The javax.sound.sampled.Clip is a handy little class for small
clips, but it does not handle large clips (even if the JRE has
increased memory). I am trying* (and failing**) to alter the
returned clip to support a larger buffer.

Should this be possible, using reflection?

Looking at the implementation in my Java implementation:
public int getBufferSize() {
return bufferSize;
}

/**
* This implementation does NOT change the buffer size
*/
public int setBufferSize(int newSize) {
return getBufferSize();
}

So there is no easy progmatic way to do it, unless you start messing
around with bufferSize directly. Which might not be the best of ideas.
 
A

Andrew Thompson

....
Looking at the implementation in my Java implementation:
...there is no easy progmatic way to do it, unless you start messing
around with bufferSize directly. Which might not be the best of ideas.

1) Thanks for your input. You are probably correct.(3)

2) My apologies for my late reply to this thread. Truth
is, I have been busy developing a Jukebox that is not
dependent on the Clip. It still has some distinct
oddities that need sorting though (most of which would
be easily sorted with a 'Big' Clip).

3) But I would eventually like to turn 'might not be
the best of ideas' into 'fails because..' (shrugs -
that's just the way I am).

4) ..But do not have the time at the moment, to adequately
address my entire failure to get access to the bufferSize
field, in order to do my hacking and get the result
mentioned in point 3.

I hope to revisit this topic in the future.
 
A

Andrew Thompson

The javax.sound.sampled.Clip is a handy little class for small
clips, but it does not handle large clips (even if the JRE has
increased memory).

Wrong!

I wish I could remember exactly what specific test
or result caused me to think that, because at this
very instant I can listen to a 23:57 length MP3* using
Clip in a JRE which defaults to ..512 Meg for some
reason.

Clip can also play longer (27:21) MP3s if the max
memory is increased, but it seems to lead to the
longer tracks playing in a 'jerky - stop/start'
fashion. I have not ruled out that the jerkyness
is an 'implementation detail' of the JRE though.

* All stereo, 16 bit, 44.1KHz.
System.out.println( getBufferString(clip.getBufferSize()) );

Wrong again! That was a dead-end. The buffer
size only relates to the size of the chunks the
Clip feeds to the DataLine. It is *not* the size
of the Clip's internal audio buffer.
----------

Doy! What a waste of time that all was.
The only salvageable part is to record my
later discoveries here, for the benefit of
anyone who might see the thread later.
 
A

Andrew Thompson


Wrong yet again! Maybe 3rd time lucky.
I wish I could remember exactly what specific test
or result caused me to think that, ..

It turned out to be different behaviours in different
JREs. I have (for some reason) 3 different JREs available
on this box. One is used for applets, another is used
for ant, and a third is used from the command line.

The one that I got from the command line (I don't
think it really matters* which JRE) was implemented
to allow Clips to the size of the available memory,
but others are typically not.

* It does not matter because..
- Generally Clips are limited in size, so there is
no benefit from further considering one 'aberrant'
JRE that will do better.
- I put 'aberrant' in inverted commas, since there
is no documentation as to how big a Clip should be
able to be, and as a result of that, any JRE that
can load a Clip of any size can be said to be
'compliant with the documentation'.
- I spent last night hacking together the parts of
the code that I had developed for playing large byte[]
arrays and ended up with a BigClip that implements
Clip in a way that is not 'useless and crappy'. It
still needs a lot of testing and work, but it'll do
for now.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,588
Members
45,100
Latest member
MelodeeFaj
Top