2016-04-14 4 views
0

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

Бывает с каждым типом звука .. с синусом он громче.

Вот код, я использую для генерации звука

int amp = 32767; 
double phase = 0.0; 

protected void onCreate(Bundle savedInstanceState) { 
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 
     AudioManager myAudioMgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 
     String nativeParam = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE); 
     sampleRate = Integer.parseInt(nativeParam); 
     nativeParam = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER); 
     bufSize = Integer.parseInt(nativeParam); 
    } 
    else { 
     sampleRate = 44100; 
     bufSize = AudioTrack.getMinBufferSize(sampleRate, 
       AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT); 
    } 

    audioOutput = new AudioOutput(); 
    audioOutput.Start(sampleRate, bufSize); 

    samples = new short[bufSize]; // buffer size is 512 

    playTask.execute(); 
} 

class PlayTask extends AsyncTask<Object, Void, Void> { 
    @Override 
    protected Void doInBackground(Object[] params) { 
     android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE); 

     while (!this.isCancelled()) { 
      while (touched) { 
       generateTone(); 
       audioOutput.write(samples, 0, samples.length); 
      } 
     } 
     return null; 
    } 
} 

private void generateTone() { 
    double phaseIncrement = (2 * Math.PI)/sampleRate; 
    switch (currentShape) { 
     case SINE: 
      for (int i = 0; i < bufSize; i++) { 
       samples[i] = (short) (amp * Math.sin(phase)); 
       phase += phaseIncrement * freq; 
       if (phase > 2 * Math.PI) 
        phase -= 2 * Math.PI; 
      } 
      break; 
     case SAWTOOTH: 
      for (int i = 0; i < bufSize; i++) { 
       samples[i] = (short) (amp * (phase - amp)); 
       phase += phaseIncrement * freq; 
       if (phase > 2 * Math.PI) 
        phase -= 2 * Math.PI; 
      } 
      break; 
     case SQUARE: 
      for (int i = 0; i < bufSize; i++) { 
       if (phase < Math.PI) 
        samples[i] = (short) amp; 
       else 
        samples[i] = (short) -amp; 
       phase += phaseIncrement * freq; 
       if (phase > 2 * Math.PI) 
        phase -= 2 * Math.PI; 
      } 
      break; 
    } 
} 

public class AudioOutput { 
    private AudioTrack mAudioTrack; 
    private int mFrameRate; 

    public void Start(int sampleRate, int bufferSize) { 
     Stop(); 
     mFrameRate = sampleRate; 
     mAudioTrack = createAudioTrack(bufferSize); 

     mAudioTrack.play(); 
    } 

    private AudioTrack createAudioTrack(int buffsize) { 
     return new AudioTrack(AudioManager.STREAM_MUSIC, 
       mFrameRate, AudioFormat.CHANNEL_OUT_MONO, 
       AudioFormat.ENCODING_PCM_16BIT, buffsize, 
       AudioTrack.MODE_STREAM); 
    } 

    public int write(short[] buffer, int offset, int length) { 
     return write = mAudioTrack.write(buffer, offset, length); 
    } 

    public void Stop() { 
     if (mAudioTrack != null) { 
      mAudioTrack.stop(); 
      mAudioTrack.release(); 
      mAudioTrack = null; 
     } 
    } 
} 

Аудио пример: https://soundcloud.com/syntey/sinewavetest

Любой знает, где может быть проблема?

Благодаря

+0

Вы можете дать ссылку на фактический файл волны? Я думаю, что больше информации можно было бы почерпнуть от взгляда на нее, чем от прослушивания. – jaket

+0

Sure http://www.mediafire.com/download/hotb3wpz7q3v2jc/sinewave+test.wav – Syntey

+0

Вы делаете выгорание в/из любого места в незарегистрированном коде? Сгенерированный сигнал явно имеет своего рода конверт. Также у синуса много искажений. – jaket

ответ

1

Вы не начала и окончания каждого буфера при переходе через нуль. Случайная фаза в начале каждого буфера, скорее всего, приведет к слишком резкому переходному временному сдвигу в самый первый образец. Конусность (с косинусным конусом) может помочь первая и последняя несколько десятков образцов от нуля до нуля.

+0

Я установил эту фазу реселлинга на 0, но я не могу понять ее. Знаете ли вы какой-то запрограммированный пример сужения? Я пытался найти что-то, но ничего .. Спасибо – Syntey