Звук Java - начальный громкий шум перед мягким шумом - PullRequest
1 голос
/ 21 февраля 2012

Я пытаюсь создать программу, которая будет генерировать звук с заданной громкостью в течение одной секунды на основе параметра. Я включил код ниже. В функции setUpSound() есть строка "control.setValue(integer)", которая управляет объемом. Например, если значение равно -30, в течение одной секунды будет действительно тихий звуковой сигнал. Если значение равно 20, в течение одной секунды будет очень громкий шум.

В тех случаях, когда шум мягкий (когда параметр находится в диапазоне от -30 до -10), возникает начальный громкий шум, который длится около 100 миллисекунд или около того, и затем включается мягкий обычный звук. Это звучит почти так, как будто звуковая карта на моих компьютерных существах испугалась за долю секунды, прежде чем она воспроизводит обычный нормальный звук. Имеет ли это смысл? Вы можете попробовать это на своей машине. Я использую MacBook Pro под управлением Lion.

Я пытаюсь выяснить, почему Java это делает и как ее решить?

import java.io.ByteArrayInputStream;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Test {

    FloatControl control;

    public static void main(String[] args) {
        Test test = new Test();
        test.setUpSound();
        test.loopSound(true);

        try {
            Thread.sleep(1000);
        } catch(Exception e) {

        }
        test.loopSound(false);
    }
    Clip clip;

     public void setUpSound() {

         /** Volume */

            try {

                generateTone();

                control = (FloatControl)
                        clip.getControl( FloatControl.Type.MASTER_GAIN );

             System.out.println("min volume: " + control.getMinimum());
             System.out.println("max volume " + control.getMaximum());
             System.out.println("end of sounds");

             control.setValue(-40);



            } catch(Exception e) {
                e.printStackTrace();
            }
        }

    public void loopSound(boolean commence) {
        if ( commence ) {
            clip.setFramePosition(0);
            clip.loop( Clip.LOOP_CONTINUOUSLY );
        } else {
            clip.stop();
        }
    }

    /** Generates a tone, and assigns it to the Clip. */
    public void generateTone()
        throws LineUnavailableException {
        if ( clip!=null ) {
            clip.stop();
            clip.close();
        } else {
            clip = AudioSystem.getClip();
        }
        boolean addHarmonic = true;

        int intSR = 10025;
        int intFPW = 20;
        System.out.println("sampleRate = " + intSR);
        System.out.println("framesPerWavelength = " + intFPW);

        float sampleRate = (float)intSR;

        // oddly, the sound does not loop well for less than
        // around 5 or so, wavelengths
        int wavelengths = 5;
        byte[] buf = new byte[2*intFPW*wavelengths];
        AudioFormat af = new AudioFormat(
            sampleRate,
            8,  // sample size in bits
            2,  // channels
            true,  // signed
            false  // bigendian
            );

        for(int i=0; i<intFPW*wavelengths; i++){
            double angle = ((float)(i*2)/((float)intFPW))*(Math.PI);
            buf[i*2]=getByteValue(angle);
            if(addHarmonic) {
                buf[(i*2)+1]=getByteValue(2*angle);
            } else {
                buf[(i*2)+1] = buf[i*2];
            }
        }

        try {
            byte[] b = buf;
            AudioInputStream ais = new AudioInputStream(
                new ByteArrayInputStream(b),
                af,
                buf.length/2 );

            clip.open( ais );
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    /** Provides the byte value for this point in the sinusoidal wave. */
    private static byte getByteValue(double angle) {
        int maxVol = 127;
        return (new Integer(
            (int)Math.round(
            Math.sin(angle)*maxVol))).
            byteValue();
    }
}

1 Ответ

1 голос
/ 21 февраля 2012

.. как решить?

Оставьте мастер-громкость в покое и отрегулируйте громкость, используя другой параметр, для метода getByteValue() (возвращайте меньшие значения байтов для мягких звуков).


.. использовать другой параметр ..

И.Е.
- Измените getByteValue() на getByteValue(float scale).
- throw и IllegalArgumentException, если диапазон находится за пределами 0.0f - 1.0f. - Умножьте значение сигнала в этот момент на значение scale.

Если для scale указано значение 0,5f, звук будет менее громким, чем если бы оно было 1,0f.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...