#146333 - Noda - Sun Dec 02, 2007 10:23 pm
Hi,
As I announced some times ago in the mp3 thread, here is finally the release of my new library.
Features:
* MP3 engine:
- mp3 is decoded on the arm7, so use nearly no CPU time on the arm9
- stereo & surround modes available (surround works even for mono mp3s)
- up to 44Khz/stereo/96Kbps, though I recommend using 32Khz/stereo/80Kbps max, which is enough for the DS and works great with up to +25%/-100% pitching
- support real-time pitching (changing the playing speed of the mp3)
- support real-time volume and panning change
- the mp3 can be paused and restarted
- the mp3 can be set to loop automatically
- support playing from RAM and streaming from FAT or EFS
- you can disable the mp3 engine if you want, to get 2 more channels
* Audio engine:
- can use the whole 16 DS channel or only the first half (so you can use an external mod player, for example)
- support standard or surround/fx mode (16 channels in standard mode (-2 if mp3), 8 in surround/fx mode (-1 if mp3))
- simple sound playing using a priority system: if no channel is available, stop a sound that has less priority than the new one to play it, or skip it if all sounds have more priority.
- possibility to reserve a particular channel so it won't be used in the channel pool by the priority playing system. You can then manage the reserved sound channels manually.
- surround or pseudo-reverb can be activated per sound (works great with mono sounds)
- support real-time volume, panning and pitch modifications for each sound
- support sound looping
I'm open to any suggestions on how to improve it ;)
Download link:
http://noda.free.fr/nds/as_lib_template_v1.0.rar
The lib comes with a template and a example of what you can do with it.
It didn't tested it exhaustively, so feel free to report any bug.
Credits:
- IPC sound system and streaming is based on cold_as_ice streaming example
- audio stream filling / mp3 decoding based on ThomasS mp3 decoding example
- ASM stereo desinterleave function was made by Thoduv
#146335 - Peter - Sun Dec 02, 2007 11:08 pm
I have not really a question regarding the audio system, but I found the following lines in as_lib9.h and I wonder why you declare all inline functions as extern:
Code: |
extern inline void AS_ReserveChannel(u8 channel)
{
IPC_Sound->chan[channel].reserved = true;
}
|
_________________
Kind Regards,
Peter
#146336 - Lick - Sun Dec 02, 2007 11:16 pm
This lib sounds awesome! Have you planned support for formats other than mp3?
_________________
http://licklick.wordpress.com
#146337 - Noda - Sun Dec 02, 2007 11:18 pm
Peter wrote: |
I have not really a question regarding the audio system, but I found the following lines in as_lib9.h and I wonder why you declare all inline functions as extern:
Code: |
extern inline void AS_ReserveChannel(u8 channel)
{
IPC_Sound->chan[channel].reserved = true;
}
|
|
That's because if you use it in a cpp project and rename the file from .c to .cpp (not necessary), the inline functions need to be declared as extern in cpp in order to be used on other files ;)
Lick wrote: |
This lib sounds awesome! Have you planned support for formats other than mp3? |
I've done it mainly to fit my needs, so not for now..
what formats would you have wanted? .ogg needs too much memory for the arm7, but I may consider adding later a mod player which could be used instead of the mp3 player.
Last edited by Noda on Sun Dec 02, 2007 11:22 pm; edited 2 times in total
#146338 - Noda - Sun Dec 02, 2007 11:20 pm
[please delete this post, sorry for the double post]
#146340 - NeX - Sun Dec 02, 2007 11:27 pm
Please tell me how on Earth the DS can output surround with two speakers and stereo headphones.
_________________
Strummer or Drummer?.
Or maybe you would rather play with sand? Sandscape is for you in that case.
#146341 - Noda - Sun Dec 02, 2007 11:31 pm
http://en.wikipedia.org/wiki/Virtual_surround
Surround is enabled in most commercial games, though the method used is litlle different.
I'm not talking about 5.1 DTS ;)
Actually, 2 speakers/headphone is enough: remember, you only have 2 ears, right? there is some algorithms which can provide exact 3D sound placement using simple headphones, the perception of the sound in space is related the frequencies/delay perceived.
#146343 - yellowstar - Mon Dec 03, 2007 12:21 am
I'm having problems with the example.
It won't play the mp3 from fat.
Instead,
it only plays the built-in mp3.
I uncommented the define for this,
and rebuilt it.
I have the mp3 in the correct place,
and it is named correctly.
I found this on line 117 in the example:
Code: |
AS_MP3StreamPlay("test.mp3");
|
Shouldn't there be a / for the root?("/test.mp3")
I tried fixing that,
but it still won't work.
Even commenting out
all the lines for the fat define
won't fix it.(that includes the function call to
play the built-in mp3.)
#146348 - Noda - Mon Dec 03, 2007 1:21 am
Huh?
I just tried it, you just need to uncomment the define, then rebuild it and you're done.
I tested it under no$gba with fcsr driver, on my DS-X and on my MK5, it just works fine loading the file "test.mp3" at the root of the card..
What version of DKP are you using?
#146350 - yellowstar - Mon Dec 03, 2007 1:32 am
DKA r21.
I tested it on my DS-X.
#146351 - Noda - Mon Dec 03, 2007 1:42 am
I've only tested the lib under DKA r20 (I have a school project due in 2 weeks and I don't want to mess with the update for now), maybe that's the problem, though I don't saw any major changes in r21 which could cause that..
Can anyone using DKA r21 confirm that the example is not working with fat with just uncommenting the define?
EDIT: how, I saw that you use a DS-X.. is your DS-X set to automatically runs the last .nds launched? if that's the case, then hold A at startup and reload the example with the loader. The DS-X has some memory where the homebrews are put on, and sometimes when you update it you need to reload the file through the loader so the file is reload in this "cache" memory (I noticed that some time ago). I think that is your problem
#146354 - yellowstar - Mon Dec 03, 2007 2:02 am
It still won't work,
with booting the example manually.
#146356 - Noda - Mon Dec 03, 2007 2:11 am
What it does? does it show a "fat init error?"
#146359 - spinal_cord - Mon Dec 03, 2007 3:01 am
How much of a pain would this be to get working with palib? I assume it would mean removing some of palibs arm7 stuff, or is it likely to fit?
_________________
I'm not a boring person, it's just that boring things keep happening to me.
Homepage
#146364 - Noda - Mon Dec 03, 2007 4:34 am
basically, you just need to get rid of PALib's modplayer to free up some space on the arm7 binary, and change the IPC structure location so it doesn't conflicts with the PALib's one.
#146380 - chishm - Mon Dec 03, 2007 8:04 am
There's not enough free RAM on the ARM7 for the Helix decoder in DKA r21. I get around this by using VRAM bank D as the heap location for the ARM7. To do this, in arm9/source/main.c, add the following line at the start of main ()
Code: |
// Give 128KiB of VRAM to the ARM7
vramSetBankD(VRAM_D_ARM7_0x06000000); |
That gives the RAM to the ARM7. Now in arm7/source/main.c, add the following at the top of the source file.
Code: |
#include <string.h> // For memset
#define VRAM_START ((char*)0x06000000)
#define VRAM_END ((char*)0x06020000)
extern char *fake_heap_start;
extern char *fake_heap_end; |
Then add the following to the start of main ()
Code: |
// Wait for VRAM to become available
while ((*(vuint8*)0x04000240 & 0x02) == 0);
// Clear VRAM
memset (VRAM_START, 0, VRAM_END - VRAM_START);
// Use VRAM as heap
fake_heap_start = VRAM_START;
fake_heap_end = VRAM_END; |
Finally, you'll need to bypass the ARM9's data cache for the ARM7 to be able to access the data correctly. Since the ARM9 is only writing to the buffer once then never touching the data again, the best way to do this is to use an uncached mirror of EXRAM.
After the line
Code: |
mp3filebuffer = (u8*)memalign(4, AS_FILEBUFFER_SIZE * 2); // 2 buffers, to swap |
add the following line
Code: |
mp3filebuffer = (u8*)((int)mp3filebuffer | 0x00400000); // Bypass cache |
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com
#146386 - Noda - Mon Dec 03, 2007 1:52 pm
Thanks for the precision, but why less memory is available on the arm7 since DKP r21? what has been added?
It's really disappointing for me since I don't want to waste a full VRAM bank just to have the mp3 player working, wheras in DKP r20 it's not needed. :/
And your remark concerning the cache is interesting, but what are the benefits? since only arm7 will access the data I don't see where the problem is?
#146405 - yellowstar - Mon Dec 03, 2007 8:28 pm
Here's the problem:
Instead of playing the mp3 from fat,
it only plays the built-in mp3.
#146408 - Noda - Mon Dec 03, 2007 9:53 pm
yellowstar> I was talking about Chism's post.
Concerning your problem, I actually don't see how it's possible as the AS_MP3StreamPlay() and AS_MP3DirectPlay() are completely different functions, so if you call AS_MP3StreamPlay("test.mp3") it's impossible that the built-in mp3 is played!
Have you tested your binary under no$gba or ideas? does it give the same result?
And as Chism pointed out, there may be some modifications to do to make it work with DKP r21 apparently (I won't be able to check this for some weeks as I first have to finish my school project under DKP r20..)
#146424 - melw - Tue Dec 04, 2007 12:34 am
Noda wrote: |
And as Chism pointed out, there may be some modifications to do to make it work with DKP r21 apparently (I won't be able to check this for some weeks as I first have to finish my school project under DKP r20..) |
Just confirming Chishm's observations here. Compiling the original example with DKA r21 gives no mp3 playback. Again, adding Chishm's VRAM trickery and recompiling will give you sound back.
Coincidently, I'm just in a need of mp3 player for a project that uses lot of memory on the graphics front, and losing one full VRAM bank to ARM7 is something that makes me consider other options for sound playback. Hopefully there is another way to go around this problem - it'd be interesting to know what has been changed between DKA r20 and r21 and where the ARM7 has lost its memory. :)
#146425 - Noda - Tue Dec 04, 2007 12:41 am
Thanks, I'm also really wondering what changed and eats the arm7's RAM.
Anyway, I always have the solution (if nothing can be done to recover the lost ram) to allocate the needed space with the arm9 and pass it to arm7 via IPC (like I do for the audio & file buffers), so there won't be no need for a VRAM bank.
I guess r21 users will have to wait the end of the project so I can correct this ;)
#146426 - Lick - Tue Dec 04, 2007 1:11 am
Just wondering, did you enable the Helix decoder's ARM assembly routines?
_________________
http://licklick.wordpress.com
#146428 - Noda - Tue Dec 04, 2007 3:03 am
Yes.
By the way, can someone can telle me the size of the compiled arm7 binary with devkitARM r21?
I still think it's strange that there's not enough ram, as with devkitARM r20 the binary is ~52Ko, and use less than 4Ko of ram (the audio & file buffers are allocated on arm9), so this should fit in 64Ko without any problem, and I don't think there's more than 8Ko more ram space used by r21, isn't there?
[corrected terminology -- MOD]
#146442 - melw - Tue Dec 04, 2007 7:53 am
Noda wrote: |
By the way, can someone can telle me the size of the compiled arm7 binary with the DKP r21? |
aslib.arm7: 58 800 / 58 864 bytes - (original / modified)
EDIT: The most obvious workaround: Setting -Os in arm7 makefile -> aslib.arm7 55 632 bytes and the original version works as well. 3 kilos seems to make a difference in this case. No idea if turning size optimization affects performance in any way, tested only with accompanied test.mp3.
Last edited by melw on Tue Dec 04, 2007 8:02 am; edited 1 time in total
#146443 - wintermute - Tue Dec 04, 2007 7:58 am
There's no such thing as DKP r21.
Personally I think mp3 is an unsuitable format for DS game music anyway - the memory and processor requirements push things a bit close to the edge to do much else.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog
#146465 - Noda - Tue Dec 04, 2007 4:37 pm
Decoding a 22Khz/stereo/64Kbps use less than 50% of the arm7 CPU, so it's very suitable for me, and there's enough free CPU time to run dswifi/liblobby I think.
The only thing that really bothers me is that 64K restriction for the arm7: I would really love to have the choice of putting the arm7 binary in main ram and using those 64K only as heap for the arm7. Moonshell has an arm7 binary which is more than 300K in size (but compiled with ADS), so that should be possible right?
#146472 - ecurtz - Tue Dec 04, 2007 5:30 pm
WARNING: This was written on the bus this morning and I almost never do any assembly programming, so it's guarenteed to have a bug or two.
(All that indexing in the loop was driving me nuts)
Code: |
// desinterleave a stereo source (thanks to Thoduv for the code)
// version 2 by ecurtz (optimized loop)
asm (
"@--------------------------------------------------------------------------------------\n"
" .text \n"
" .arm \n"
" \n"
"@ desinterleave an mp3 stereo source \n"
"@ r0 = interleaved data, r1 = left, r2 = right, r3 = len \n"
" \n"
" .global AS_StereoDesinterleave \n"
" \n"
"AS_StereoDesinterleave : \n"
" stmfd sp!, {r5-r11} \n"
" \n"
"@ get the 3 low bits of len \n"
" ands r5, r3, #7 \n"
"@ if 0 jump to the loop \n"
" beq _loop \n"
"@ load data, we know r5 won't be used in incomplete loop \n"
" ldmia r0, {r6-r12} \n"
"@ adjust data and len by amount we're actually using \n"
" add r0, r5, lsl #2 \n"
" sub r3, r5 \n"
"@ r5 = 8 - r5 (amount of loop to skip) \n"
" rsb r5, #8 \n"
"@ r5 = r5 * 3 instructions per sample \n"
" add r5, r5, lsl #1 \n"
"@ slam the pc forward into the loop (automatically skips next instruction) \n"
" add pc, r5, lsl #2 \n"
" \n"
"_loop: \n"
" ldmia r0!, {r5-r12} \n"
" \n"
" strh r5, [r1], #2 \n"
" mov r5, r5, lsr #16 \n"
" strh r5, [r2], #2 \n"
" \n"
" strh r6, [r1], #2 \n"
" mov r6, r6, lsr #16 \n"
" strh r6, [r2], #2 \n"
" \n"
" strh r7, [r1], #2 \n"
" mov r7, r7, lsr #16 \n"
" strh r7, [r2], #2 \n"
" \n"
" strh r8, [r1], #2 \n"
" mov r8, r8, lsr #16 \n"
" strh r8, [r2], #2 \n"
" \n"
" strh r9, [r1], #2 \n"
" mov r9, r9, lsr #16 \n"
" strh r9, [r2], #2 \n"
" \n"
" strh r10, [r1], #2 \n"
" mov r10, r10, lsr #16 \n"
" strh r10, [r2], #2 \n"
" \n"
" strh r11, [r1], #2 \n"
" mov r11, r10, lsr #16 \n"
" strh r11, [r2], #2 \n"
" \n"
" strh r12, [r1], #2 \n"
" mov r12, r12, lsr #16 \n"
" strh r12, [r2], #2 \n"
" \n"
" subs r3, #8 \n"
" bne _loop \n"
" \n"
" ldmia sp!, {r5-r11} \n"
" bx lr \n"
"@--------------------------------------------------------------------------------------\n"
);
|
#146479 - yellowstar - Tue Dec 04, 2007 8:12 pm
I have found out why it was doing that previously.
I forgot to copy the newly-compiled nds to my card.
(I always have a command in my Makefiles
to copy it to my card for me)
#146482 - Echo49 - Tue Dec 04, 2007 8:26 pm
Have you thought about adding streaming raw sound data from the flashcart? Also, is it possible to play both an MP3 and SFX at the same time?
#146483 - wintermute - Tue Dec 04, 2007 8:29 pm
Noda wrote: |
Decoding a 22Khz/stereo/64Kbps use less than 50% of the arm7 CPU, so it's very suitable for me, and there's enough free CPU time to run dswifi/liblobby I think.
The only thing that really bothers me is that 64K restriction for the arm7: I would really love to have the choice of putting the arm7 binary in main ram and using those 64K only as heap for the arm7. Moonshell has an arm7 binary which is more than 300K in size (but compiled with ADS), so that should be possible right? |
We're using 96K for the arm7.
Running the arm7 in main RAM has a detrimental effect on both processors.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog
#146490 - tepples - Tue Dec 04, 2007 8:55 pm
Can an MP3 decoder on the ARM7 be broken into overlay sections that are copied from main RAM to ARM7 RAM as each pass of MP3 decoding (huffman, rescaling, imdct, polyphase) completes? Would it be helpful?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#146497 - Noda - Tue Dec 04, 2007 10:53 pm
Echo49> raw sound streaming is useless since you can have mp3 for free, and yes you sure can use mp3 & sfx at the same time.
wintermute> 96K? then the 58K of the binary + 4~5K of heap used for variable should not cause any problem! maybe there's a problem here, and heap adress is incorrect then?
#146498 - tepples - Tue Dec 04, 2007 11:09 pm
Noda wrote: |
Echo49> raw sound streaming is useless since you can have mp3 for free, and yes you sure can use mp3 & sfx at the same time. |
But what about comparatively long sound effects, such as a rain loop or voice acting? One can't have multiple MP3s at once, right?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#146506 - Noda - Wed Dec 05, 2007 2:27 am
tepples> yeah, we can have 2 mp3 at a time, I was think of having a wav file streaming instead of the mp3. I could add a raw streaming channel, but the problem lies with the timers: 2 timers are already used to stream the mp3, and the others are needed for the dswifi lib :/
#146509 - tepples - Wed Dec 05, 2007 3:18 am
In that case, you might want to have software mix the two streams into a ring buffer.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#146513 - Noda - Wed Dec 05, 2007 4:07 am
that's not the problem, it's that if the 2 sources streamed use different sample rate I need to set up different timings to know when to regenerate the ring buffers, and that impossible because we only have 4 timers (2 used for the first stream, and the others by the dswifi lib)
#146515 - tepples - Wed Dec 05, 2007 4:14 am
Mixers on the GBA had to handle multiple sample rates the hard way, yet AAS could still mix a 4 channel mod in 5% of CPU time.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#146655 - chishm - Fri Dec 07, 2007 9:54 am
Could someone who is still using DKA r20 compile this then tell me the offset of _end in the ARM7 binary. You can find this info from the file arm7/build/.map. Look for _end then report the address next to it. This will help me figure out how much memory the MP3 decoder is using when compiled in r20 vs r21.
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com
#146657 - masscat - Fri Dec 07, 2007 11:27 am
chishm wrote: |
Could someone who is still using DKA r20 compile this then tell me the offset of _end in the ARM7 binary. You can find this info from the file arm7/build/.map. Look for _end then report the address next to it. This will help me figure out how much memory the MP3 decoder is using when compiled in r20 vs r21. |
A bit of the arm7 .map from a r20 compile:
Code: |
0x038066fc . = ALIGN (0x4)
0x038066fc __bss_end = .
0x038066fc __bss_end__ = .
0x038066fc _end = .
0x038066fc __end__ = .
0x038066fc PROVIDE (end, _end)
|
Edit: you can get the entire .map file here.
#146659 - chishm - Fri Dec 07, 2007 11:44 am
In r21, with the changes I suggest previously, the size is 0x03807970, which is 4724 bytes difference. I'm not sure what caused such a large size change, but that is the cause of memory overflows when compiling with r21.
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com
#146688 - Noda - Fri Dec 07, 2007 5:54 pm
Ok, so I'll just move the allocated buffers in main ram and let the arm9 allocate it, but that bothers me as when the arm7 access main ram, it slows down the arm9..
But the way, do you know of much memory (rom+ram) is required for the dswifi/liblobby library?
#146691 - kusma - Fri Dec 07, 2007 6:50 pm
i think generating a map-file with both dka r20 and r21 and inspect the differences could be really useful here.
#146704 - melw - Fri Dec 07, 2007 10:30 pm
The biggest difference in .map files seems to be mktime that's still absent in DKA r20.
Code: |
.text 0x038012ec 0x7e4 c:/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.1.2/../../../../arm-eabi/lib\libg.a(lib_a-mktime.o)
0x038016a4 mktime
.text 0x03801ad0 0x848 c:/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.1.2/../../../../arm-eabi/lib\libg.a(lib_a-mktm_r.o)
0x03801ad0 __tzcalc_limits
0x03801d40 _mktm_r
.text 0x03802318 0x8 |
i.e. 4140 bytes.
#146947 - ThomasS - Tue Dec 11, 2007 9:12 pm
I've succeeded to use this with PALib. To solve the memory-on-arm7 problem, I've let the arm9 pass the arm7 a pointer to a volatile part of main RAM and modified the helix function AllocateBuffers in real/buffers.c to locate its structures there instead of using malloc (I've already successfully used this with my own mp3 stuff).
The sounds work fine. However, the mp3 included in the download doesn't work anymore. It plays very shortly, then stutters, and crashes no$gba or shuts down a real DS. MP3's with lower quality do work, however. Is this the normal behaviour if the decoding is too slow (because of using main RAM) or is something else wrong with it? If so, do you have a guess what it could be?
_________________
<dsFont> <Game Collection>
#146959 - Noda - Wed Dec 12, 2007 2:58 am
What you have done is what is was planning to do correct this issue ;)
The stuttering appear when the arm7 is too slow to decode the the mp3, and may lead to a crash, but never a shutdown, that's strange...
and concerning the example, the performance when using the main ram should be sufficient to decode the demo mp3 properly (it's 32kHz, stereo 80kbps), I'll investigate this problem when I'll update to r21.
But in-game, using main ram for the mp3 structure could affect the arm9 performance as the memory cannot be accessed by both processors at the same time, AFAIK.
#146992 - masscat - Wed Dec 12, 2007 7:36 pm
Noda wrote: |
But in-game, using main ram for the mp3 structure could affect the arm9 performance as the memory cannot be accessed by both processors at the same time, AFAIK. |
I wonder how this does affect the performance. Just thinking, it may not be that bad.
If the ARM7 is only accessing data in main memory then it will only be reading/writing main memory every few instructions.
Since the ARM9 is normally running with its caches enabled it may be able to continue executing even when the ARM7 is blocking main memory.
#147113 - thoduv - Fri Dec 14, 2007 5:46 pm
ThomasS wrote: |
mp3 included in the download doesn't work anymore. It plays very shortly, then stutters, and crashes no$gba or shuts down a real DS. MP3's with lower quality do work, however. Is this the normal behaviour if the decoding is too slow (because of using main RAM) or is something else wrong with it? If so, do you have a guess what it could be? |
I'm having exactly this problem with my own integration of HelixMP3... I haven't figured how to solve it yet...
#147126 - Noda - Fri Dec 14, 2007 8:16 pm
The problem with this is simple and can't really be avoided: if the mp3 decoder is too slow, there will a moment the audio buffer will be refilled while in the same time being read by the sound hardware... crash.
#147151 - Michoko - Sat Dec 15, 2007 11:46 am
Noda, what did you use to encode the MP3 you put as an example in your lib please?
I tried to replace the MP3 you're using with mines, to do a quick check. I get some normal results if I encode my MP3 as mono (using DBPowerAmp + LAME 3.97 encoder), but if I use the same settings with stereo option, I only can hear a slow tune with "metallic" sound.
#147162 - ThomasS - Sat Dec 15, 2007 6:03 pm
What I've found out so far about my issues:
The problems depend on the version of LAME used to encode the MP3 and if the file is mono or stereo (the bitrate isn't the problem):
Official example with chism's changes:
3.95 and 3.97: mono works, stereo works
3.92: mono works, stereo doesn't get recognized as stereo and is played as mono
My PALib implementation:
3.95 and 3.97: mono works, stereo crashes
3.92: mono works, stereo doesn't get recognized as stereo and is played as mono
Michoko's "metallic" sound is also most likely a stereo file played as mono. To solve this, replace the following code:
Code: |
// gather information about the format
MP3GetNextFrameInfo(hMP3Decoder, &mp3FrameInfo, IPC_Sound->mp3.mp3buffer);
stereo = mp3FrameInfo.nChans >> 1; |
in as_lib7.c with
Code: |
// find the first sync word
u32 offset = MP3FindSyncWord(readPtr, bytesLeft);
readPtr += offset;
bytesLeft -= offset;
// gather information about the format
MP3GetNextFrameInfo(hMP3Decoder, &mp3FrameInfo, readPtr);
stereo = mp3FrameInfo.nChans >> 1; |
Now my stereo files from the version 3.92 got recognized correctly.
I've still not solved the second issue, that stereo files crash my program.
The problem seems to be that numsamples gets too big (at all bitrates, even 30kbps), and then the program writes data behind the mixbuffer and crashes.
I can improve the situation by increasing AS_AUDIOBUFFER_SIZE in as_lib9.h, then it doesn't crash anymore, but it still stutters from time to time and writes data behind the buffer.
I didn't get why this still happens then yet. Maybe a timer issue? But the PALib arm7 code doesn't seem to set any of the timers ...
_________________
<dsFont> <Game Collection>
#147165 - Noda - Sat Dec 15, 2007 6:27 pm
The problem with PALib is that they do various other things in the VBL loop, so this eats some CPU power I think... also, it include the WifiLib which make use of timers! so that may be the problem..
My mp3 was encoded with Wavelab 5.0, which use Lame (don't know the versiion though).
But it plays fine on my DS (and some others), but one has crackling problem with the exacct same binary, which is quite strange :/
And thanks for the .92 fix, I wasn't aware of that problem, I'll correct that in the lib.
#147181 - chishm - Sun Dec 16, 2007 1:47 am
I strongly advise against having the sound mixer called from a vblank or vcount interrupt. Depending on how your interrupt handler is set up, if the mixer runs over time (longer than 1/60th of a second) during an interrupt, it will get called again, while the first one is still processing. Since it is definitely not re-entrant, you'll get data corruption, leading to crashes. Alternatively, it will delay all other interrupts from being processed until it is finished, including IPC FIFO and IPC structure updates.
Stick the call to the mixer in your main loop instead. This way, it won't prevent interrupts from occurring, and it won't be called more than once at a time. The worst that can happen is the audio decoding falls behind slightly for one or two frames, but provided you have a large enough decode buffer and the MP3 is not too complex for the ARM7 to actually handle, the decoder should catch up with the next call to the mixer.
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com
#147209 - Noda - Sun Dec 16, 2007 7:36 am
The sound mixer which handle the audio stream & decode the mp3 is already in the main loop and not called by an interrupt ;) on the vblank IRQ there's only the code which set up the sound channels and change the channels parameters (volume, pan etc..) which is way faster than 1/60s, so the problem is not here.
#147500 - Noda - Fri Dec 21, 2007 7:28 pm
ecurtz wrote: |
WARNING: This was written on the bus this morning and I almost never do any assembly programming, so it's guarenteed to have a bug or two.
(All that indexing in the loop was driving me nuts)
Code: |
// desinterleave a stereo source (thanks to Thoduv for the code)
// version 2 by ecurtz (optimized loop)
asm (
"@--------------------------------------------------------------------------------------\n"
" .text \n"
" .arm \n"
" \n"
"@ desinterleave an mp3 stereo source \n"
"@ r0 = interleaved data, r1 = left, r2 = right, r3 = len \n"
" \n"
" .global AS_StereoDesinterleave \n"
" \n"
"AS_StereoDesinterleave : \n"
" stmfd sp!, {r5-r11} \n"
" \n"
"@ get the 3 low bits of len \n"
" ands r5, r3, #7 \n"
"@ if 0 jump to the loop \n"
" beq _loop \n"
"@ load data, we know r5 won't be used in incomplete loop \n"
" ldmia r0, {r6-r12} \n"
"@ adjust data and len by amount we're actually using \n"
" add r0, r5, lsl #2 \n"
" sub r3, r5 \n"
"@ r5 = 8 - r5 (amount of loop to skip) \n"
" rsb r5, #8 \n"
"@ r5 = r5 * 3 instructions per sample \n"
" add r5, r5, lsl #1 \n"
"@ slam the pc forward into the loop (automatically skips next instruction) \n"
" add pc, r5, lsl #2 \n"
" \n"
"_loop: \n"
" ldmia r0!, {r5-r12} \n"
" \n"
" strh r5, [r1], #2 \n"
" mov r5, r5, lsr #16 \n"
" strh r5, [r2], #2 \n"
" \n"
" strh r6, [r1], #2 \n"
" mov r6, r6, lsr #16 \n"
" strh r6, [r2], #2 \n"
" \n"
" strh r7, [r1], #2 \n"
" mov r7, r7, lsr #16 \n"
" strh r7, [r2], #2 \n"
" \n"
" strh r8, [r1], #2 \n"
" mov r8, r8, lsr #16 \n"
" strh r8, [r2], #2 \n"
" \n"
" strh r9, [r1], #2 \n"
" mov r9, r9, lsr #16 \n"
" strh r9, [r2], #2 \n"
" \n"
" strh r10, [r1], #2 \n"
" mov r10, r10, lsr #16 \n"
" strh r10, [r2], #2 \n"
" \n"
" strh r11, [r1], #2 \n"
" mov r11, r10, lsr #16 \n"
" strh r11, [r2], #2 \n"
" \n"
" strh r12, [r1], #2 \n"
" mov r12, r12, lsr #16 \n"
" strh r12, [r2], #2 \n"
" \n"
" subs r3, #8 \n"
" bne _loop \n"
" \n"
" ldmia sp!, {r5-r11} \n"
" bx lr \n"
"@--------------------------------------------------------------------------------------\n"
);
|
|
just tried, it crashes the emu/DS.
BTW, I added an arm7 init function as M3S/R4 cards don't seem to clear the memory before loading the .nds files.
#147503 - ecurtz - Fri Dec 21, 2007 8:55 pm
Noda wrote: |
ecurtz wrote: | WARNING: This was written on the bus this morning and I almost never do any assembly programming, so it's guarenteed to have a bug or two.
(All that indexing in the loop was driving me nuts)
|
just tried, it crashes the emu/DS.
BTW, I added an arm7 init function as M3S/R4 cards don't seem to clear the memory before loading the .nds files. |
Bah, I'll fix it as soon as I get a chance to actually compile and test. As I mentioned it was just typed in during my commute.
#147512 - ecurtz - Fri Dec 21, 2007 10:48 pm
Code: |
// desinterleave a stereo source (thanks to Thoduv for the code)
// version 2 by ecurtz (optimized loop)
asm (
"@--------------------------------------------------------------------------------------\n"
" .text \n"
" .arm \n"
" \n"
"@ desinterleave an mp3 stereo source \n"
"@ r0 = interleaved data, r1 = left, r2 = right, r3 = len \n"
" \n"
" .global AS_StereoDesinterleave \n"
" \n"
"AS_StereoDesinterleave : \n"
" stmfd sp!, {r4-r11} \n"
" \n"
"@ get the 3 low bits of len \n"
" ands r4, r3, #7 \n"
"@ if 0 jump to the loop \n"
" beq _loop \n"
"@ r4 = 8 - r4 (amount of loop to skip) \n"
" rsb r4, #8 \n"
"@ adjust data to include what we're actually using \n"
" sub r0, r4, lsl #2 \n"
"@ load data \n"
" ldmia r0!, {r5-r12} \n"
"@ bump count as if we were completing full loop \n"
" add r3, r4 \n"
"@ r4 = r4 * 3 instructions per sample \n"
" add r4, r4, lsl #1 \n"
"@ slam the pc forward into the loop (automatically skips next instruction) \n"
" add pc, r4, lsl #2 \n"
" \n"
"_loop: \n"
" ldmia r0!, {r5-r12} \n"
" \n"
" strh r5, [r1], #2 \n"
" mov r5, r5, lsr #16 \n"
" strh r5, [r2], #2 \n"
" \n"
" strh r6, [r1], #2 \n"
" mov r6, r6, lsr #16 \n"
" strh r6, [r2], #2 \n"
" \n"
" strh r7, [r1], #2 \n"
" mov r7, r7, lsr #16 \n"
" strh r7, [r2], #2 \n"
" \n"
" strh r8, [r1], #2 \n"
" mov r8, r8, lsr #16 \n"
" strh r8, [r2], #2 \n"
" \n"
" strh r9, [r1], #2 \n"
" mov r9, r9, lsr #16 \n"
" strh r9, [r2], #2 \n"
" \n"
" strh r10, [r1], #2 \n"
" mov r10, r10, lsr #16 \n"
" strh r10, [r2], #2 \n"
" \n"
" strh r11, [r1], #2 \n"
" mov r11, r11, lsr #16 \n"
" strh r11, [r2], #2 \n"
" \n"
" strh r12, [r1], #2 \n"
" mov r12, r12, lsr #16 \n"
" strh r12, [r2], #2 \n"
" \n"
" subs r3, #8 \n"
" bne _loop \n"
" \n"
" ldmia sp!, {r4-r11} \n"
" bx lr \n"
"@--------------------------------------------------------------------------------------\n"
); |
I think that fixed it. The bug was with the condition code checking the loop, it went negative if there wasn't an even amount of data. Is there a condition code for a postive result (not zero or negative?) that's what I need for this, but I just modified the loop value so it thinks it's completed 8 steps on the partial case.
edit -> OK, tested new code against the original for 1-31 samples, looks good at this point. <-
#148056 - Michoko - Tue Jan 01, 2008 3:29 pm
Hi,
First of all, Happy New Year! :)
I'm currently testing the ASlib port made by Thomas for usage with PAlib. And I think I encountered a problem which is not PAlib related but more global.
I'm using EFSlib for storing many small texts files in my ROM. Depending on the actions in my game, I load those small text files (it's an adventure book project). I'm streaming an MP3 file at the same time. Under NO$GBA + FCSR + Libfat mode only (for both EFS and ASlib), everything works fine. But when I want to switch to full EFS implementation on real DS hardware, I get random freezes whenever I try to load text files while the music is streaming.
I was suspecting a bug due to concurrent access to two files in the EFS file system at the same time, so I left the "#define AS_USE_EFS" line commented, so ASlib uses pure libfat access. I kept the rest of the code untouched (so the text files are still loaded using EFS) and copied the MP3 file directly on my linker. And it seems to work fine, which may confirm that it's an issue related to the access to an EFS file while MP3 is streaming using EFS at the same time.
Noda, do you think it would be necessary to add some kind of simple lockup system in EFSlib to prevent this bug?
Thanks for your reply! :)
Michoko
#148100 - Noda - Wed Jan 02, 2008 7:20 am
Hi ;)
Just quickly because I just came back from NY (yeah I was on Time Square 8-p): the EFS support in ASLib has not been tested, so I think that's it, I'll check that, multiple file access should not be a problem ;)
happy new year everyone ^^
#148236 - melw - Thu Jan 03, 2008 9:01 pm
Few more remarks using ASlib with DKA R21: If you don't want to waste extra VRAM bank for arm7 as with Chishm's version, one possibility is to comment rtcReset() from arm7 main (that is, if realtime clock isn't needed in your project). This cuts the arm7 size with 4kb, which seems to be enough for Helix decoder to function properly.
Another remark what comes to highest possible bitrates: Streaming from the disk results far more often to decoding errors than direct play from the memory. I didn't look at the inner workings, but perhaps there should be a larger buffer for streaming from the disk or reading more in advance to help with the performance? With M3Lite and 1Gb Kingston MicroSD card I had problems playing as low as 40kbit mono MP3's, glitches and decoding errors all around, and 56kbit mono MP3 crashing almost immediately.
#148239 - Lazy1 - Thu Jan 03, 2008 9:10 pm
Maybe it just needs to be fed more often on the arm9 side, maybe start a timer and update every 1-4ms.
The first version of my decoder checked if the arm7 needed to be fed during hblank and that seemed to work fine for 128kbps mono MP3s.
#148396 - Michoko - Sat Jan 05, 2008 11:02 am
I take my words back, now even when streaming in pure libfat mode I get freezes and lockups if I try to load files from EFS at the same time.
So it appears to be a broader issue happening when you try to access data from the linker both from a random file AND your MP3. It doesn't occur all the time, but probably when the decoding buffer tries to refill itself.
It seems I'm stuck for now and I'll have to stick with MP3 fully loaded in RAM.
#148446 - DekuTree64 - Sat Jan 05, 2008 9:13 pm
Michoko wrote: |
So it appears to be a broader issue happening when you try to access data from the linker both from a random file AND your MP3. It doesn't occur all the time, but probably when the decoding buffer tries to refill itself. |
File systems and interrupts are old enemies. Can you stream the MP3 data from your main loop on the ARM9? Maybe keep a big buffer of compressed data in memory, and then just let ARM7 eat up little bits of it at a time from an interrupt or whatever it likes to do.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku
#148479 - chishm - Sun Jan 06, 2008 7:55 am
It appears that EFSlib is using a single FILE* for all libfat calls, with seeks at the start of each read. This is why you get massive slow down when reading another file in the NitroFS at the same time. Seeks are an expensive operation when they jump backwards or make a large jump forwards.
As an efficiency improvement, I suggest EFSlib be recoded to use one libfat file handle for the NitroFS directory and create a new one (by opening the NDS file again) for each NitroFS file opened. This should be an optional setting, as there can also be efficiency gains by using the one libfat file handle for all operations, eg when many NitroFS files are opened, read, then closed at once.
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com
#148513 - Noda - Sun Jan 06, 2008 5:06 pm
Nice suggestion, I'll dig that for a future release ;)
#148515 - Michoko - Sun Jan 06, 2008 5:20 pm
Nice indeed! We can't wait! ;)
#148668 - kusma - Tue Jan 08, 2008 6:11 pm
melw wrote: |
The biggest difference in .map files seems to be mktime that's still absent in DKA r20.
Code: | .text 0x038012ec 0x7e4 c:/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.1.2/../../../../arm-eabi/lib\libg.a(lib_a-mktime.o)
0x038016a4 mktime
.text 0x03801ad0 0x848 c:/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.1.2/../../../../arm-eabi/lib\libg.a(lib_a-mktm_r.o)
0x03801ad0 __tzcalc_limits
0x03801d40 _mktm_r
.text 0x03802318 0x8 |
i.e. 4140 bytes. |
Just noticed this, all mktime-stuff dissapears for me if I remove the call to initClockIRQ() btw. If you need those 4k and RTC is not needed, you might save this memory.
edit: and for this libs example, that would most likely be rtcReset(), but I haven't tested that.
edit2: ...but apparently melw had. I didn't see that until now, sorry ;)
#149478 - Jesse - Sun Jan 20, 2008 8:48 pm
I'm having trouble getting the example-project to compile & run. The included .nds works fine, but when I try to compile it myself there is constant noise in the speakers while running the app, and starting a sample generates even more noise (sometimes resembling the original sample). I did a fresh install of devkitPro and tried both the suggested fixes for the devkitARM r21 problems (even though that looked like another issue). chisms' fix locked up in the waiting for VRAM loop. I'm running a M3 Simply and a R4 revolution. Also, I found a small update to the lib on the download site, but that didn't help and just made it lock up in the waiting for Arm7 loop.
I feels like it should be something wrong with my setup, since the included .nds works and other seems to have been able to compile it properly, but I can't figure what it could be. Anyone has any ideas?
_________________
http://www.collectingsmiles.com/colors & http://www.collectingsmiles.com/hyena
#149502 - Noda - Mon Jan 21, 2008 6:00 am
you have a M3S/R4 card, right? It's because your card doesn't clear memory before loading the homebrew, causing wrong values in my variables. I have fixed this by doing a safe initilization sequence on both processors in the current (soon to be released) version.
#149515 - Jesse - Mon Jan 21, 2008 1:32 pm
Thanks, I'm looking forward to testing it. Still, I don't understand how that can explain that the included .nds works while the one I build don't.
_________________
http://www.collectingsmiles.com/colors & http://www.collectingsmiles.com/hyena
#149953 - Jesse - Sun Jan 27, 2008 10:21 pm
Ok. I got this working at last. I still don't know why my the original version never compiled properly for me, but after integrating the fixes I found and debugging the lib to understand what was missing, it is working as it should on my R4.
With both liblobby and libwifi (as well as my need for a RTC) in there is not enough memory on the Arm7. With the VRAM trick it worked as it should though, but I wish there was a cheaper way.
But anyway, thanks a bunch Noda, the thing I'm working on right now would have been meaningless without a mp3-lib. :)
Edit: I also get this metallic-like sound when playing a 16khz mono-mp3. It feels like one speaker is lagging behind. Here's the link if anyone wants to test it: http://www.collectingsmiles.com/temp/mono.rar
Edit2: I'm having problems playing multiple mp3's after each other. I can't find a good way to write a IsPlaying function, since the status-variable doesn't change until the Arm7 has processed the play-command.
_________________
http://www.collectingsmiles.com/colors & http://www.collectingsmiles.com/hyena
#149985 - Jesse - Mon Jan 28, 2008 12:41 pm
I guess my app is a real stress-test for this thing as I play many short mp3s after each other.
Right now I'm looking at instability problems in about 10% of the times I start playing. The lib sometimes reports MP3ST_DECODE_ERROR and sometimes it just crashes the Arm7. The mentioned problems about interrupts and file-system doesn't apply if you only read data on the Arm9 in the main thread, right?
By the way. What's the best way for the Arm9 to generally keep track of what's happening on the Arm7? Right now I'm sending a FIFO command in Vblank every 2 seconds to determine if the Arm7 has crashed.
EDIT: Juming to conclusions again... Instability is basically gone. I backtracked in the posts and found out about the Arm7/Arm9 cache issue, and also the AS_MP3StreamPlay function I completely missed. I still get decode-error 1 in 10, but only on the first sample weirdly enough.
_________________
http://www.collectingsmiles.com/colors & http://www.collectingsmiles.com/hyena
#149989 - kusma - Mon Jan 28, 2008 2:04 pm
Jesse wrote: |
I guess my app is a real stress-test for this thing as I play many short mp3s after each other. |
This strikes me as a bad idea, since MP3-streams really don't have any well-defined starts and stops. The usual way to cope with this is to add silence to the beginning and end of the streams, but that won't work well if you want the different sounds stitched together to sound continuous. Maybe I'm not understanding what you're doing, though.
#149997 - Jesse - Mon Jan 28, 2008 6:12 pm
kusma wrote: |
This strikes me as a bad idea, since MP3-streams really don't have any well-defined starts and stops. |
Well, I'm only stitching together voice, so I'm hopefully fine. Thanks for the heads-up.
_________________
http://www.collectingsmiles.com/colors & http://www.collectingsmiles.com/hyena
#150002 - Noda - Mon Jan 28, 2008 7:23 pm
Jesse wrote: |
Ok. I got this working at last. I still don't know why my the original version never compiled properly for me, but after integrating the fixes I found and debugging the lib to understand what was missing, it is working as it should on my R4.
With both liblobby and libwifi (as well as my need for a RTC) in there is not enough memory on the Arm7. With the VRAM trick it worked as it should though, but I wish there was a cheaper way.
But anyway, thanks a bunch Noda, the thing I'm working on right now would have been meaningless without a mp3-lib. :)
Edit: I also get this metallic-like sound when playing a 16khz mono-mp3. It feels like one speaker is lagging behind. Here's the link if anyone wants to test it: http://www.collectingsmiles.com/temp/mono.rar
Edit2: I'm having problems playing multiple mp3's after each other. I can't find a good way to write a IsPlaying function, since the status-variable doesn't change until the Arm7 has processed the play-command. |
The mettalic sound is a stereo detection problem which appears with some version of Lame. It has been corrected in the (yet to released) current version.
Concerning the isPlaying() function:
inline bool isMP3Playing() { return (AS_GetMP3Status() & MP3ST_PLAYING); }
#150011 - Jesse - Mon Jan 28, 2008 9:54 pm
Noda wrote: |
The mettalic sound is a stereo detection problem which appears with some version of Lame. It has been corrected in the (yet to released) current version. |
Oh, I thought that was only the other way around. My sounds are mono. I hope you are right! :)
Noda wrote: |
Concerning the isPlaying() function:
inline bool isMP3Playing() { return (AS_GetMP3Status() & MP3ST_PLAYING); } |
That doesn't work since the status doens't set until Arm7 has processed the command. If I would use this, and check to early it would report that it isn't playing (I need to know that it has _finished_ playing). Right now I get around this by waiting a vbl after starting playing. That works ok for now.
Thanks.
_________________
http://www.collectingsmiles.com/colors & http://www.collectingsmiles.com/hyena
#150465 - Jesse - Mon Feb 04, 2008 11:19 pm
I managed to fix the metallic sound. It was due to mp3s always being played in with the surround delay, which cause the two speakers to play out of sync. A small hack in the arm7 code fixed that for me.
I've released an app using this lib now: http://forum.gbadev.org/viewtopic.php?t=14979
Thanks.
_________________
http://www.collectingsmiles.com/colors & http://www.collectingsmiles.com/hyena
#150467 - Noda - Mon Feb 04, 2008 11:30 pm
Could you post that hack please?
#150468 - Jesse - Mon Feb 04, 2008 11:38 pm
Well, I don't think it's very usable for you, but I just replaced Code: |
IPC_Sound->chan[IPC_Sound->mp3.channelR].snd.delay = IPC_Sound->mp3.delay;
IPC_Sound->chan[IPC_Sound->mp3.channelR].cmd |= SNDCMD_DELAY; |
with Code: |
IPC_Sound->chan[IPC_Sound->mp3.channelR].snd.delay = 0;
IPC_Sound->chan[IPC_Sound->mp3.channelR].cmd |= SNDCMD_PLAY; |
And thereby removing all surround possibilites. I guess a proper fix would be to:
1. Not post a delay command if mp3 is on mono or mp3.delay is already 0
2. Fix so that surround is not used if the surround flag isn't specified in Init.
_________________
http://www.collectingsmiles.com/colors & http://www.collectingsmiles.com/hyena
#150473 - Noda - Tue Feb 05, 2008 2:10 am
Surround works fine even with mono mp3's, but it may lead to some strange effect in particular cases (like your metallic sound).
The correct way to do this is to use this command:
Code: |
// set the default mp3 delay mode (warning: high values can cause glitches)
void AS_SetMP3Delay(u8 delay); |
Just call SetMP3Delay(AS_NO_DELAY); and you're done, no need for your correction.
If the delay is already 0, then it has the same effect as SNDCMD_PLAY.
#150635 - wondersye - Sat Feb 09, 2008 12:38 am
Hi,
I just wanted to share an alternate implementation of a mp3 player on the ARM7. It is by no means as complete as Noda's Advanced Sound Library (for my project, no need of stereo, surround, etc.) but, being more lightweight, the .bin fits in 61 ko. I tried to choose reliable and efficient solutions, all details are listed here.
By the way, many thanks to Noda, ThomasS, DekuTree64 and al for sharing their knowledge !
#153258 - Massif - Thu Mar 27, 2008 4:30 am
I'm having some issues with AS_SetMP3Loop().
I have one song that loops during the game. This works fine. However, when the game is over I stop it, set loop to false, then play another MP3. This song also loops even though it shouldn't.
NOTE: I also tried changing the AS_SetMP3Loop(true) to false, but the first song still loops. If I remove the call entirely, it doesn't loop.
Am I using the loop command incorrectly?
Here's the snippet that is loading the first and second MP3s:
Code: |
AS_MP3Stop();
AS_SetMP3Loop(true);
AS_MP3DirectPlay((u8*)ragingcards_80kbps_32kHz_mono_mp3, (u32)ragingcards_80kbps_32kHz_mono_mp3_size);
...
AS_MP3Stop();
AS_SetMP3Loop(false);
AS_MP3DirectPlay((u8*)victory_80kbps_32kHz_mono_mp3, (u32)victory_80kbps_32kHz_mono_mp3_size);
|
EDIT: Nevermind, I didn't even bother to check the inner workings of the function. It sets loop to true regardless of what is passed in.
_________________
Massif - It means mountain.
#153264 - TheMagnitude - Thu Mar 27, 2008 12:16 pm
Wow, a MP3 codec for DS, nice job!
#154194 - melw - Sat Apr 12, 2008 7:34 pm
I just noticed that in all of the projects I've used ASlib there's significant problems with R4DS - I have no idea if this general problem or just something related to this adapter / sd card, as there hasn't been other complaints, but running the AS_MP3Engine() on ARM7 causes continuous rumble noise. This is also true even if there's no playback, the noise exists always. In one of the project I also get immediate crash on R4. Using default exception handler gives a red screen but no text, however the noise keeps on going even after the crash.
All of the applications I tested run perfectly on M3 Lite, which is also my primary development adapter. Any ideas?
#154195 - SiW - Sat Apr 12, 2008 7:48 pm
I'm using ASlib with the R4DS. I'm having some issues (instability mostly - sometimes MP3 audio just cuts out), but I put them down to my code - do you have any examples of your projects I can try out?
I can't say I'm experiencing this rumble noise though. Which version of ASlib are you using? There is updated code on Noda's site and I'm using the latest.
#154196 - melw - Sat Apr 12, 2008 8:00 pm
For example this one. Although I just realized I'm probably using an old version, so let's see if compiling with the latest version helps here...
EDIT: Unzipped the newest aslib.rar (10/03/08) and now there's no sound, just blank screen and nothing seems to work even on the M3 Lite. :) Did anything change in the template or in the way how the library should be used?
EDIT 2: This seems to be the case even with the template. Did the upgrade break / add something that prevents ASlib from working with devkitARM R21? I'm bit confused now with all the simultaneous versions, what should be used and what works. The original v1.0 is so far the only one that I've used succesfully with R21, but gives the problems described before with R4DS.
#154201 - Noda - Sat Apr 12, 2008 8:55 pm
yes, the latest released ASLib version does not work with DKP r21. I've already fixed the problem, but still didn't released it yet as I'm quite busy with school work for now :/
#154209 - SiW - Sat Apr 12, 2008 10:13 pm
Sorry melw, I should have said I was also using the ARM7 fixes mentioned in this thread (either disabling the use of the RTC, or optimizing for size instead of speed) so that the ARM7 binary is small enough in r21.
#154214 - melw - Sat Apr 12, 2008 10:45 pm
SiW, No RTC used either, so ARM7 size isn't a problem.
Noda, if you have the latest development / test version laying around somewhere, I'd be more than willing to help with testing.
Until then, I guess I'll just rollback to older version and forget R4DS for a while... not in such a big hurry anyways.
#154224 - SiW - Sun Apr 13, 2008 12:58 am
I just tested snowflakes on my R4 and did indeed get the background "roar".
As to getting the current ASlib (or as current as you have available to download, Noda :)) running on r21, make sure you call AS_Init() in your ARM7 startup. I also have an IPC->sounddata = 0; after enabling the sound control register. I think that's all I had to do, based on some quick diff'ing
#154236 - melw - Sun Apr 13, 2008 8:39 am
SiW wrote: |
As to getting the current ASlib running on r21, make sure you call AS_Init() in your ARM7 startup. |
Thanks, this did the trick! Noda, having an updated template available for v1.1 would be a good idea, as the only/old one available doesn't call AS_Init() on the ARM7 side...
#154255 - Noda - Sun Apr 13, 2008 6:28 pm
Yes, I forgot this as I made the update quickly to fix M3/R4 problems ;)
I think the next release will be available in the next weeks...
#154256 - wintermute - Sun Apr 13, 2008 6:59 pm
Please don't.
Forthcoming libnds updates will trash this library completely
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog
#154257 - Noda - Sun Apr 13, 2008 7:12 pm
Then I'll update it.
I don't really understand why you put so much efforts to prevent people from releasing their own lib why may be useful for some other. Even if it's not perfect, having the choice of what to use is better than not having it...
And I know the next libnds update will throw away the current IPC struct to use IPC FIFO instead, but that's not a big to update my lib to work with it as it's only a matter of command sync, nothing else.
#154262 - wintermute - Sun Apr 13, 2008 8:35 pm
Some libs are completely unsuitable for the DS ...
It's not about preventing people releasing their own libs, it's about trying to get people to stop releasing crap that frustrates developers when they realise all this stuff is too resource intensive and has to be ripped out again.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog
#154265 - SiW - Sun Apr 13, 2008 9:25 pm
Don't you think this is a rather presumptious attitude though? Having had to support my own software before I do understand where you're coming from, but it seems a little insulting to assume that everybody who makes use of this particular lib is unaware of the problems or suitability.
#154275 - tepples - Sun Apr 13, 2008 11:44 pm
wintermute wrote: |
It's not about preventing people releasing their own libs, it's about trying to get people to stop releasing crap that frustrates developers |
Do you have any tips for making interesting "libs" without making "crap that frustrates developers"
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#154284 - Doom5 - Mon Apr 14, 2008 2:37 am
wintermute wrote: |
Some libs are completely unsuitable for the DS ...
It's not about preventing people releasing their own libs, it's about trying to get people to stop releasing crap that frustrates developers when they realise all this stuff is too resource intensive and has to be ripped out again. |
It's not as if it'll be built into the official libnds and you'd be forced to use the library. If more amateur developers, or ones who feel the library does what it needs for them, what's the issue?
If you want to design your own sound system is your homebrew, as most developers do, that's your prerogative.
#154302 - Michoko - Mon Apr 14, 2008 11:22 am
A new ASlib update? This is great news!
<sarcasm>
(but I suppose I must be totally stupid and ignorant to think that way :P)
</sarcasm>
Can't wait for the release. Thanks Noda for your cool libs (EFSLib and ASLib were really life savers for me)
Cheers
Michoko
#154305 - thoduv - Mon Apr 14, 2008 1:30 pm
I don't understand why ASlib is as bas as you say. I've never encountered any problems you mention while using it. It is also quite simple to build: it's only one quite light source file for each CPU.
The only problem could be the IPC system, which is memory-based and statically located, but still, I don't care since it manages to do exactly what I want it to do, and is easy to integrate to a project.
#154308 - melw - Mon Apr 14, 2008 4:10 pm
Naeh, Wintermute is just cranky as this library doesn't fall into same philosophy as libnds - as in, everyone should be able to use it and it should not limit the developer in any way. I don't want to stir this dev-politics any further, but no matter of personal opinions, there's clearly plenty of projects where MP3 playback is useful. Better let the developers make their decisions, aight?
BTW. Same applies for liblobby (that is also going to get broken after forthcoming libnds updates). But as long as the promised new dswifi library with ad-hoc connectivity is not here, I'm more than happy to use it.
#163602 - a128 - Mon Oct 06, 2008 9:49 am
chishm wrote: |
In r21, with the changes I suggest previously, the size is 0x03807970, which is 4724 bytes difference. I'm not sure what caused such a large size change, but that is the cause of memory overflows when compiling with r21. |
as wintermute already said devkitARM R21 uses 96K for ARM7
so it has to be working?!!!
#165231 - Echo49 - Sat Dec 13, 2008 9:06 pm
One year after my last post, I decided to try this out (finally). I got what appears to be the latest version from http://noda.free.fr/nds/, but I've hit a few snags.
Sometimes, changes to my other code causes the mp3 to suddenly stop for no reason at all. Commenting out iprintf()s seems to fix this. Is this because it's not decoding in time? Sampling rate jumps to 0 when this happens, perhaps it's not reading any more data from my file? Maybe it runs out of RAM. Most likely I won't need to use VRAM_D, does chishm's hack still work on this release?
If I use AS_SetMP3Rate() at all, the mp3 will instantly stop working (weird sounds associated with data corruption in previous posts), usually leading to a crash.
I had a problem with sampling rate being read correctly but actual playback at half the speed, but it seems to work fine for the test mp3 so I'll need to see if this is a problem with Audacity instead.
#165239 - a128 - Sun Dec 14, 2008 10:16 am
Echo49 wrote: |
One year after my last post, I decided to try this out (finally). I got what appears to be the latest version from http://noda.free.fr/nds/, but I've hit a few snags.
|
maybe try this mp3/sfx lib from isabella (eric) it seems fine
http://blea.ch/wiki/index.php/Thmp3
#165991 - a128 - Thu Jan 15, 2009 7:03 pm
BUG FIX if you change the rate and using AS_SoundDirectPlay
as_lib9.c
Code: |
// play a sound directly using the given channel
void AS_SoundDirectPlay(u8 chan, SoundInfo sound)
{
IPC_Sound->chan[chan].snd = sound;
IPC_Sound->chan[chan].busy = true;
IPC_Sound->chan[chan].cmd = SNDCMD_PLAY;
IPC_Sound->chan[chan].volume = sound.volume;
if(IPC_Sound->surround) {
IPC_Sound->chan[chan + IPC_Sound->num_chan].snd = sound;
IPC_Sound->chan[chan + IPC_Sound->num_chan].busy = true;
IPC_Sound->chan[chan + IPC_Sound->num_chan].cmd = SNDCMD_DELAY;
// set the correct surround volume & pan
AS_SetSoundVolume(chan, sound.volume);
//NEW BUG FIX?!!!
// set the correct surround rate
AS_SetSoundRate(chan, sound.rate);
} else {
IPC_Sound->chan[chan].pan = sound.pan;
IPC_Sound->chan[chan].snd.rate = sound.rate;//NEW BUG FIX?!!!
}
} |
#166009 - chatterbug89 - Fri Jan 16, 2009 4:51 am
I noticed someone on the PAlib forums also had this issue but it was never resolved:
In a nutshell I am not able to stop an mp3, so, if I do something like this:
AS_MP3DirectPlay((u8*)test, (u32)test_size);
and then stop it later on with
AS_MP3Stop();
it never stops and just keeps playing. Also, if the mp3 ends and I call AS_MP3DirectPlay((u8*)test, (u32)test_size); again the song starts playing (as would be expected).
If i'm using streaming when I use stop I get either a crash or a nice little loop of the last couple seconds of the song playing over and over again.
I've been digging through forum posts and trying all kinds of random things with no luck. All the sound playing stuff seems to work just fine however, but...any volume changing stuff, panning, etc. with sounds or mp3's seems to not work. In fact, it doesn't even seem to work in the PALib demo. What's weird is others are reporting this to work. If anyone has any idea what I could try it'd be appreciated (I posted on the PAlib forums also, but somehow I don't think I'll get an answer there).
EDIT: Yes, I have tested everything on real hardware and I have been using no$gba as my emulator
EDIT2: I seemed to have created a temporary solution to my problem that allows me to change the song by simply jut changign the file being read at any random point like this:
Code: |
if(mp3file)
FILE_CLOSE(mp3file);
mp3file = FILE_OPEN("testtwo.mp3");
if(mp3file) {
// start playing
IPC_Sound->mp3.stream = true;
IPC_Sound->mp3.cmd = MP3CMD_PLAY;
}
|
Now, this is a quick and dirty solution that would work for now..however, I'm not sure if because I cahnged the stream mid-way like this if the file will still play to the very end. Could anyone make a suggestion for this quick and dirty fix (unlless you know how to fix my real initial problem).
EDIT3: Yeah, I thought this would happen. If the file is suspose to end in a couple seconds and you start streaming from another file that's longer, it will end when the first file was suspose to end...so...i need to update those variables somehow without breaking anything.
#166394 - hacker013 - Sat Feb 07, 2009 9:52 am
is it already tested of this still works with the newest DKA ?
_________________
Website / Blog
Let the nds be with you.
#166396 - AxemRed - Sat Feb 07, 2009 11:12 am
hacker013 wrote: |
is it already tested of this still works with the newest DKA ? |
It's possible to modify it to work, but not really worth the effort unless you absolutely need MP3 support for your game.
#166403 - hacker013 - Sat Feb 07, 2009 1:20 pm
AxemRed wrote: |
hacker013 wrote: | is it already tested of this still works with the newest DKA ? |
It's possible to modify it to work, but not really worth the effort unless you absolutely need MP3 support for your game. |
why do you say it is it not worth?
_________________
Website / Blog
Let the nds be with you.
#166783 - a128 - Tue Feb 17, 2009 6:42 pm
I like AS lib for sound fx because it already has surround , reverb via a tricky delay trick.
anyway.
here is a wav file loader using FAT for it
Code: |
SoundInfo* AS_LoadWav(const char *filename) |
Code: |
//--- WAV loading
//Audio sample structure type
typedef struct _thSample_t {
u32 start; //start of sample in ram
u32 loopstart; //where to start looping sample (bytes from start of sample)
int len; //number of samples in sample
int rate; //sample rate (in hz, converted on arm7 side, mebbe shoiuld be u16 like the actual reg?)
// char level; //default volume
// char pan; //left/rightpan
u32 opts; //
} thSample_t;
//for reading wav data
typedef struct _riffHeader_t {
char id[4];
u32 len;
char type[4];
} riffHeader_t;
//riff chunk header
typedef struct _riffChunkHdr_t {
char type[4];
u32 len;
} riffChunkHdr_t;
typedef struct _adpcmHeader_t {
s16 firstSample;
char stepTableIndex;
char reserved;
} adpcmHeader_t;
//wave specific header
typedef struct _riffWaveFmt_t {
u16 formatTag; //always 0x01
u16 channels; //number of channels
u32 rate; //sample rate in hz
u32 bytesPerSec; //bytes per second
u16 bytesPerSample; //bytes per sample 1=8bitmono, 2=8bitstereo or 16bitmono, 4-16bitstereo (block alignment for adpcm)
u16 bitsPerSamp; //bitsper sample
} riffWaveFmt_t;
//bytesPerSample possibilities (these name sux >_>)
#define WAVE_8 0x1 //8bit mono for sure
#define WAVE_8_16 0x2 //8bit stereo or 16 bit mono wth?! (use bitsPerSamp for more detail)
#define WAVE_16 0x4 //16 bit stereo for sure
//
//formatTag vales
#define WAVE_FORMAT_PCM 0x0001 //pcm data
//only adpcm supported on ds
#define WAVE_FORMAT_MULAW 0x0101 //IBM mu-Law
#define WAVE_FORMAT_ALAW 0x0102 //IBM a-Law format
#define WAVE_FORMAT_ADPCM 0x0103 //IBM AVC Adaptive Differntial PCM
//inline sub function to help simplify wave messyness +_+
inline void _SampleLoadWav8mono(FILE *fp, s8 *smpbuf, SoundInfo *smp, int len) {
int c=0;
fread(smpbuf,1,len,fp);
do {
*smpbuf=*smpbuf-0x80;
smpbuf++;
} while(++c<len);
smp->size=len;
smp->format=AS_PCM_8BIT;
}
//inline sub function to help simplify wave format messyness +_+
inline void _SampleLoadWav16mono(FILE *fp, s16 *smpbuf, SoundInfo *smp, int len) {
len>>=1;
fread(smpbuf,2,len,fp); //whaddaya know... microsoft stores wav data as 16 bit signed, while it stores 8bit unsigned... W T F?!?
smp->size=len;
smp->format=AS_PCM_16BIT;
}
//create SoundInfo from wav
//taken from thaudio9.c from Isabella. thanx!
SoundInfo* AS_LoadWav(const char *name)
{
MSG("AS_LoadWav\n");
if(as_default_rate==0) {
MSG("Error: You have to AS_INit() first\n");
for(;;);
}
SoundInfo *snd;
FILE *fp;
//MSG("gonna open it...\n");
if((fp=fopen(name,"rb"))!=NULL) {
//MSG("reading header\n");
riffHeader_t riffHeader;
fread(&riffHeader,sizeof(riffHeader_t),1,fp);
if((strncmp(riffHeader.id,"RIFF",4)==0)&&(strncmp(riffHeader.type,"WAVE",4)==0)) {
//MSG("reading chunk header\n");
riffChunkHdr_t riffChunkHdr;
fread(&riffChunkHdr,sizeof(riffChunkHdr_t),1,fp);
if(strncmp(riffChunkHdr.type,"fmt ",4)==0) {
riffWaveFmt_t riffWaveFmt;
//MSG("reading riff wave fmt\n");
fread(&riffWaveFmt,sizeof(riffWaveFmt_t),1,fp);
riffChunkHdr.len-=sizeof(riffWaveFmt_t); //len = remainder in case any extra data after format struct
//MSG("reading chunk header again %04x %d\n",ftell(fp),riffChunkHdr.len-sizeof(riffWaveFmt_t));
do {
fseek(fp,riffChunkHdr.len,SEEK_CUR); //get over this...
fread(&riffChunkHdr,sizeof(riffChunkHdr_t),1,fp);
if(feof(fp)) {
MSG("unexpected end of .wav file!\n");
return(NULL);
}
} while(strncmp(riffChunkHdr.type,"data",4)!=0);
//riffChunkHdr.len should == size of ALL wav data in bytes
//go ahead here and malloc for thSample_t struct as well ^^
//todo: fix bugs here!!! malloc size may not include adpcm header... buff offset not right at all either..
snd=(thSample_t *)malloc(riffChunkHdr.len+sizeof(SoundInfo)+3);
if(snd) {
u32 buff=(((u32)snd)+sizeof(SoundInfo)+3)&~0x3; //consolidate mallocs
//MSG("m:%08x,b:%08x\n",retval,buff);
//MSG("reading %d bytes of data @%dhz type:%04x\n",riffChunkHdr.len,riffWaveFmt.rate,riffWaveFmt.formatTag);
if(riffWaveFmt.formatTag==WAVE_FORMAT_PCM) {
if(riffWaveFmt.bytesPerSample==WAVE_8) {
MSG("8bit wave\n");
_SampleLoadWav8mono(fp,(s8*)buff, snd,riffChunkHdr.len);
} else if(riffWaveFmt.bytesPerSample==WAVE_8_16) {
MSG("16bit wave\n");
_SampleLoadWav16mono(fp,(s16*)buff,snd, riffChunkHdr.len);
//8stereo unsupported for now anyway!! (need auto channel selection first..)
} else {
//16stereo unsupported!
}
} else { //i cant deal w/this format u_u;;
MSG("Unsupported .wav format!\n");
free(snd);
return(NULL);
}
snd->data=buff;
snd->rate=riffWaveFmt.rate;//ok?
snd->volume=127;
snd->pan=64;
snd->loop=0;
// (counted in words, ie. N*4 bytes)
//snd->loopstart=0;
snd->priority=0;
snd->delay=as_default_delay;
MSG("wav loaded with rate %d!\n",snd->rate);
} else {
// MSG("cannot malloc %d bytes for wav file! :/\n",riffChunkHdr.len);
}
}
} else {
//MSG("%s is not a .wave file!\n",name);
}
fclose(fp);
}
return snd;
}
|
#166787 - hacker013 - Tue Feb 17, 2009 8:00 pm
aslib doesn't work anymore with the newest devkitARM
_________________
Website / Blog
Let the nds be with you.
#166790 - a128 - Tue Feb 17, 2009 11:10 pm
hacker013 wrote: |
aslib doesn't work anymore with the newest devkitARM |
it work with devkitARM but it does not work with the latest libnds...use the older libnds ...like I do....
#166814 - wintermute - Thu Feb 19, 2009 1:36 pm
a128 wrote: |
hacker013 wrote: | aslib doesn't work anymore with the newest devkitARM |
it work with devkitARM but it does not work with the latest libnds...use the older libnds ...like I do.... |
Please don't advise people to use old releases. This causes major support issues.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog
#166864 - a128 - Sat Feb 21, 2009 9:55 am
wintermute wrote: |
a128 wrote: | hacker013 wrote: | aslib doesn't work anymore with the newest devkitARM |
it work with devkitARM but it does not work with the latest libnds...use the older libnds ...like I do.... |
Please don't advise people to use old releases. This causes major support issues. |
Ok, you mean using an older version does not drive the new libnds further?! I do not think so.
#166870 - TwentySeven - Sat Feb 21, 2009 1:53 pm
Please dont start this crap again.
#167517 - Dud86 - Mon Mar 16, 2009 9:46 pm
Is there anyway of getting the DS to play 128kbps or higher Mp3 files?? As im making a DJ game and sound quality is really important!
Cheers Duds!!
#167528 - renatobs - Tue Mar 17, 2009 2:05 pm
Hi. I?d like to know if I could and how to do to play a mp3, stop in a certain point of this ( save this point ), play another mp3 for a time, stop this and go back to the first mp3, but contnue by the point where it was ?! Could someone help me with this ?!? Could I improve the code to it or the code already have this ( and I don?t know ) ?!?
Another thing: when I need to stop many times one mp3 to play another, the AS_lib stop to play and don?t play more. Why ?!? I need to wait some special moment to stop a mp3 to play another one ?!?!
Thanks !!!
#167554 - AxemRed - Wed Mar 18, 2009 8:24 am
renatobs wrote: |
Another thing: when I need to stop many times one mp3 to play another, the AS_lib stop to play and don?t play more. Why ?!? I need to wait some special moment to stop a mp3 to play another one ?!?! |
AS_MP3Stop is broken: It doesn't set mp3file to NULL, so FILE_CLOSE is called twice on the same file handle if you stop and then play another mp3.
#167579 - renatobs - Wed Mar 18, 2009 9:51 pm
hunnn... ok, but what have I do to resolve (arrange) this ?!? Sorry for my lack of knowledge !
And the other question ? Somebody that could help me ?!?!
Thanks !!
#167609 - renatobs - Thu Mar 19, 2009 10:03 pm
Well, it?s possible to get a peace of the RAM ( like 1 Mb ), create a "volatile variable" and using the FAT ( libfat / EFS ) read and put there the mp3 music and play direct form RAM ? Cuz I could not do the ASlib play mp3 stream, but I have space in the RAM to change the mp3. Have some way to convert the mp3 files to "*.o" ( this is the files that the ASlib read ), put in a directory and use the libfat to change the file in the RAM and play with with MP3DirectPlay ( using a pointer )... ?!? I think that this will help a lot of people like me. I?m doing a remake of the game "Shining Force 2" ( the name is Shining Force 2 Tribute and have some videos on YOU TUBE ) and I love the ASlib. The problem is that I already reach the top of RAM put only 2 mp3?s music on the game, and I need to make a lot of more things and put a lot of more musics, but I?d like to use MP3, not WAV. I have sucess to use ASlib together my code, but until now I didn?t use libfat for nothing.
#168657 - renatobs - Wed May 13, 2009 4:39 pm
My ASLIb is working !!! And with EFSLib... the ony thing that I did was his:
as_lib9.h
// locate the IPC structure after the libnds one
#define IPC_Sound ((IPC_SoundSystem*)((u32)(IPC) + sizeof(TransferRegion)))
// file access functions
/*
#ifdef AS_USE_EFS
// use EFSlib functions
#define MP3FILE EFS_FILE
#define FILE_CLOSE(f) EFS_fclose(f)
#define FILE_OPEN(f) EFS_fopen(f)
#define FILE_READ(buf, size, num, f) EFS_fread(buf, size, num, f)
#define FILE_SEEK(f, pos, off) EFS_fseek(f, pos, off)
#define FILE_TELL(f) EFS_ftell(f)
#else */
// use libfat functions
#define MP3FILE FILE
#define FILE_CLOSE(f) fclose(f)
#define FILE_OPEN(f) fopen(f, "rb")
#define FILE_READ(buf, size, num, f) fread(buf, size, num, f)
#define FILE_SEEK(f, pos, off) fseek(f, pos, off)
#define FILE_TELL(f) ftell(f)
//#endif
I disable all the AS_USE_EFS macros. The EFS works with the FAT normal macros. The problem that I?m having now is when I need use the EFS to load some VRAM datas while the MP3 is playing. Some times all sounds stop or the game freeze. The other thing is when one MP3 stop to play another, so all sounds stop too. These problems happen sometimes, not often.
Some ideia ? What need I do to can use swiCopy, dmaCopy, memCopy without problem even when I?m using EFS ?
The ASLib is fantastic cuz I can play MP3 while do sound effects too. Please, someone that is ESXCELENT with C coding improve this !!! Where is NODA ?!?!?