// Path: vorbis-support/src/main/java/com/github/trilarion/sound/sampled/AudioFormats.java
// public final class AudioFormats {
// 
//     private static final Logger LOG = Logger.getLogger(AudioFormats.class.getName());
// 
//     private static boolean doMatch(int i1, int i2) {
//         return i1 == AudioSystem.NOT_SPECIFIED
//                 || i2 == AudioSystem.NOT_SPECIFIED
//                 || i1 == i2;
//     }
// 
//     private static boolean doMatch(float f1, float f2) {
//         return f1 == AudioSystem.NOT_SPECIFIED
//                 || f2 == AudioSystem.NOT_SPECIFIED
//                 || Math.abs(f1 - f2) < 1.0e-9;
//     }
// 
//     /**
//      * Tests whether 2 AudioFormats have matching formats. A field matches when
//      * it is AudioSystem.NOT_SPECIFIED in at least one of the formats or the
//      * field is the same in both formats.<br>
//      * Exceptions:
//      * <ul>
//      * <li>Encoding must always be equal for a match.
//      * <li> For a match, endianness must be equal if SampleSizeInBits is not
//      * AudioSystem.NOT_SPECIFIED and greater than 8bit in both formats.<br>
//      * In other words: If SampleSizeInBits is AudioSystem.NOT_SPECIFIED in
//      * either format or both formats have a SampleSizeInBits smaller than 8, endianness does
//      * not matter. </ul> This is a proposition to be used as
//      * AudioFormat.matches. It can therefore be considered as a temporary
//      * workaround.
//      *
//      * @param format1
//      * @param format2
//      * @return
//      */
//     // IDEA: create a special "NOT_SPECIFIED" encoding
//     // and a AudioFormat.Encoding.matches method.
//     public static boolean matches(AudioFormat format1,
//                                   AudioFormat format2) {
//         //$$fb 19 Dec 99: endian must be checked, too.
//         //
//         // we do have a problem with redundant elements:
//         // e.g.
//         // encoding=ALAW || ULAW -> bigEndian and samplesizeinbits don't matter
//         // sample size in bits == 8 -> bigEndian doesn't matter
//         // sample size in bits > 8 -> PCM is always signed.
//         // This is an overall issue in JavaSound, I think.
//         // At present, it is not consistently implemented to support these
//         // redundancies and implicit definitions
//         //
//         // As a workaround of this issue I return in the converters
//         // all combinations, e.g. for ULAW I return bigEndian and !bigEndian formats.
//         /* old version
//          */
//         // as proposed by florian
//         return format1.getEncoding().equals(format2.getEncoding())
//                 && (format2.getSampleSizeInBits() <= 8
//                 || format1.getSampleSizeInBits() == AudioSystem.NOT_SPECIFIED
//                 || format2.getSampleSizeInBits() == AudioSystem.NOT_SPECIFIED
//                 || format1.isBigEndian() == format2.isBigEndian())
//                 && doMatch(format1.getChannels(), format2.getChannels())
//                 && doMatch(format1.getSampleSizeInBits(), format2.getSampleSizeInBits())
//                 && doMatch(format1.getFrameSize(), format2.getFrameSize())
//                 && doMatch(format1.getSampleRate(), format2.getSampleRate())
//                 && doMatch(format1.getFrameRate(), format2.getFrameRate());
//     }
// }


import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.spi.FormatConversionProvider;
import com.github.trilarion.sound.sampled.AudioFormats;
        return getAudioInputStream(targetFormat, audioInputStream);
    }

    /**
     * WARNING: this method uses
     * <code>getTargetFormats(AudioFormat.Encoding, AudioFormat)</code> which
     * may create infinite loops if the latter is overwritten.
     * <p>
     * This method is overwritten here to make use of
     * org.tritonus.share.sampled.AudioFormats.matches and is considered
     * temporary until AudioFormat.matches is corrected in the JavaSound API.
     *
     * @return
     */
    /* $$mp: if we decide to use getMatchingFormat(), this method should be
     implemented by simply calling getMatchingFormat() and comparing the
     result against null.
     */
    @Override
    public boolean isConversionSupported(
            AudioFormat targetFormat,
            AudioFormat sourceFormat) {
        LOG.log(Level.FINE, ">TFormatConversionProvider.isConversionSupported(AudioFormat, AudioFormat):");
        LOG.log(Level.FINE, "class: {0}", getClass().getName());
        LOG.log(Level.FINE, "checking if conversion possible");
        LOG.log(Level.FINE, "from: {0}", sourceFormat);
        LOG.log(Level.FINE, "to: {0}", targetFormat);
        AudioFormat[] aTargetFormats = getTargetFormats(targetFormat.getEncoding(), sourceFormat);
        for (AudioFormat aTargetFormat : aTargetFormats) {
            LOG.log(Level.FINE, "checking against possible target format: {0}", aTargetFormat);
// Path: vorbis-support/src/main/java/com/github/trilarion/sound/sampled/AudioFormats.java
// public final class AudioFormats {
// 
//     private static final Logger LOG = Logger.getLogger(AudioFormats.class.getName());
// 
//     private static boolean doMatch(int i1, int i2) {
//         return i1 == AudioSystem.NOT_SPECIFIED
//                 || i2 == AudioSystem.NOT_SPECIFIED
//                 || i1 == i2;
//     }
// 
//     private static boolean doMatch(float f1, float f2) {
//         return f1 == AudioSystem.NOT_SPECIFIED
//                 || f2 == AudioSystem.NOT_SPECIFIED
//                 || Math.abs(f1 - f2) < 1.0e-9;
//     }
// 
//     /**
//      * Tests whether 2 AudioFormats have matching formats. A field matches when
//      * it is AudioSystem.NOT_SPECIFIED in at least one of the formats or the
//      * field is the same in both formats.<br>
//      * Exceptions:
//      * <ul>
//      * <li>Encoding must always be equal for a match.
//      * <li> For a match, endianness must be equal if SampleSizeInBits is not
//      * AudioSystem.NOT_SPECIFIED and greater than 8bit in both formats.<br>
//      * In other words: If SampleSizeInBits is AudioSystem.NOT_SPECIFIED in
//      * either format or both formats have a SampleSizeInBits smaller than 8, endianness does
//      * not matter. </ul> This is a proposition to be used as
//      * AudioFormat.matches. It can therefore be considered as a temporary
//      * workaround.
//      *
//      * @param format1
//      * @param format2
//      * @return
//      */
//     // IDEA: create a special "NOT_SPECIFIED" encoding
//     // and a AudioFormat.Encoding.matches method.
//     public static boolean matches(AudioFormat format1,
//                                   AudioFormat format2) {
//         //$$fb 19 Dec 99: endian must be checked, too.
//         //
//         // we do have a problem with redundant elements:
//         // e.g.
//         // encoding=ALAW || ULAW -> bigEndian and samplesizeinbits don't matter
//         // sample size in bits == 8 -> bigEndian doesn't matter
//         // sample size in bits > 8 -> PCM is always signed.
//         // This is an overall issue in JavaSound, I think.
//         // At present, it is not consistently implemented to support these
//         // redundancies and implicit definitions
//         //
//         // As a workaround of this issue I return in the converters
//         // all combinations, e.g. for ULAW I return bigEndian and !bigEndian formats.
//         /* old version
//          */
//         // as proposed by florian
//         return format1.getEncoding().equals(format2.getEncoding())
//                 && (format2.getSampleSizeInBits() <= 8
//                 || format1.getSampleSizeInBits() == AudioSystem.NOT_SPECIFIED
//                 || format2.getSampleSizeInBits() == AudioSystem.NOT_SPECIFIED
//                 || format1.isBigEndian() == format2.isBigEndian())
//                 && doMatch(format1.getChannels(), format2.getChannels())
//                 && doMatch(format1.getSampleSizeInBits(), format2.getSampleSizeInBits())
//                 && doMatch(format1.getFrameSize(), format2.getFrameSize())
//                 && doMatch(format1.getSampleRate(), format2.getSampleRate())
//                 && doMatch(format1.getFrameRate(), format2.getFrameRate());
//     }
// }


// Path: vorbis-support/src/main/java/com/github/trilarion/sound/sampled/spi/TFormatConversionProvider.java
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.spi.FormatConversionProvider;
import com.github.trilarion.sound.sampled.AudioFormats;

        return getAudioInputStream(targetFormat, audioInputStream);
    }

    /**
     * WARNING: this method uses
     * <code>getTargetFormats(AudioFormat.Encoding, AudioFormat)</code> which
     * may create infinite loops if the latter is overwritten.
     * <p>
     * This method is overwritten here to make use of
     * org.tritonus.share.sampled.AudioFormats.matches and is considered
     * temporary until AudioFormat.matches is corrected in the JavaSound API.
     *
     * @return
     */
    /* $$mp: if we decide to use getMatchingFormat(), this method should be
     implemented by simply calling getMatchingFormat() and comparing the
     result against null.
     */
    @Override
    public boolean isConversionSupported(
            AudioFormat targetFormat,
            AudioFormat sourceFormat) {
        LOG.log(Level.FINE, ">TFormatConversionProvider.isConversionSupported(AudioFormat, AudioFormat):");
        LOG.log(Level.FINE, "class: {0}", getClass().getName());
        LOG.log(Level.FINE, "checking if conversion possible");
        LOG.log(Level.FINE, "from: {0}", sourceFormat);
        LOG.log(Level.FINE, "to: {0}", targetFormat);
        AudioFormat[] aTargetFormats = getTargetFormats(targetFormat.getEncoding(), sourceFormat);
        for (AudioFormat aTargetFormat : aTargetFormats) {
            LOG.log(Level.FINE, "checking against possible target format: {0}", aTargetFormat);
            if (aTargetFormat != null && AudioFormats.matches(aTargetFormat, targetFormat)) {