Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.example.armorvoicemodulator;
- import android.Manifest;
- import android.content.pm.PackageManager;
- import android.media.AudioFormat;
- import android.media.AudioManager;
- import android.media.AudioTrack;
- import android.os.Build;
- import android.os.Bundle;
- import android.util.Log;
- import androidx.annotation.NonNull;
- import androidx.appcompat.app.AppCompatActivity;
- import androidx.core.app.ActivityCompat;
- import androidx.core.content.ContextCompat;
- import be.tarsos.dsp.AudioDispatcher;
- import be.tarsos.dsp.io.android.AudioDispatcherFactory;
- import be.tarsos.dsp.WaveformSimilarityBasedOverlapAdd;
- import be.tarsos.dsp.resample.RateTransposer;
- import be.tarsos.dsp.filters.BandPass;
- import be.tarsos.dsp.effects.DelayEffect;
- import be.tarsos.dsp.GainProcessor;
- import be.tarsos.dsp.io.TarsosDSPAudioFormat;
- import be.tarsos.dsp.io.android.AndroidAudioPlayer;
- public class MainActivity extends AppCompatActivity {
- private static final int REQUEST_RECORD_AUDIO = 13;
- private AudioDispatcher dispatcher;
- private Thread audioThread;
- // Desired effect parameters
- private double pitchFactor = 1.0;
- private float gainFactor = 2.0f;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // No setContentView()—headless operation
- // 1) Check/request RECORD_AUDIO permission
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
- && ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
- != PackageManager.PERMISSION_GRANTED) {
- ActivityCompat.requestPermissions(
- this,
- new String[]{Manifest.permission.RECORD_AUDIO},
- REQUEST_RECORD_AUDIO
- );
- } else {
- startAudioProcessing(); // already have permission
- }
- }
- @Override
- public void onRequestPermissionsResult(int requestCode,
- @NonNull String[] permissions,
- @NonNull int[] grantResults) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- if (requestCode == REQUEST_RECORD_AUDIO
- && grantResults.length > 0
- && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- startAudioProcessing();
- } else {
- Log.e("VoiceModulator", "Permission denied. Exiting.");
- finish();
- }
- }
- private void startAudioProcessing() {
- // 2) Stop existing dispatcher if running
- if (audioThread != null && audioThread.isAlive()) {
- dispatcher.stop();
- audioThread = null;
- dispatcher = null;
- }
- // 3) Audio settings
- float sampleRate = 44100f;
- int sampleRateInt = (int) sampleRate;
- // Create WSOLA processor first
- WaveformSimilarityBasedOverlapAdd wsola =
- new WaveformSimilarityBasedOverlapAdd(
- WaveformSimilarityBasedOverlapAdd
- .Parameters.musicDefaults(pitchFactor, sampleRate)
- );
- // Retrieve buffer size and overlap from WSOLA
- int bufferSize = wsola.getInputBufferSize();
- int bufferOverlap = wsola.getOverlap();
- // 4) Create dispatcher with WSOLA's buffer size and overlap
- dispatcher = AudioDispatcherFactory.fromDefaultMicrophone(
- sampleRateInt,
- bufferSize,
- bufferOverlap
- );
- // 5) Set dispatcher for WSOLA
- wsola.setDispatcher(dispatcher);
- dispatcher.addAudioProcessor(wsola);
- // 6) Chain remaining effects
- dispatcher.addAudioProcessor(new RateTransposer(pitchFactor));
- dispatcher.addAudioProcessor(new BandPass(300f, 3000f, sampleRate));
- dispatcher.addAudioProcessor(new DelayEffect(0.09f, 0.3f, sampleRate));
- dispatcher.addAudioProcessor(new GainProcessor(gainFactor));
- // 7) Playback via AndroidAudioPlayer
- TarsosDSPAudioFormat tarsosFormat = new TarsosDSPAudioFormat(
- sampleRate, 16, 1, true, false
- );
- dispatcher.addAudioProcessor(
- new AndroidAudioPlayer(
- tarsosFormat,
- bufferSize,
- AudioManager.STREAM_MUSIC
- )
- );
- // 8) Launch processing thread
- audioThread = new Thread(dispatcher, "Audio Dispatcher");
- audioThread.start();
- Log.i("VoiceModulator", "Modulator started.");
- }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- if (audioThread != null && audioThread.isAlive()) {
- dispatcher.stop();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement