AudioTrack на Android неправильно воспроизводит потоковые аудиобайтыAndroid

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 AudioTrack на Android неправильно воспроизводит потоковые аудиобайты

Сообщение Anonymous »

Я записываю и транслирую звук через BLE на устройстве XIAO Esp32S3 Sense с помощью этого кода:

Код: Выделить всё

#include 
#include 
#include 
#include 
#include 

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define NOTIFY_CHARACTERISTIC_UUID "abc3483e-36e1-4688-b7f5-ea07361b26a8"
#define WRITE_CHARACTERISTIC_UUID "3cba5540-1d0b-4b0b-929f-81c2ec474cf4"

#define SAMPLE_RATE 16000U
#define SAMPLE_BITS 16
#define RECORD_TIME 5  // seconds

bool deviceConnected = false;
bool captureRequest = false;
bool recordingRequest = false;
int maxPacketSize = 509;  // BLE packet size limit

I2SClass I2S;
BLEServer *pServer;
BLECharacteristic *pNotifyCharacteristic;
BLECharacteristic *pWriteCharacteristic;

// BLE Callbacks to track connection/disconnection
class MyServerCallbacks : public BLEServerCallbacks {
  void onConnect(BLEServer* pServer) {
    deviceConnected = true;
    Serial.println("Device connected!");
  }

  void onDisconnect(BLEServer* pServer) {
    deviceConnected = false;
    Serial.println("Device disconnected!");
    BLEDevice::startAdvertising();
  }
};

// BLE Write Callback
class MyWriteCallbacks : public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *pCharacteristic) {
    String value = pCharacteristic->getValue();
    if (value == "START_RECORDING") {
      Serial.println("Recording request received.");
      recordingRequest = true;  // Set flag to start recording
    }
  }
};

// Function to record and stream audio over BLE for 20 seconds
void recordAndStreamAudio() {
  uint32_t record_size = (SAMPLE_RATE * SAMPLE_BITS / 8) * RECORD_TIME; // 20 seconds buffer
  uint8_t *rec_buffer = (uint8_t *)ps_malloc(record_size);  // Allocate buffer for recording
  if (rec_buffer == NULL) {
    Serial.println("Audio buffer malloc failed!");
    return;
  }

  Serial.printf("Recording for %d seconds...\n", RECORD_TIME);

  // Start recording
  uint32_t sample_size = I2S.readBytes((char*)rec_buffer, record_size);

  if (sample_size == 0) {
    Serial.println("Recording failed!");
    free(rec_buffer);
    return;
  } else {
    Serial.printf("Recorded %d bytes\n", sample_size);
  }

  // Stream recorded audio in chunks over BLE
  size_t offset = 0;
  while (offset < sample_size) {
    size_t chunk_size = min((size_t)maxPacketSize, (size_t)(sample_size - offset));
    uint8_t* chunk_data = rec_buffer + offset;
    pNotifyCharacteristic->setValue(chunk_data, chunk_size);
    pNotifyCharacteristic->notify();

    offset += chunk_size;
    delay(30);  // Small delay to avoid overwhelming BLE
  }

  // Send "END" to signal the end of transmission
  const char* terminator = "END_AUDIO";
  pNotifyCharacteristic->setValue((uint8_t*)terminator, 9);
  pNotifyCharacteristic->notify();

  free(rec_buffer);   // Release buffer memory
  Serial.println("Audio sent successfully over BLE.");
}

void setup() {
  Serial.begin(115200);

  // Initialize BLE
  BLEDevice::init("Mira_Glasses");
  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  BLEService *pService = pServer->createService(SERVICE_UUID);
 
  // Notify Characteristic for sending audio data
  pNotifyCharacteristic = pService->createCharacteristic(
      NOTIFY_CHARACTERISTIC_UUID,
      BLECharacteristic::PROPERTY_NOTIFY);
  pNotifyCharacteristic->addDescriptor(new BLE2902());

  // Write Characteristic for receiving recording requests
  pWriteCharacteristic = pService->createCharacteristic(
      WRITE_CHARACTERISTIC_UUID,
      BLECharacteristic::PROPERTY_WRITE);
  pWriteCharacteristic->setCallbacks(new MyWriteCallbacks());

  pService->start();
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  BLEDevice::startAdvertising();
  Serial.println("Waiting for client to connect...");

  // Setup I2S
  I2S.setPinsPdmRx(42, 41);
  if (!I2S.begin(I2S_MODE_PDM_RX, SAMPLE_RATE, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO)) {
    Serial.println("Failed to initialize I2S!");
    while (1);
  }

}

void loop() {
  if (deviceConnected && recordingRequest) {
    recordAndStreamAudio();  // Record and stream audio when request is received
    recordingRequest = false;  // Reset the request flag after recording
  }
}
Получение потоковых данных и работа с этим кодом:

Код: Выделить всё

package

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

private lateinit var audioTrack: AudioTrack
private const val SAMPLE_RATE = 16000
private const val CHANNEL_CONFIG = AudioFormat.CHANNEL_OUT_MONO
private const val AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT

fun initAudioTrack() {
val bufferSize = AudioTrack.getMinBufferSize(SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT)
audioTrack = AudioTrack( AudioManager.STREAM_MUSIC,
SAMPLE_RATE,
CHANNEL_CONFIG,
AUDIO_FORMAT,
bufferSize,
AudioTrack.MODE_STREAM
)

audioTrack.play()
}

fun playAudio(pcmData: ByteArray) {
// Write the PCM data to AudioTrack for playback
val written = audioTrack.write(pcmData, 0, pcmData.size)
if (written < 0) {
Log.e("AudioTrack", "Error writing audio data: $written")
}
}

fun releaseAudioTrack() {

audioTrack.stop()

audioTrack.release()
}
Но это всего лишь воспроизведение шума. Только ШУМ. Я измерил высоту звука, и высота соответствует тому, что я говорю на самом деле, но мы буквально не можем понять ни одного записанного слова.
Моя цель — воспроизводить потоковые аудиоданные в реальном времени. Мое устройство IoT — Little Endian, и я думаю, что Android также работает на Little Endian, так что, вероятно, это не может быть причиной шума.
Я считаю, что такие параметры конфигурации, как частота дискретизации, канал и т. д. одинаковы на устройствах IoT и Android, поэтому они должны работать должным образом, но почему они не работают?
Спасибо

Подробнее здесь: https://stackoverflow.com/questions/790 ... s-properly
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»