简体   繁体   English

生成和播放声音信号

[英]Generating and playing sound signals

I want to create app to play Morse Code.我想创建应用程序来播放摩尔斯电码。 To do this i find that you can generate sound by writing bytes array to AudoTrack object.为此,我发现您可以通过将字节数组写入 AudoTrack 对象来生成声音。 However, no matter of configuration, i can't hear any sound, even tho my Logs are saying, that every function i called correctly但是,无论配置如何,我都听不到任何声音,即使我的日志在说,我正确调用了每个函数

Main class主班

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();
            }
        });



    }


}



Const Class常量类

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 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();



            }

        }
    }

}

For now i only wrote dot function and silence, as other characters will base on those 2 functions, but onyl increase size of them by multiplying numer of samples ex audioTrack.write(samples, 0, 8000*3);现在我只写了点函数和静音,因为其他字符将基于这两个函数,但是只有通过乘以样本数来增加它们的大小,例如audioTrack.write(samples, 0, 8000*3); for playing line, not dot用于播放线,而不是点

I'm surprised you're not hearing a clicking sound (because of the transition from 15000 to 0).我很惊讶您没有听到咔嗒声(因为从 15000 过渡到 0)。 Anyway, you're not hearing any beeping because you didn't put an actual waveform into samples.无论如何,您没有听到任何哔哔声,因为您没有将实际波形放入样本中。 15000 is just a straight line. 15000只是一条直线。 Try a sine wave instead:尝试使用正弦波:

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

Whenever you write code to generate a wave, in memory, like this, it's a good idea to check the array in the debugger.每当您编写代码以在内存中生成波形时,就像这样,最好在调试器中检查数组。 That way you can make sure you did your math right.这样你就可以确保你的数学是正确的。 This one should show a wave, starting at 0, and undulating between roughly +15000 and -15000, with a period of about 44 samples.这应该显示一个波,从 0 开始,在大约 +15000 和 -15000 之间波动,周期约为 44 个样本。

Also, you want to make sure that your sound arrays are of a size of at least 8000, since that's how much you're trying to write() .此外,您要确保声音数组的大小至少为 8000,因为这是您尝试write() Make sure this line:确保这一行:

250 * 8000 / 1000

is using the correct sample rate:正在使用正确的采样率:

250 * SAMPLE_RATE_HZ / 1000

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

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