Какие параметры нужны для AndroidTrack AudioTrack для воспроизведения выходных данных TextToSpeech.synthesizeToFile? - PullRequest
0 голосов
/ 16 января 2019

Я хочу воспроизвести вывод Android TextToSpeech.synthesizeToFile , используя AudioTrack , но боюсь, что я передаю сборщикам AudioTrack неправильные параметры. Я скопировал один из файлов, созданных с помощью TextToSpeech.synthesizeToFile, используя adb, и вставил этот файл github , если вы хотите увидеть вывод TextToSpeech.synthesizeToFile для себя. Когда я запускаю play tempSoundFile8290688667049742717.wav в Linux, файл воспроизводит текст, который я написал ( hello world ), и печатает следующее:

play WARN alsa: can't encode 0-bit Unknown or not applicable

tempSoundFile8290688667049742717.wav:

 File Size: 39.4k     Bit Rate: 353k
  Encoding: Signed PCM    
  Channels: 1 @ 16-bit   
Samplerate: 22050Hz      
Replaygain: off         
  Duration: 00:00:00.89  

In:100%  00:00:00.89 [00:00:00.00] Out:19.7k [!=====|=====!]        Clip:0    
Done.

соответственно, я устанавливаю параметры AudioTrack следующим образом:

private AudioDeviceInfo findAudioDevice(int deviceFlag, int deviceType) {
    AudioManager manager = (AudioManager) this.context.getSystemService(Context.AUDIO_SERVICE);
    AudioDeviceInfo[] adis = manager.getDevices(deviceFlag);
    for (AudioDeviceInfo adi : adis) {
        if (adi.getType() == deviceType) {
            return adi;
        }
    }
    return null;
}

AudioDeviceInfo mAudioOutputDevice = findAudioDevice(AudioManager.GET_DEVICES_OUTPUTS,
        AudioDeviceInfo.TYPE_BUS);

AudioAttributes.Builder audioAttributesBuilder = new AudioAttributes.Builder().
        setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING).
        setContentType(AudioAttributes.CONTENT_TYPE_SPEECH).
        setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED);
attributes = audioAttributesBuilder.build();

int minBufferSize = AudioTrack.getMinBufferSize(22050, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);

AudioTrack.Builder atBuilder = new AudioTrack.Builder();
//builder.setAudioAttributes()
AudioFormat.Builder afBuilder = new AudioFormat.Builder();

afBuilder.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
        .setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
        .setSampleRate(22050);

atBuilder.setAudioFormat(afBuilder.build())
        .setTransferMode(AudioTrack.MODE_STREAM)
        .setBufferSizeInBytes(minBufferSize)
        .setAudioAttributes(attributes);


at = atBuilder.build();
at.setPreferredDevice(mAudioOutputDevice);

File myFile = File.createTempFile("tempSoundFile", ".wav");
            myFile.deleteOnExit();
            myFile.setWritable(true);
            myFile.setReadable(true);

и позже воспроизводит файл, используя код из здесь :

/**
* Code taken from here:
* /7213439/android-audiotrack-vosproizvodit-wav-fail-poluchaya-tolko-belyi-shum
*/
private void playWav(){
    Log.d(TAG, "Playing speech to text wav file");
    String filepath = this.myFile.getAbsolutePath();

    int i = 0;
    int BUFFER_SIZE = 512;
    byte[] s = new byte[BUFFER_SIZE];
    try {
        Log.i(TAG, "file path is: " + filepath);
        FileInputStream fin = new FileInputStream(filepath);
        DataInputStream dis = new DataInputStream(fin);


        at.play();

        while((i = dis.read(s, 0, BUFFER_SIZE)) > -1){
            at.write(s, 0, i);
            Log.v(TAG, Arrays.toString(s));

        }
        at.stop();
        at.release();
        dis.close();
        fin.close();

    } catch (FileNotFoundException e) {
        // TODO
        e.printStackTrace();
    } catch (IOException e) {
        // TODO
        e.printStackTrace();
    }
}

Конечно, их вызовы распределены по разным асинхронным вызовам, как вы можете видеть в моем коде , но я отлаживал все это с помощью операторов журнала и отладчика и не вижу никаких проблем. playWav () получает удар, когда я ожидаю, но ничего не играет.

редактирование:

Моя основная мотивация для использования AudioTrack - сделать его совместимым с TextToSpeech с голосовым набором raspberry pi библиотека вещей для Android . Использование AudioTrack позволит мне воспроизводить textToSpeech через I2S (или любой другой динамик, который я выберу).

редактировать 2, более глубокий взгляд:

Согласно этому веб-сайту , wav-файлы имеют 44-байтовый заголовок, который сообщает обо всех этих параметрах. В этом заголовке по адресу:

  • позиция 20, 2 байта, которые определяют тип файла (little-endian) (16 для PCM)
  • позиция 22, 2 байта, которые определяют количество каналов (1 для моно, 2 для стерео) (младший порядок)
  • позиция 24, 4 байта, которые определяют частоту дискретизации (little-endian)
  • и, наконец, в позиции 34, 2 байта определяют биты на выборку (младший порядок)

вот шестнадцатеричный дамп вышеупомянутого файла:

$ hd -n 44 tempSoundFile8290688667049742717.wav 
00000000  52 49 46 46 f8 99 00 00  57 41 56 45 66 6d 74 20  |RIFF....WAVEfmt |
00000010  10 00 00 <b>00 01 00 01 00  22 56</b> 00 00 44 ac 00 00  |........"V..D...|
00000020  02 <b>00 10</b> 00 64 61 74 61  d4 99 00 00              |....data....|
0000002c
...