2013-04-03 4 views
0

Я использую класс AudioRecord от https://github.com/nonameentername/soundtouch-android/blob/master/src/org/tecunhuman/ExtAudioRecorder.java, но с его небольшим изменением.Получить Android AudioRecord startRecording time delay

В методе start() я начинаю запись с класса AudioRecord. Я также начинаю MediaPlayer, чтобы сыграть инструментальную. Чтобы заставить вокал и инструментал перемешаться в правильных положениях на сервере, я посылаю инструментальную задержку, чтобы нанести инструментальное средство в начале с тишиной (битDelayInSeconds - MediaPlayer задержка с того момента, когда в нее запускается начало, так как есть латентность при запуске медиаплеера).

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

Для лучшего объяснения:

Запись голоса Начало

| ------------------------------ ---------- |

Бит/Инструментальная начинает играть после

[X] | -------------------------------- --------------- |

Я пытаюсь найти X, чтобы отправить метод startPlayback() как beatDelayInSeconds и на сервер. X - время между тем, когда голос начинает записываться до тех пор, пока бит не начнет играть. В настоящее время в моем методе startPlayback() воспроизводятся как ритм, так и вокал назад, они не синхронизированы, как это было записано. Надеюсь, это имеет смысл.

Примечание: Мне пришлось помещать обработчик задержки там для некоторых устройств Jelly Bean, потому что прослушиватель AudioRecord не вызывался.

public void start() 
{ 
    if (state == State.READY) 
    { 
     if (rUncompressed) 
     { 
      payloadSize = 0; 
      RecordReadDelayInSeconds = 0; 
      RecordDelayInSeconds = 0; 

      mPlayer = new MediaPlayer(); 

      try { 

       mPlayer.setDataSource(mp3Path); 

       mPlayer.prepare(); 

      } catch (IllegalArgumentException e) {e.printStackTrace();} 
       catch (SecurityException e) {e.printStackTrace();} 
       catch (IllegalStateException e) {e.printStackTrace();} 
       catch (IOException e) { e.printStackTrace();} 

      final long recordstarted = System.nanoTime() + 1500000000; //handler delay 

      audioRecorder.startRecording(); 

      //Fix for recording issue with Samsung s3 Sprint phones.Doing a delayed first read 
       new Handler().postDelayed(new Runnable() {      
        @Override 
        public void run() { 

         long recordstopped = System.nanoTime(); 

         long recordDelay = recordstopped - recordstarted; 

         double RecordDelayInSeconds = recordDelay/1000000.0; 

         Log.i("StartRecording() Delay in seconds", 
           String.valueOf(RecordDelayInSeconds)); 

         long recordreadstarted = System.nanoTime(); 

         int bytesReceived = audioRecorder.read(buffer, 0, buffer.length); 
         Log.d(TAG,"Delayed first read: bytes recieved "+ bytesReceived); 

         long recordreadstopped = System.nanoTime(); 

         long recordreadDelay = recordreadstopped - recordreadstarted; 

         RecordReadDelayInSeconds = recordreadDelay/1000000.0; 

         Log.i("Record read() Delay in seconds", 
           String.valueOf(RecordReadDelayInSeconds)); 

         long mediastarted = System.nanoTime(); 

         mPlayer.start(); 

         long mediastopped = System.nanoTime(); 

         long beatDelay = mediastopped - mediastarted; 

         beatDelayInSeconds = 0; 

         beatDelayInSeconds = (beatDelay)/1000000000.0; 

         Log.i("Beat Delay in seconds", 
           String.valueOf(beatDelayInSeconds)); 

        } 
       }, 1500); 
} 

Это код воспроизведения, который пользователь прослушивает перед отправкой информации на сервер. Сначала он запускает воспроизведение wav, который только что записал пользователь, а затем воспроизводит инструмент в соответствии с переменной beatDelayInSeconds от другого метода.

private void startPlayback() { 

    wavPlayer.start(); 
    RefreshHandler mp3PlaybackHandler = new RefreshHandler(); 
      mp3PlaybackHandler.sleep((long) (beatDelayInSeconds * 1000)); 

} 

class RefreshHandler extends Handler { 
    @Override 
    public void handleMessage(Message msg) { 
     mp3Player.start(); 
    } 

    public void sleep(long delayMillis) { 
     this.removeMessages(0); 
     Log.i(TAG, "Beat delayed for " + delayMillis + " milliseconds"); 
     sendMessageDelayed(obtainMessage(0), delayMillis); 
    } 
}; 
+0

@nawlrus .. В вашем вопросе вы указали «Чтобы синхронизировать их на сервере». Я понимаю, что вы пытаетесь записать и одновременно воспроизводить контент. Я не мог понять контекст воспроизводимого комментария. Не могли бы вы прояснить? – Ganesh

+0

Извините Ганеш. Я отредактировал и добавил дополнительную информацию. Я посылаю битDelayInseconds и запись recordDelay, которая равна RecordReadDelayInSeconds + RecordDelayInSeconds. Сервер позаботится о обработке мультимедиа оттуда, но я не думаю, что получаю правильные задержки там для обработки и для воспроизведения после записи. – nawlrus

+0

@nawlrus .. Так что, если я правильно понимаю, вы пытаетесь записать некоторые данные, поток его на сервер, получить то же самое с сервера и воспроизводить его на том же устройстве. Правильно ли это понимание? Если это верно, если во время воспроизведения включен сеанс записи, вы не встретите эхо или фоновое эхо в контуре петли? Это приемлемо? Еще один момент. Даже если у рекордера есть задержка при запуске, как только он начнет выводить данные, он должен придерживаться некоторых правил битрейта, поэтому даже если ваш медиапланер задерживается, он не должен иметь идеальный минимум. Разве это не так? – Ganesh

ответ

0

Я не понимаю «сроки всегда выключен»? что это значит?

Я не очень понятен в отношении вашего вопроса и вашего описания, но верно ли это: вы хотите отложить выполнение блока кода через определенный промежуток времени?

Если это так, вы должны подумать, вызывается ли ваш new Handler().postDelayed(..) внутри другой нити пользовательского интерфейса. Попробуйте это, если это процесс это деятельность по:

your_activity_instance.runOnUiThread(new Runnable() 
{ 
      @Override 
      public void run() 
      { 
       //delay with thread 
       try{ 
        Thread.sleep(1500); 
       }catch(.....) 
       {..} 

       //your work load here 
      } 
}); 

Примечание:

  • Handler.postDelayed() не создает отделенный поток для вашего блока кода, но только добавить новое сообщение (связанные с вашим Runnable instance) с таймером в текущей очереди сообщений потока.

  • activity.runOnUiThread() сделать нечто подобное, но Runnable.run() должен ждать, пока система не возвращается к деятельности UI нить затем excuted. Это полезно, если вы хотите выполнять работу какого-либо мероприятия в дочернем потоке.

Обновление для модифицированного вопроса:

Я могу понять ваши намерения: попытка выполнить wavPlayer.start() и mp3Player.start() в то же время; но ваше текущее решение не хорошо или даже невозможно:

  • В том же потоке, который вы используете обработчик, вы вряд ли будете синхронизировать 2 функции (как я упоминаю, handler.run() не икру отдельная нить).

  • вы не можете придавить точное время печати hanler.run() потому что управление системой, когда сообщение добавляются в очередь, пост с задержкой является относительной величиной.

Мое предложенное решение:

  • Вы икра отделенного потока для каждого игрока.

  • Перед каждым началом резьбы(), вы отметите метку времени (может использовать миллисекунды, не такой точности, чтобы использовать нано)

  • Во втором потоке, который называется позже, вы также перейти к нему в DELTA временных марок (различие между маркерами). Затем используйте Thread.Sleep() или Handler.postDelayed() для регулировки синхронизации.

+0

Отредактированный вопрос. Мне нужны вокалы и инструментальные средства для воспроизведения на устройстве так же, как они записывали его. В настоящее время воспроизведение не синхронизировано. Вокал будет либо задерживаться, либо слишком быстро по сравнению с инструментальным. – nawlrus