У меня возникла проблема генерации гладкой волны синуса.Звуковая волна Android - негладкая и длительная проблема
Я сделал это несколько лет назад на C++, и все сработало отлично. Теперь я пытаюсь сделать это с помощью AudioTrack, и я не знаю, что не так.
Это мой тест:
Я хочу, чтобы произвести на пять второй пазухи волны, которая является гладкой (без трещин и т.п.). В течение одной секунды я генерирую 44100 выборок и разделяю их на пару буфера размером 8192 (вероятно, это причина трещин, но как я могу исправить это, не придавая большему размеру буфера). К сожалению, используя мой код, звук не является гладким и вместо 5 секунд занимает около 1 секунды. Я был бы благодарен за любую помощь. Пожалуйста, позвольте мне сейчас, если этого фрагмента недостаточно.
class Constants:
//<---
public final static int SAMPLING = 44100;
public final static int DEFAULT_GEN_DURATION = 1000;
public final static int DEFAULT_NUM_SAMPLES = DEFAULT_GEN_DURATION * SAMPLING/1000; //44100 per second
public final static int DEFAULT_BUFFER_SIZE = 8192;
//--->
//preparing buffers to play;
Buffer buffer = new Buffer();
short[] buffer_values = new short[Constants.DEFAULT_BUFFER_SIZE];
float[] samples = new float[Constants.DEFAULT_BUFFER_SIZE];
float d = (float) ((Constants.FREQUENCIES[index] * 2 * Math.PI)/Constants.SAMPLING);
int numSamples = Constants.DEFAULT_NUM_SAMPLES; //44100 per second - for test
float x = 0;
int index_in_buffer = 0;
for(int i = 0; i < numSamples; i++){
if(index_in_buffer >= Constants.DEFAULT_BUFFER_SIZE - 1){
buffer.setBufferShort(buffer_values);
buffer.setBufferSizeShort(index_in_buffer);
queue_with_data_AL.add(buffer); //add buffer to queue
buffer_values = new short[Constants.DEFAULT_BUFFER_SIZE];
samples = new float[Constants.DEFAULT_BUFFER_SIZE];
index_in_buffer = 0;
}
samples[index_in_buffer] = (float) Math.sin(x);
buffer_values[index_in_buffer] = (short) (samples[index_in_buffer] * Short.MAX_VALUE);
x += d;
index_in_buffer++;
}
buffer.setBufferShort(buffer_values);
buffer.setBufferSizeShort(index_in_buffer+1);
queue_with_data_AL.add(buffer);
index_in_buffer = 0;
}
//class AudioPlayer
public AudioPlayer(int sampleRate) { //44100
int minSize = AudioTrack.getMinBufferSize(sampleRate,
AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
audiotrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
minSize, AudioTrack.MODE_STREAM);
}
public void play(byte[] audioData, int sizeOfBuffer) {
audiotrack.write(audioData, 0, sizeOfBuffer);
}
public void start() {
if (state == Constants.STOP_STATE) {
state = Constants.START_STATE;
int startLength = 0;
while (state == Constants.START_STATE) {
Buffer buffer = getBufferFromQueueAL(); //getting buffer from prepared list
if (buffer != null) {
short[] data = buffer.getBufferShort();
int size_of_data = buffer.getBufferSizeShort();
if (data != null) {
int len = audiotrack.write(data, 0, size_of_data);
if (startLength == 0) {
audiotrack.play();
}
startLength += len;
} else {
break;
}
} else {
MessagesLog.e(TAG, "get null data");
break;
}
}
if (audiotrack != null) {
audiotrack.pause();
audiotrack.flush();
audiotrack.stop();
}
}
}
Извините, я не был достаточно ясен. Генератор синусовой волны находился в цикле, который повторял процедуру 5 раз. Несколько минут назад я добавил ответ, что не так. В любом случае, спасибо. – user1683637