Устранение щелчков по громкости на конвертере - Jsyn на Android - PullRequest
0 голосов
/ 24 мая 2018

Я ищу идеи о том, как обработать повторный запуск конвертов для новых заметок в монофонической установке сэмплера, вызывающих щелчки, если конверт предыдущей заметки еще не закончен.В текущей настройке экземпляр предыдущей заметки уничтожается на месте, когда запускается новая заметка (вызов метода synth.stop), вызывая щелчок, поскольку конверт не получает шанса закончить и достичь 0 тома.Любые намеки приветствуются.

Я также добавил в приведенный ниже код свое собственное неудовлетворительное решение, подавляя усиление голоса до 0, а затем переводя голос в спящий режим на 70 мс.Это вносит задержку в 70 мс во взаимодействие с пользователем, но избавляет от любых кликов.Любые значения ниже 70 мс во сне не решают щелчок.

В настоящий момент переменная является общедоступной статической, поэтому я все еще могу поиграть с тем, куда я их вызываю.

Здесьмой код слушателя:

buttonNoteC1Get.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            if (event.getAction() == MotionEvent.ACTION_UP) {
                buttonNoteC1Get.setBackgroundColor(myColorWhite); // reset gui color
                if (sample.getSustainBegin() > 0) { // trigger release for looping sample
                    ampEnv.dataQueue.queue(ampEnvelope, 3, 1); // release called
                }
                limit = 0; // reset action down limiter
                return true;
            }

            if (limit == 0) { // respond only to first touch event
                if (samplePlayer != null) { // check if a previous note exists
                    synth.stop(); // stop instance of previous note
                }
                buttonNoteC1Get.setBackgroundColor(myColorGrey); // key pressed gui color
                samplePitch = octave * 1; // set samplerate multiplier
                Sampler.player(); // call setup code for new note
                Sampler.play(); // play new note
                limit = 1; // prevent stacking of action down touch events
            }
            return false;
        }

    }); // end listener

Вот мой код сэмплера

public class Sampler {

public static VariableRateDataReader samplePlayer;
public static LineOut lineOut;
public static FloatSample sample;
public static SegmentedEnvelope ampEnvelope;
public static VariableRateMonoReader ampEnv;
public static MixerMonoRamped mixerMono;
public static double[] ampData;
public static FilterStateVariable mMainFilter;

public static Synthesizer synth = JSyn.createSynthesizer(new JSynAndroidAudioDevice());

// load the chosen sample, called by instrument select spinner
static void loadSample(){
    SampleLoader.setJavaSoundPreferred(false);
    try {
        sample = SampleLoader.loadFloatSample(sampleFile);
    } catch (IOException e) {
        e.printStackTrace();
    }
} // end load sample


// initialize sampler voice
static void player() {

 // Create an amplitude envelope and fill it with data.
 ampData = new double[] {
         envA, 0.9, //  pair 0, "attack"
         envD, envS, // pair 2, "decay"
         0, envS, // pair 3, "sustain"
         envR, 0.0, // pair 4, "release"
        /* 0.04, 0.0 // pair 5, "silence"*/

 };

    // initialize voice
    ampEnvelope = new SegmentedEnvelope(ampData);
    synth.add(ampEnv = new VariableRateMonoReader());
    synth.add(lineOut = new LineOut());
    synth.add(mixerMono = new MixerMonoRamped(2));
    synth.add(mMainFilter = new FilterStateVariable());

    // connect signal flow
    mixerMono.output.connect(mMainFilter.input);
    mMainFilter.output.connect(0, lineOut.input, 0);
    mMainFilter.output.connect(0, lineOut.input, 1);

    // set control values
    mixerMono.amplitude.set(sliderVal / 100.0f);
    mMainFilter.amplitude.set(0.9);
    mMainFilter.frequency.set(mainFilterCutFloat);
    mMainFilter.resonance.set(mainFilterResFloat);

    // initialize and connect sampler voice
 if (sample.getChannelsPerFrame() == 1) {
     synth.add(samplePlayer = new VariableRateMonoReader());
     ampEnv.output.connect(samplePlayer.amplitude);
     samplePlayer.output.connect(0, mixerMono.input, 0);
     samplePlayer.output.connect(0, mixerMono.input, 1);
 } else if (sample.getChannelsPerFrame() == 2) {
     synth.add(samplePlayer = new VariableRateStereoReader());
     ampEnv.output.connect(samplePlayer.amplitude);
     samplePlayer.output.connect(0, mixerMono.input, 0);
     samplePlayer.output.connect(1, mixerMono.input, 1);
 } else {
     throw new RuntimeException("Can only play mono or stereo samples.");
 }

} // end player

// play the sample
public static void play() {

    if (samplePlayer != null)
    {samplePlayer.dataQueue.clear();
        samplePlayer.rate.set(sample.getFrameRate() * samplePitch); // set pitch
    }

    // start the synth engine
    synth.start();
    lineOut.start();
    ampEnv.start();

   // play one shot sample
    if (sample.getSustainBegin() < 0) {
        samplePlayer.dataQueue.queue(sample);
        ampEnv.dataQueue.queue( ampEnvelope );

    // play sustaining sample
    } else {
        samplePlayer.dataQueue.queueOn(sample);
        ampEnv.dataQueue.queue( ampEnvelope, 0,3);
        ampEnv.dataQueue.queueLoop( ampEnvelope, 1, 2 );
    }
} } 

Неудовлетворительное решение, которое вводит задержку 70 мс, изменяя обработку прослушивателя действий предыдущей заметки на это:

 if (limit == 0) {
                if (samplePlayer != null) {
                    mixerMono.amplitude.set(0);
                    try {
                        synth.sleepFor(0.07);
                        synth.stop(); // stop instance of previous note
                    }catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

1 Ответ

0 голосов
/ 26 мая 2018

Вы не должны вызывать synth.start () и synth.stop () для каждой заметки.Думайте об этом как о включении физического синтезатора.Просто запустите синтезатор и строку сразу.Если ampEnv подключен косвенно к чему-то еще, что является start () ed, то вам не нужно запускать () ampEnv.

Затем просто поставьте свои сэмплы и конверты в очередь, когда хотите начать запись.

Когда вы закончите играть ноты, вызовите synth.stop ().

...