mmitch / gbsplay

gameboy sound player
https://mmitch.github.io/gbsplay/
Other
98 stars 20 forks source link

dump sound as WAV file #68

Closed RiedleroD closed 2 years ago

RiedleroD commented 3 years ago

preferrably optional; with ffmpeg support or something. Currently the only way to dump to file is something like this: gbsplay -o stdout -E l -r 48000 in.gbs | ffmpeg -ac 2 -f s16le -ar 48000 -i - -c:a pcm_s16le out.wav

But it's kind of a hassle & it'd be much more convenient to just do something like this: gbsplay -o ffmpeg in.gbs out.wav

mmitch commented 3 years ago

Instead of ffmpeg you could also use sox to convert from raw to WAV (which only adds the WAV header, anyway). There is no need to compile gbsplay with ffmpeg.

If you have the right media player, you could just play the stdout stream, no conversion necessary (eg. gbsplay -o stdout foo.gbs > foo.pcm and then play foo.pcm).

Writing a WAV header is quite easy, so we could provide a WAV plugout. The real problem is that the WAV header contains the file length and we don't know it in advance. So after writing the audio data, we'd have to rewind the file stream and update the header with the audio length. Sadly, that is impossible on a stdout stream.

So the only way for a proper WAV output would be to write into a real file. This means gbsplay would have to parse an output filename like you propose, but that would require changes to the parameter handling code (extra complication: the output filename would only be relevant for that single plugout). Another solution would be to pass the parameter directly to the output plugin (eg. -o wav:filename.wav), but we don't have that yet either.

(I've edited the issue title to clarify, because dump to file is literally what the existing stdout plugout does)

mmitch commented 3 years ago

My personal opinion: I don't mind calling sox or ffmpeg to convert the raw PCM data into another audio file format. For MP3 or OGG you'd need to do that anyway (see contrib/gbs2ogg.sh).

gbsplay's job is to provide the audio data, which it already does with -o stdout. To convert audio data between formats, use a different program. That's the Unix philosophy ;-) It would be much more work to add every possibly audio format to gbsplay itself than to just combine gbsplay with an existing converter.

Btw: You have a working solution, what is so bad about it? Put that oneliner into a shell script or shell alias if you don't want to type it every time and you're ready to go, for example like this:

#/bin/sh
gbsplay -o stdout -E l -r 48000 "$1" | ffmpeg -ac 2 -f s16le -ar 48000 -i - -c:a pcm_s16le "${1%.gbs}.wav"

You can call it as gbs2way foo.gbs and it will automatically write to foo.way.

RiedleroD commented 3 years ago

It was just a thought to make life easier for people that don't know much about shell scripting. I can definitely live without the feature; I've actually made myself a little python script to automate the rendering process, so I can just put the gbs into the script, and it runs it automatically through gbsplayer and corrscope.

But yeah, as I said, writing to a wav file would be nice for less advanced users.

mmitch commented 2 years ago

While looking over the MIDI plugouts because of issue #88 I realized we already have everything in place there to provide a WAV output without much hassle. I've had some spare time and it's already working. Not in master yet, but in the plugout_wav branch (look out, I'm rebasing a lot in there).

The two main issues noted above are handled like this:

So I take back everything I wrote before and claim the opposite: WAV output is nearly done :wink:

mmitch commented 2 years ago

The WAV output is working and has been merged to master. Feel free to try it and report any problems, I'll close this issue as the implementation is done.