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

Audio Recording from godot #15967

Merged
merged 2 commits into from
Jul 26, 2018
Merged

Conversation

Tugsav
Copy link
Contributor

@Tugsav Tugsav commented Jan 22, 2018

This pull request implements an Audio bus effect, that outputs the audio from the bus into a raw audio file.

I implemented this since i needed it myself but figured i would put it up as a PR in case it could be useful for others.

Potential use case examples:

  • Record audio for in-game cut-scene
  • Allowing the user to save specific audio during run-time, for an example if you have a recorder in-game.

[edit]
As per the suggestions, the functionality has been changed in the following ways
The audio effect now records into a buffer that a user can get an AudioStreamSample object from.
AudioStreamSample formats supported are 8-bit and 16-bit PCM, as well as IMA_ADPCM
Additionally a function has been added to AudioStreamSample that allows the user to save it as a WAV file.
Supported formats for saving as WAV are 8-bit and 16-bit PCM

@@ -0,0 +1,101 @@
/*************************************************************************/
/* audio_effect_record.cpp */
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep the */ in line on both files.

Thanks for contributing! Very nice feature. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Thanks for spotting it quickly

@Zylann
Copy link
Contributor

Zylann commented Jan 22, 2018

Aaah I thought it was for recording with a mic ^^"

@groud
Copy link
Member

groud commented Jan 22, 2018

How do you change the output format ?

@Tugsav
Copy link
Contributor Author

Tugsav commented Jan 22, 2018

The output format is raw audio (no format really). In order to play it with a media player you have to encode it to a real format.
As an example i used ffmpeg to make a wav file:
ffmpeg -f f32le -ar 44.1k -ac 2 -i testaudio.raw testconverted.wav

@groud
Copy link
Member

groud commented Jan 23, 2018

I like the idea, but I wonder if how it is useful when building a game.
I think it would be better making this a plugin, as I see few realistic use cases.

But maybe you have a good counter-example. ^^

@Tugsav
Copy link
Contributor Author

Tugsav commented Jan 23, 2018

The original intention of this were to use it for pre-rendered cutscenes created in the godot engine (using the --fixed-fps and --disable-render-loop flags and using a GD-script to save frames).
As for whether to use pre-rendered cutscenes or not (or a mix) the opinions are many ^^'

@reduz
Copy link
Member

reduz commented Jan 23, 2018

Memory allocation and IO in audio threads is forbidden, you should probably use a ringbuffer for this and write in another thread.

Also, we should expose AudioEffect via GDNative, so you can do this without needing to modify core godot.

@Zylann
Copy link
Contributor

Zylann commented Jan 23, 2018

Being able to write AudioEffects using GDNative would be awesome :D

@Tugsav
Copy link
Contributor Author

Tugsav commented Jan 25, 2018

I have moved the IO to a separate thread and instead buffered the Audio as requested. Also the recording audio effect now creates a header in the file so that we get valid (though completely uncompressed) .wav files.

I am not sure if there isn't a better way of dealing with creation of the thread though. Optimally it should only be started when beginning a new recording, but i am not sure if it is allowed to start the thread from within the Audio thread.

@Tugsav
Copy link
Contributor Author

Tugsav commented Feb 26, 2018

I have rebased the PR to adhere to the guidelines. Also the audio is now saved as uncompressed .wav files instead of raw audio.

@reduz
Copy link
Member

reduz commented May 7, 2018

@SaracenOne is working on something similar that also includes audio input. Holding off on this one to see how both mix, if they do.

@SaracenOne
Copy link
Member

@reduz It should be fine I think. As per what we discussed, my microphone code is only interested in trying to get microphone input from the audio driver into an audio stream, and then ultimately into the mixer where we can do things with it.

@reduz
Copy link
Member

reduz commented Jul 4, 2018

After discussion, probably a more desired functionality would be to just record to an AudioStreamSample, and eventually add a function to it to save to a wav file. This way we can use it together with the new option to record from microphone

@Tugsav Tugsav changed the title Audio Recording from godot Audio Recording from godot (WIP) Jul 23, 2018
@Tugsav Tugsav force-pushed the AudioRecordingModule branch 2 times, most recently from c2b9574 to caa01ad Compare July 23, 2018 14:30
@Tugsav Tugsav changed the title Audio Recording from godot (WIP) Audio Recording from godot Jul 24, 2018
@Tugsav
Copy link
Contributor Author

Tugsav commented Jul 24, 2018

@reduz PR has been updated in an attempt to implement it like the desired functionality. PR description has been updated as well.

@@ -509,6 +509,34 @@ PoolVector<uint8_t> AudioStreamSample::get_data() const {
return pv;
}

void AudioStreamSample::save_to_wav(String path) {
// float sample_rate = AudioServer::get_singleton()->get_mix_rate();
Copy link
Member

@akien-mga akien-mga Jul 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind amend the first commit to remove/not add the commented out code? (You can leave a stub with a TODO comment if you want though.)

//Read from the buffer into file
_io_store_buffer();
//Update the header
//_create_wav_header(ring_buffer_pos); //The ring_buffer_pos will be consistent with the amount of frames written
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New commented out code here, should it be removed or fixed?

@@ -509,6 +511,76 @@ PoolVector<uint8_t> AudioStreamSample::get_data() const {
return pv;
}

void AudioStreamSample::save_to_wav(String p_path) {
if (format == AudioStreamSample::FORMAT_IMA_ADPCM) {
printf("Saving IMA_ADPC samples are not supported yet\n");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use WARN_PRINTS to issue a proper warning (it takes a String, with no need for newline character at the end).

@akien-mga
Copy link
Member

There seems to be a build issue on Android: https://travis-ci.org/godotengine/godot/jobs/407176455 (you might need to press the "Raw log" button if it doesn't show up)

@Tugsav
Copy link
Contributor Author

Tugsav commented Jul 25, 2018

I will look into those that build issue. It seems to be linked to the fact that i madeResourceImporterWAV::_compress_ima_adpcm into a static method.
Not sure if i should fix the commented code or just squash both commits into a single one.

@akien-mga
Copy link
Member

Not sure if i should fix the commented code or just squash both commits into a single one.

That's up to you, but I think it makes sense to have two commits, once for implementing the audio recording feature, and one for implement the save to WAV.

@Tugsav Tugsav force-pushed the AudioRecordingModule branch 6 times, most recently from 3b04390 to c1f6808 Compare July 26, 2018 11:41
Implements an Audio bus effect that outputs the audio from the bus into a wav file

Now channels audio recording into an AudioStreamSample instead of saving to wav
8 and 16 bit sample saving has been implemented.
@Tugsav
Copy link
Contributor Author

Tugsav commented Jul 26, 2018

Recommended changes have been applied, and the Android build issue resolved

@akien-mga
Copy link
Member

Awesome, thanks!

@akien-mga akien-mga merged commit 91d6fa8 into godotengine:master Jul 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants