hendriks73 / ffsampledsp

FFmpeg based service provider for javax.sound.sampled.
GNU Lesser General Public License v2.1
24 stars 5 forks source link

[Question] How to read a file with a high sample rate? #15

Closed Kokecena closed 2 years ago

Kokecena commented 2 years ago

Hello, it's been a while, your library has surprised me a lot, it supports too many types of audio, so much so that even the teachers asked me what the hell I was using haha

Well I have a doubt, I was experimenting with the sample rate of the songs I have and it occurred to me to download a hi-fi song it works very well except that it takes up a lot of memory, I guess it's because of the way I load the song. I have tested on songs up to 176.4khz and they work fine, but i tried with 352khz and it didn't work anymore (i guess i should lower the sample rate), i don't know why exactly this is,.

This is the way i load AudioInputStream and SourceDataLine.

private void initAudioInputStream() throws JovisPlayerException {
        // Close any previous opened audio stream before creating a new one.
        closeAudioInputStream();
        if (audioStream == null) {
            try {
                logger.info("Data source: {}", audioSource);
                initAudioInputStream(audioSource);
                AudioFormat format = audioStream.getFormat();
                logger.info("Source format: {}", format);
                int nSampleSizeInBits = format.getSampleSizeInBits();
                if (nSampleSizeInBits <= 0) {
                    nSampleSizeInBits = 16;
                }
                if ((format.getEncoding() == AudioFormat.Encoding.ULAW) || (format.getEncoding() == AudioFormat.Encoding.ALAW)) {
                    nSampleSizeInBits = 16;
                }
                if (nSampleSizeInBits != 8) {
                    nSampleSizeInBits = 16;
                }
                targetFormat = new AudioFormat(FFAudioFormat.FFEncoding.PCM_SIGNED,
                        format.getSampleRate(),
                        nSampleSizeInBits,
                        format.getChannels(),
                        nSampleSizeInBits * format.getChannels() / 8,
                        format.getSampleRate(),
                        format.isBigEndian());
                audioStream = (FFAudioInputStream) AudioSystem.getAudioInputStream(targetFormat, audioStream);
                try {
                    if (equalizer) {
                        logger.info("Setting Equalizer....");
                        equalizerStream = new EqualizerInputStream(audioStream, IIR.EQ_10_BANDS, RestoreState.getEqualizerMode());
                        logger.info("Equalizer is Ready!");
                    } else {
                        equalizerStream = null;
                        logger.info("Equalizer is off :(");
                }
                } catch (Exception ex) {
                    equalizerStream = null;
                    logger.info("Equalizer not ready :( {}", ex.getMessage());
                }

               ....
               ....

            } catch (UnsupportedAudioFileException | IOException ex) {
                throw new JovisPlayerException(ex);
            }
        }

    }
private void initSourceDataLine() throws JovisPlayerException {
        if (sourceDataLine != null) {
            return;
        }
        try {
            logger.info("Create SourceDataLine");
            DataLine.Info lineInfo = new DataLine.Info(SourceDataLine.class, targetFormat);
            if (!AudioSystem.isLineSupported(lineInfo)) {
                throw new JovisPlayerException(lineInfo + "is not supported");
            }
            if (mixerName == null) {
                mixerName = getMixers().get(0);
            }
            Mixer mixer = getMixer(mixerName);
            if (mixer != null) {
                logger.info("Mixer: {}", mixer.getMixerInfo().toString());
                sourceDataLine = (SourceDataLine) mixer.getLine(lineInfo);
            } else {
                sourceDataLine = (SourceDataLine) AudioSystem.getLine(lineInfo);
                mixerName = null;
            }

            sourceDataLine.addLineListener(dss);
            logger.info("Line info: {}", sourceDataLine.getLineInfo().toString());
            logger.info("Line AudioFormat: {}", sourceDataLine.getFormat().toString());
            if (bufferSize <= 0) {
                bufferSize = sourceDataLine.getBufferSize();
            }
            sourceDataLine.open(targetFormat, bufferSize);
            logger.info("Line BufferSize: {}", sourceDataLine.getBufferSize());
            for (Control c : sourceDataLine.getControls()) {
                logger.info("Line Controls: {}", c);
            }
            if (sourceDataLine.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
                gainControl = (FloatControl) sourceDataLine.getControl(FloatControl.Type.MASTER_GAIN);
            }
            if (sourceDataLine.isControlSupported(FloatControl.Type.PAN)) {
                panControl = (FloatControl) sourceDataLine.getControl(FloatControl.Type.PAN);
            }
            if (sourceDataLine.isControlSupported(BooleanControl.Type.MUTE)) {
                muteControl = (BooleanControl) sourceDataLine.getControl(BooleanControl.Type.MUTE);
            }
            sourceDataLine.start();
            playerState = INIT;
            future = execService.submit(this);
            notifyEvent(JovisPlayback.OPENED);
        } catch (LineUnavailableException ex) {
            throw new JovisPlayerException(ex);
        }
    }

This is the error throws me java.util.concurrent.ExecutionException: jovis.audioplayer.JovisPlayerException: javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 352800.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian not supported.

works image

it does not work image

Kokecena commented 2 years ago

[Update] I was reading something about these audio frequencies and I found that they can be harmful to hearing, maybe it's a bad idea to let my player read these frequencies and moreover to be able to modify them with the equalizer and that 48khz are the safest...

hendriks73 commented 2 years ago

Check out the stacktrace of the javax.sound.sampled.LineUnavailableException—it's not thrown FFSampledSP, but by the audio system.

Kokecena commented 2 years ago

Check out the stacktrace of the javax.sound.sampled.LineUnavailableException—it's not thrown FFSampledSP, but by the audio system.

Sorry for the inconvenience, check and it's a Java error on Windows for some reason it doesn't recognize the devices ability to play 24 bit data, but on Mac and Linux it works, I will close this thread It doesn't influence your library, thanks anyway :)