2017-02-20 8 views
0

다음은 android studio에서 연속 사인파를 생성하는 데 사용하는 코드입니다. 모든 것은 스레드 내에서 실행됩니다. 내 질문은 : 내가 audio.write()를 호출하면 버퍼에 남아있을 수있는 데이터는 어떻게 될까요? 이전 샘플을 덤프하고 새 세트를 작성합니까 아니면 나머지 샘플에 새 샘플 배열을 추가합니까?AudioTrack.write()의 버퍼에있는 데이터는 어떻게됩니까?

int buffSize = AudioTrack.getMinBufferSize(sr, AudioFormat.CHANNEL_OUT_MONO,AudioFormat.ENCODING_PCM_16BIT); 
      //create the AudioTrack object 
      AudioTrack audio = new AudioTrack( AudioManager.STREAM_MUSIC, 
               sr, 
               AudioFormat.CHANNEL_OUT_MONO, 
               AudioFormat.ENCODING_PCM_16BIT, 
               buffSize, 
               AudioTrack.MODE_STREAM); 
      //initialise values for synthesis 
      short samples[]= new short[buffSize]; //array the same size as buffer 
      int amp=10000;       //amplitude of the waveform 
      double twopi = 8.*Math.tan(1.);   //2*pi 
      double fr = 440;      //the frequency to create 
      double ph = 0;       //phase shift 
      //start audio 
      audio.play(); 
      //synthesis loop 
      while (isRunning) 
      { 
       fr=440+4.4*sliderVal; 

       for (int i=0;i<buffSize;i++) 
       { 
         samples[i]=(short)(amp*Math.sin(ph)); 
         ph+=twopi*fr/sr; 
       } 
       audio.write(samples,0,buffSize); 
      } 
      //stop the audio track 
      audio.stop(); 
      audio.release(); 

답변

0

대기 시간을 최소화하기 위해 매우 중요한 장치 기능에 따라 버퍼 크기를 올바르게 설정하고 있습니다.

그런 다음 버퍼를 만들고 하드웨어로 청취하여 청취 할 수 있습니다. 말에는 "거기"가 없습니다. 버퍼가 만들어지고, 매번 buffer.write에 전체 버퍼를 씁니다.

다음은 내 generateTone 루틴입니다. MS에서의 진동수 (Hz)와 지속 시간과 같은 같은 호출 :

AudioTrack sound = generateTone(440, 250); 

그리고 generateTone 클래스 : 당신이 바로 너 한테이있는 경우 소리의 모든 종류를 만들 수 있기 때문에

private AudioTrack generateTone(double freqHz, int durationMs) { 
    int count = (int)(44100.0 * 2.0 * (durationMs/1000.0)) & ~1; 
    short[] samples = new short[count]; 
    for(int i = 0; i < count; i += 2){ 
     short sample = (short)(Math.sin(2 * Math.PI * i/(44100.0/freqHz)) * 0x7FFF); 
     samples[i + 0] = sample; 
     samples[i + 1] = sample; 
    } 
    AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, 
    AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, 
    count * (Short.SIZE/8), AudioTrack.MODE_STATIC); 
    track.write(samples, 0, count); 
    return track; 
} 

AudioTrack이 멋지다. Puredata와 Csound는 안드로이드에서 훨씬 쉽게 해줍니다.

는 의견을

+0

감사합니다 (I는. 실제 프로젝트의 내 책 안드로이드 소프트웨어 개발 - 컬렉션에 오디오에 큰 장을 썼다) 바른 길에 저를 얻었다. 다음 x 샘플을 작성하기 전에 x 샘플을 재생했는지 확인하기 위해 동기화가 필요한 경우가 있습니까? – Johan

+0

듣기 좋습니다! 글쎄, 당신은 동기화 할 필요는 없지만, "계속"해야합니다. 버퍼 크기 블록을 충분히 빠르게 채울 수 없으면 건너 뛰기 또는 중단이 발생합니다. 당신은 당신이 그것을들을 수 있기 때문에 이것이 일어난다는 것을 알고 있습니다. 이것은 오디오 대기 시간 문제 때문에 Android에서 큰 문제입니다. 지금까지 제작 된 모든 Android 기기는 생성 된 모든 iOS 기기보다 대기 시간이 길다. 믿기 ​​어렵지만 사실입니다. AudioBuffersSize라고하는 정말 좋은 Google 오픈 소스 앱이 있습니다.이 앱은 buffersize 및 samplerate와 같이 기기의 기능을 보여줍니다. 그런 다음 오디오 앱에서 올바르게 설정할 수 있습니다. –

+0

고마워요! 그 문제는 아직 발생하지 않았습니다. 별도의 가벼운 writeToBuffer 쓰레드를 작성하는 것이 좋은 생각일까요? – Johan