part-cw / lambdanative

LambdaNative is a cross-platform development environment written in Scheme, supporting Android, iOS, BlackBerry 10, OS X, Linux, Windows, OpenBSD, NetBSD, FreeBSD and OpenWrt.
http://www.lambdanative.org
Other
1.39k stars 86 forks source link

Sound files wav vs ogg vs long files #13

Closed dmalves closed 10 years ago

dmalves commented 10 years ago

Hi,

DemoHelloWorld plays a small 8 bits mono file. I tried to add a larger file (a song) and the sound did not played at first (16 bits stereo), so I converted the file to 8bits mono. I could play the file, but just for a few seconds. No crash, just couldn't play the whole file.

I tried the same thing on android, same result. Also, make.sh does not pack other files like mp3 or ogg. It would be great to have those. I don't know much about PortAudio, so I guess it does not support mp3 or wav? I tried something radical and renamed my ogg file to wav just to test. On my Linux box I couldn't play to song, but as expected I could play it on Android, but not the whole song.

And yes, I can play the song on my PC. For that I used smplayer or any other music player.

dmalves commented 10 years ago

Well,

it seems that in the case of Android bootstrap, LambdaNative is using a SoundPool. SoundPools can't play big files

http://stackoverflow.com/questions/17097948/sound-pool-not-finish-playing-entire-file

MediaPlayer class could fix this, but the same behaviour is observed on Linux. In that case, I don't know what is going on.

dmalves commented 10 years ago

I reduced the file size making the frequency reduce to 8000. It was 44100. And now it plays nice on Linux and Android . Strange.

I noticed lines 98 and 153 on the file https://github.com/part-cw/lambdanative/blob/master/modules/ln_audio/audiofile.scm

does the "-4" on line 153 has something to do with "short *data" on line 98? if yes, I looked here for more info on the wav file header

https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

data is the last field. Actually data is the raw data, not the header. So, the -4 is to remove the data pointer? If so, on my system(64bits linux), short* and int are of different sizes, if that really matters here.

I tested with this code:

include

int main(int argc, char *argv[]) { int i_am_int; short i_am_short; printf("\nsize of i_am_int: %d, i_am_short = %d\n", sizeof(i_am_int), sizeof(i_am_short)); return 0; }

and I got:

size of i_am_int: 4, i_am_short = 8

I guess on 64 bit machines the pointer is a bit longer. I guess that does not hurt too much, but 4 bytes should be missing on data.

OK, maybe I am wrong here. This is too low level. But it would be nice with the header was more independent if the machine is 32 or 64 bits, so the header could use types from stdint.

http://www.nongnu.org/avr-libc/user-manual/group__avr__stdint.html

clpetersen commented 10 years ago

The wav reader in lambdanative only understands simple uncompressed single-chunk pcm files. I suspect that your big sound files are multi-chunk and/or compressed. You can try to convert them into plain single-chunk pcm with audacity or a similar tool. I'll look into including an ogg reader, which would be a more appropriate format for longer sounds.

dmalves commented 10 years ago

In that case I sujest http://www.nothings.org/stb_vorbis/ it is public domain, tested in some games and everything is in a single C file :-)

clpetersen commented 10 years ago

Thanks for that pointer. Among other things commit bf53628e adds ogg support to all platforms using stb_vorbis everywhere except on Android (where ogg is supported natively through SoundPool). Note that there are new requirements to WAV files, they must now be 44100Hz 16 bit pcm. Information on the wiki here