Android-аудио: изменение высоты тона - PullRequest
6 голосов
/ 29 октября 2011

Документация Android для SoundPool гласит: «Приложение также может изменять высоту звука, регулируя скорость воспроизведения в режиме реального времени для доплеровских эффектов или эффектов синтеза».Поэтому я попытался сделать это, используя метод setRate, чтобы плавно варьироваться от одной ноты к другой, но результат ужасен: вариации звука очень рваные.Вот код, который я попробовал.Пожалуйста, скажите мне, если есть лучший способ.

int streamId = soundPool.play (soundId, 1, 1, 1, 0, 1.0f);
for (float x = 0; x < 1; x += 0.005) {
  SystemClock.sleep (10);
  soundPool.setRate (streamId, 1 + x);
}

Ответы [ 2 ]

13 голосов
/ 18 ноября 2011

Несмотря на то, что в документации Android указано, что вы можете использовать setRate() для получения доплеровских эффектов, я бы не стал полагаться на быструю или достаточно хорошую реализацию на каждом устройстве Android.частота 44 кГц или 48 кГц.Следовательно, преобразование частоты дискретизации (т.е. изменение высоты тона) должно выполняться программно.Поскольку это включает в себя сокращение числа низкого уровня, я уверен, что это реализуется производителем устройства, а не Google.Учитывая большое разнообразие производителей устройств Android и часто используемое недорогое оборудование, существует множество реализаций преобразования частоты дискретизации.Некоторые быстрее, некоторые медленнее.Некоторые гладкие, некоторые рваные.

Что происходит при изменении коэффициента конверсии во время воспроизведения?Если алгоритм не совпадает по частям точно, возможно, при воспроизведении звука возникла короткая трещина.Вы меняете коэффициент конверсии каждые 10 миллисекунд.Если каждые 10 мс появляется трещина, это соответствует частоте 100 Гц, которая сама по себе является тоном.Вероятно, это то, что вы слышите как «рваный».

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

0 голосов
/ 20 мая 2012

Попробовав все, я решил использовать SoundPool, чтобы изменить высоту звука. При скорости воспроизведения 2,0 звук воспроизводится с частотой, удвоенной по сравнению с оригиналом, а при скорости воспроизведения 0,5 он воспроизводится вдвое меньше исходногочастота.Диапазон скорости воспроизведения составляет от 0,5 до 2,0.Но он работал с частотой ниже и выше, чем 0,5 и 2,0.

Я публикую свой рабочий код,

, но для демонстрационных целей здесь необходимо вручную изменять «скорость воспроизведения», каждый раз, когда вы устанавливаете приложение, например: «sp.play (Explosion, 1,1,0,0,1.5f) "здесь" 1.5f "- скорость воспроизведения.Можно легко создать EditView или что-то подобное, чтобы установить значение скорости воспроизведения во время выполнения.

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

import java.io.IOException;

import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class SoundPoolActivity extends Activity implements OnClickListener {

    SoundPool sp;
    int explosion = 0;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

       View v = new View(this);
       v.setOnClickListener(this);
       setContentView(v);
       sp = new SoundPool(1,AudioManager.STREAM_MUSIC,0);
       //explosion = sp.load(this, R.raw.hh,0);
       explosion = sp.load("/sdcard/hh.m4a",0);


    }


    public void onClick(View v){
         if (explosion!=0){

             sp.play(explosion, 1,1,0,0,2.3f);
         }

    }
}
...