繁体   English   中英

生成和播放声音信号

[英]Generating and playing sound signals

我想创建应用程序来播放摩尔斯电码。 为此,我发现您可以通过将字节数组写入 AudoTrack 对象来生成声音。 但是,无论配置如何,我都听不到任何声音,即使我的日志在说,我正确调用了每个函数

主班

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.media.MediaPlayer;
import android.media.ToneGenerator;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.util.Random;

public class MainActivity extends AppCompatActivity {

    Consts Cons = new Consts();
    final int patternLenght = 10;
    String pattern;
    int[] soundArray = new int[patternLenght * 2];
    MediaPlayer[] mp = new MediaPlayer[patternLenght * 2];
    int userInputCorrectNumber;


    private String GeneratePattern(int lenght) {
        String patterngen = "";
        Random rand = new Random();
        for (int i = 0; i < lenght; i++) {
            int n = rand.nextInt(2);
            String temp = Cons.ALFABET[n];
            patterngen = patterngen + temp;
        }
        pattern = patterngen;

        return patterngen;
    }




    private void PlayPattern(){
    BeepClassMain.SetUpEverything();
    BeepClassMain.GenerateSoundWave();
    String morsePat=BeepClassMain.ConvertPatternToMorsePattern(pattern);
    BeepClassMain.PlayPattern(morsePat);

    }





    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        Button start = findViewById(R.id.make_pattern);
        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pattern = GeneratePattern(patternLenght);
                Log.i("Pattern", pattern);
            }
        });

        Button playpattern = findViewById(R.id.playPattern);
        playpattern.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                PlayPattern();
            }
        });



    }


}



常量类

public class Consts {final String ALFABET[] = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; }

BeepClassMain

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.util.Log;

public class BeepClassMain {
    private static AudioTrack audioTrack;
    private static int SAMPLE_RATE_HZ = 48000;
    private static int numofSamples;
    private static short samples[];
    private static short silenceTab[];


    public static void SetUpEverything() {
        int bufferSize = AudioTrack.getMinBufferSize(SAMPLE_RATE_HZ, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE_HZ, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize, AudioTrack.MODE_STREAM);
        audioTrack.setStereoVolume(AudioTrack.getMaxVolume(), AudioTrack.getMaxVolume());
        numofSamples = 250 * 8000 / 1000; // duration in ms * samplerate/1000
        samples = new short[numofSamples];
        silenceTab=new short[numofSamples];

    }

    public static void GenerateSoundWave() {
        for (int i = 0; i < numofSamples; i++) {
            samples[i] = 15000; //example numbers of generated sound
            silenceTab[i]=0; //no value, silence
        }
    }


    public static String ConvertPatternToMorsePattern(String pattern) {
        String morsePattern = "";
        GenerateSoundWave();

        for (int i = 0; i < pattern.length(); i++) {
            if (pattern.charAt(i) == 'A') morsePattern += ".- ";
            if (pattern.charAt(i) == 'B') morsePattern += "-... ";
            if (pattern.charAt(i) == 'C') morsePattern += "-.-. ";
            if (pattern.charAt(i) == 'D') morsePattern += "-.. ";
            if (pattern.charAt(i) == 'E') morsePattern += ". ";
            if (pattern.charAt(i) == 'F') morsePattern += "..-. ";
            if (pattern.charAt(i) == 'G') morsePattern += "--. ";
            if (pattern.charAt(i) == 'H') morsePattern += ".... ";
            if (pattern.charAt(i) == 'I') morsePattern += ".. ";
            if (pattern.charAt(i) == 'J') morsePattern += ".--- ";
            if (pattern.charAt(i) == 'K') morsePattern += "-.- ";
            if (pattern.charAt(i) == 'L') morsePattern += ".-.. ";
            if (pattern.charAt(i) == 'M') morsePattern += "-- ";
            if (pattern.charAt(i) == 'N') morsePattern += "-. ";
            if (pattern.charAt(i) == 'O') morsePattern += "--- ";
            if (pattern.charAt(i) == 'P') morsePattern += ".--. ";
            if (pattern.charAt(i) == 'Q') morsePattern += "--.- ";
            if (pattern.charAt(i) == 'R') morsePattern += ".-. ";
            if (pattern.charAt(i) == 'S') morsePattern += "... ";
            if (pattern.charAt(i) == 'T') morsePattern += "- ";
            if (pattern.charAt(i) == 'U') morsePattern += "..- ";
            if (pattern.charAt(i) == 'V') morsePattern += "...- ";
            if (pattern.charAt(i) == 'W') morsePattern += ".-- ";
            if (pattern.charAt(i) == 'X') morsePattern += "-..- ";
            if (pattern.charAt(i) == 'Y') morsePattern += "-.-- ";
            if (pattern.charAt(i) == 'Z') morsePattern += "--.. ";

        }
        Log.i("patterntomorsebeep", morsePattern);
        return morsePattern;

    }


    private static void PlayDot() {
        audioTrack.write(samples, 0, 8000);


    }
    private static void PlaySilence(){
    audioTrack.write(silenceTab,0,8000);
    }


    public static int isStillSameCharacter(String morsePattern, int i) {

        if (morsePattern.charAt(i + 1) == '.' || morsePattern.charAt(i + 1) == '-') return 1;

        else return 0;
    }


    public static void PlayPattern(String morsePattern) {


        audioTrack.play();
        for (int i = 0; i < morsePattern.length(); i++) {




            if (morsePattern.charAt(i) == '.') {


                PlayDot();
                if (isStillSameCharacter(morsePattern, i) == 1) continue;
                PlaySilence();



            }

        }
    }

}

现在我只写了点函数和静音,因为其他字符将基于这两个函数,但是只有通过乘以样本数来增加它们的大小,例如audioTrack.write(samples, 0, 8000*3); 用于播放线,而不是点

我很惊讶您没有听到咔嗒声(因为从 15000 过渡到 0)。 无论如何,您没有听到任何哔哔声,因为您没有将实际波形放入样本中。 15000只是一条直线。 尝试使用正弦波:

samples[i] = (short) (Math.sin(i*1000.0f/*Hz*//SAMPLE_RATE_HZ*Math.PI*2)*15000/*Amp*/);

每当您编写代码以在内存中生成波形时,就像这样,最好在调试器中检查数组。 这样你就可以确保你的数学是正确的。 这应该显示一个波,从 0 开始,在大约 +15000 和 -15000 之间波动,周期约为 44 个样本。

此外,您要确保声音数组的大小至少为 8000,因为这是您尝试write() 确保这一行:

250 * 8000 / 1000

正在使用正确的采样率:

250 * SAMPLE_RATE_HZ / 1000

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM