Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recording .wav to file creating bloated file with invalid header data #280

Open
austibwu opened this issue Jan 30, 2024 · 5 comments
Open
Labels
bug Something isn't working macOS

Comments

@austibwu
Copy link

austibwu commented Jan 30, 2024

Package version
5.0.4

Environment

  • OS: MacOS 14.3

Describe the bug
Currently only tested on MacOS. When recording to file with .wav encoding set, the resulting file is consistently ~2.34x larger than expected (duration, bitrate, #channels have been defined), and does not have valid header data. When parsed out the first 44 bytes of the output file reads:
RIFF (#number of bytes in the file) WAVE JUNK 0 0 0 0 0 0 , a number of empty entries, and lastly followed by a 0.
In this case, the recording was set to 2000 ms and was expected to see a file size of 176kb but output to 411604. The ratio of file size difference is consistent with longer files as well.

I am not certain where the code for writing the recorded data to file is located, as I was not able to find it following the method calls. I saw in the web folder there is a pcm and wav_encoder file with methods to write proper but it does not seem to be called in the record-to-file 'start' call pathway nor does the wav_encoder's expected output match what I am seeing written to file.

Add your record configuration RecordConfig(...)
code related to record used is as follows:

import 'package:flutter/foundation.dart';
import 'package:audiotestproject/components/data/global.dart';
import 'package:record/record.dart';

final x = Singleton();

void playLogic() async {
  final AudioRecorder audioRecorder = AudioRecorder();
  const config = RecordConfig(encoder: AudioEncoder.wav, bitRate: 705600, numChannels: 1);

  await audioRecorder.start(config, path: '/Users/austibwu/Documents/record_project/assets/wave_in.wav');
  await x.player.resume();

  var status = x.player.onPlayerComplete;
  status.listen((event) async {
    print('Recorded file path: ${await audioRecorder.stop()}');    
  });
}

To Reproduce

Steps to reproduce the behavior:
Rudimentary implementation of records package as seen above, no modifications to basic recorder instance beyond path and recording config.

Expected behavior
correctly formatted .wav header data written as seen in record_web/lib/encoder/wav_encoder.dart or similar, and volume of data in the body matching the expected output for the given duration, bitdepth, #channels, and sampling rate.

Additional context
I'm a bit confused on the excess file size because the .wav file still plays out to the correct duration.

It doesn't seem like this is a shared experience so I'm wondering if I have done something wrong in my implementation, or simply missed a folder in the package.

@austibwu
Copy link
Author

austibwu commented Jan 31, 2024

Just saw that when config encoder is defined as wav or pcm16bit, the recording is always written in 32 bits per sample, 48kHz sample rate and monochannel. This is interesting for the pcm one because.. expected output is 16bit.

@austibwu
Copy link
Author

@llfbandit is there any chance you can look into this or advise? In my implementation, .wav and pcmstream always outputs at 48k sample rate and in float32 regardless of input parameters, haven't found a way to get around it yet.

@llfbandit llfbandit added the bug Something isn't working label Mar 2, 2024
@llfbandit
Copy link
Owner

For whatever reason, the settings are not taken into account....

@austibwu
Copy link
Author

austibwu commented Mar 4, 2024

indeed. I've still been using the package - some things I observed in the time since I submitted the issue:
MacOS

  • recording to .wav file creates a file with a PCM waveform in float32 format
  • .wav file is padded with 4096 bytes of filler bits ("JUNK" tag) before the actual PCM waveform data (denoted by the "data" tag). no header or format chunks created.
  • somehow since opening the ticket my .wav recordings switched to recording in 44.1k samplerate, rather than the 48k I mentioned above
  • as you said, recorder ignores the config settings save the encoding format
    iOS
  • limited testing but seems to be functioning as expected. channel#, bitrate, encoding. still creates the 4096 bytes of junk padding though.

for my purposes (device microphone testing) , a pcm stream and .wav PCM output at 48k float32 format is actually ideal. I don't know if it will be possible/practical to implement this intentionally, but the higher resolution allows for much more accurate expression of the wave.

@llfbandit
Copy link
Owner

floats support is an enhancement I'm thinking about but until every platform is stable, I won't increase the feature and code surface. I'm already having trouble keeping track of what should already be corrected or adjusted.
So be warned that a fix should lower the precision to int16.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working macOS
Projects
None yet
Development

No branches or pull requests

2 participants