3
$\begingroup$

I'm trying to save a recording using AudioRecord. My recording gets overwritten even if I save the output in a fresh cell. This illustrates the issue:

astream = AudioStream[First@$AudioInputDevices];
sample = AudioRecord[astream];
DialogInput[Print["Record now for 5 s..."]; Pause[5]; 
  Print["Recorded ~ 5 s"]; DialogReturn["Close me"]];
AudioStop[astream];
player = Audio[sample]

My recording is returned as an output as shown. I save it to a new cell.

Mathematica graphics

Now I do a new recording on the same channel:

AudioRecord[astream];(* once again *)

DialogInput[Print["Record again now for 10 s..."]; Pause[10]; 
  Print["Recorded ~ 10 s"]; DialogReturn[]];
AudioStop[astream];
player

Now the recording above looks the same (this does not always happen though; sometimes a fresh audio gadget replaces the one I saved before) but the data has been overwritten with the first 5 s of the new recording.

Mathematica graphics

This looks like a bug to me although I have an intuition as to why this is happening (Dynamic); can anyone suggest a workaround?

A more fundamental issue is that it does not seem to be possible to close the audio stream or to dispose of the resources it is using (without quitting the kernel). That's what's familiar to me from using streams in other programming languages. Is it too much to hope this might be available in future?

$\endgroup$
6
  • 1
    $\begingroup$ Export it to a file? $\endgroup$
    – flinty
    Oct 21, 2021 at 9:52
  • 1
    $\begingroup$ ^ or even export it to a string with ExportString ? $\endgroup$
    – flinty
    Oct 21, 2021 at 10:24
  • $\begingroup$ @flinty yes a good suggestion but I really want to save it in its original form in my notebook rather than exporting it and importing it; but then reconstructedPlayer = Audio[ImportString[ExportString[player = Audio[sample], "MP3"], "MP3"]] would do it nicely. $\endgroup$
    – fairflow
    Oct 21, 2021 at 10:53
  • $\begingroup$ It still seems like a design bug to me especially as the behaviour of the stream once it has been stopped is unpredictable. I'd like to be able to really stop it, forever. $\endgroup$
    – fairflow
    Oct 21, 2021 at 11:02
  • 1
    $\begingroup$ @fairflow you can dispose of the recording stream using RemoveAudioStream, and each time you record create a new AudioStream. This will guarantee that previous recordings will never be overwritten. $\endgroup$
    – carlog
    Jun 8, 2022 at 16:52

1 Answer 1

0
$\begingroup$

A good workflow for recording using AudioStream would be something like this:

(* Create the recording stream *)
astream = AudioStream[First@$AudioInputDevices];
(* Start the recording. AudioRecord just returns its input, so no need to assign it to a variable *)
AudioRecord[astream];
(* Block the kernel for some mount of time *)
DialogInput[Print["Record now for 5 s..."];
Pause[5];
(* End the recording, this way the recording ends after 5 seconds, not after the dialog is closed *)
AudioStop[astream];
Print["Recorded ~ 5 s"];
DialogReturn["Close me"]];
(* Now the stream still exists and it contains the recording. We need to assign the recorded audio to a variable *)
recordedAudio = Audio[sample]
(* Remove the stream and release all its resources *)
RemoveAudioStream[astream]

The result is still stored in the recordedAudio variable. Obviously if you overwrite you'll lose it. You can also save it in a file of your choice by doing something like

Export["myFile.wav", recordedAudio]

If you want to record directly to a specific file, you can use the first code block, but replace the AudioStream call with

AudioRecord[astream, GeneratedAssetLocation ->"myFile.wav"];
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.