I am receiving bytes from a BLE device. The device is recording audio for 5 secs and sends it to an Android phone in pcm format.
- 8khz
- 4 channels
- 16-bit sample (2 bytes per sample).
- number of samples = 160 000
- 5 secs recording
I am a complete beginner in audio programming so trying to construct the wav header, I am following this link.
From the byte stream:
- The 3rd - 10th bytes are the data size to be received (ignore the first 3 bytes)
- the next bytes are the data in the form:
Channel-1 1st data point = 0th & 1st position, where 0th is LSB and 1st is MSB
Channel-2 1st data point = 2nd & 3rd position, where 0th is LSB and 1st is MSB
...
My questions are, how can I represent the above in dart and is my header below ok?
The header are these values in hex, little-endian except for the strings
52 49 46 46 “RIFF”
24 E2 04 00 FILE SIZE = 320044 - 8 = 320036
57 41 56 45 “WAVE”
66 6d 74 20 fmt
10 00 00 00 size of fmt subchunk = 16
01 00 pcm = 1
04 00 channels = 4
40 1F 00 00 sample rate = 8000
00 FA 00 00 byteRate = 64 000
08 00 blockAlign = 8
10 00 bits per sample = 16
64 61 74 61 “data”
00 E2 04 00 size of data = 320000
And this is the above header into a Uint8List to create a File from it with the data appended as Int8List
final header = Uint8List.fromList([ 82, 73, 70, 70, 36, 226, 4, 0, 87, 65, 86, 69, 102, 109, 116, 32, 1, 0, 0, 0, 0, 1, 0, 4, 64, 31, 0, 0, 0, 250, 0, 0, 8, 0, 1, 0, 100, 97, 116, 97, 0, 226, 4, 0, ]);
I was expecting to be able to play the wav file with the right header even if I dont modify the data bytes but keep getting this error:
I/ExoPlayerImpl(19598): Init 5dd78f5 [ExoPlayerLib/2.17.1] [raven, Pixel 6 Pro, Google, 33] W/io.platform.dev(19598): Accessing hidden method Landroid/media/AudioTrack;->getLatency()I (unsupported, reflection, allowed) E/LoadTask(19598): Unexpected exception loading stream E/LoadTask(19598): java.lang.IllegalStateException E/LoadTask(19598): at com.google.android.exoplayer2.util.Assertions.checkState(Assertions.java:84) E/LoadTask(19598): at com.google.android.exoplayer2.extractor.wav.WavHeaderReader.readFormat(WavHeaderReader.java:100) E/LoadTask(19598): at com.google.android.exoplayer2.extractor.wav.WavExtractor.readFormat(WavExtractor.java:175) E/LoadTask(19598): at com.google.android.exoplayer2.extractor.wav.WavExtractor.read(WavExtractor.java:134) E/LoadTask(19598): at com.google.android.exoplayer2.source.BundledExtractorsAdapter.read(BundledExtractorsAdapter.java:127) E/LoadTask(19598): at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1042) E/LoadTask(19598): at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:412) E/LoadTask(19598): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137) E/LoadTask(19598): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637) E/LoadTask(19598): at java.lang.Thread.run(Thread.java:1012) E/ExoPlayerImplInternal(19598): Playback error E/ExoPlayerImplInternal(19598): com.google.android.exoplayer2.ExoPlaybackException: Source error