Homebrew Homebrew Development

Rinnegatamante

Well-Known Member
Member
Joined
Nov 24, 2014
Messages
3,162
Trophies
2
Age
29
Location
Bologna
Website
rinnegatamante.it
XP
4,858
Country
Italy
Absolutely, I've done it plenty. That's not to say there isn't anything wrong with DSP implementation, but it's definitely not merely because of simultaneously channel usage.

MMhhh that sounds strange since the only "irregularity" could be that (since if i wait a bit till the first sound ends and ten try to play the next ones, it plays fine without any problem).

That's the used code, maybe you can find something strange in it:
Code:
void CtrAudio::SE_Play(std::string const& file, int volume, int /* pitch */) {
  
   // Select an available audio channel
   int i = 0;
   while (i < num_channels){
     if (!isPlayingCallback(i)) break;
     i++;
     if (i >= num_channels){
       Output::Warning("Cannot execute %s sound: audio-device is busy.\n",file.c_str());
       return;
     }
   }
  
   if (audiobuffers[i] != NULL){
     #ifndef USE_CACHE
     linearFree(audiobuffers[i]);
     audiobuffers[i] = NULL;
     #endif
     if (isDSP) free(dspSounds[i]);
   }
  
   // Init needed vars
   bool isStereo = false;
   int audiobuf_size;
   int codec;
   DecodedSound myFile;
  
   #ifdef USE_CACHE
   // Looking if the sound is in sounds cache
   int cacheIdx = lookCache(file.c_str());
   if (cacheIdx < 0){
   #endif
  
     // Searching for the file
     std::string const path = FileFinder::FindSound(file);
     if (path.empty()) {
       Output::Debug("Sound not found: %s", file.c_str());
       return;
     }
  
     // Opening and decoding the file
     int res = DecodeSound(path, &myFile);
     if (res < 0) return;
     #ifdef USE_CACHE
     else sprintf(soundtable[res],"%s",file.c_str());
     #endif
    
   #ifdef USE_CACHE
   }else myFile = decodedtable[cacheIdx];
   #endif
  
   // Processing sound info
   audiobuffers[i] = myFile.audiobuf;
   int samplerate = myFile.samplerate;
   audiobuf_size = myFile.audiobuf_size;
   if (isDSP) codec = NDSP_CHANNELS(isStereo + 1) | NDSP_ENCODING(myFile.format);
   else codec = SOUND_FORMAT(myFile.format);
   isStereo = myFile.isStereo;
  
   #ifndef NO_DEBUG
   Output::Debug("Playing sound %s:",file.c_str());
   Output::Debug("Samplerate: %i",samplerate);
   Output::Debug("Buffer Size: %i bytes",audiobuf_size);
   #endif
  
   // Playing the sound
   float vol = volume / 100.0;
   if (isStereo && (!isDSP)){
    
     // We need a second channel where to execute right audiochannel since csnd supports only mono sounds natively
     int z = i+1;
     while (z < num_channels){
       if (!isPlayingCallback(z+0x08)) break;
       z++;
       if (z >= num_channels){
         Output::Warning("Cannot execute %s sound: audio-device is busy.\n",file.c_str());
         return;
       }
     }
     #ifndef USE_CACHE
     if (audiobuffers[z] != NULL) linearFree(audiobuffers[z]);

     // To not waste CPU clocks, we use a single audiobuffer for both channels so we put just a stubbed audiobuffer on right channel
     audiobuffers[z] = (u8*)linearAlloc(1);
     #endif
    
     int chnbuf_size = audiobuf_size>>1;
     csndPlaySound(i+0x08, SOUND_LINEAR_INTERP | codec, samplerate, vol, -1.0, (u32*)audiobuffers[i], (u32*)audiobuffers[i], chnbuf_size); // Left
     csndPlaySound(z+0x08, SOUND_LINEAR_INTERP | codec, samplerate, vol, 1.0, (u32*)(audiobuffers[i] + chnbuf_size), (u32*)(audiobuffers[i] + chnbuf_size), chnbuf_size); // Right
    
   }else{
     if (isDSP){
       ndspChnReset(i+0x08);
       ndspChnWaveBufClear(i+0x08);
       ndspChnSetInterp(i+0x08, NDSP_INTERP_LINEAR);
       ndspChnSetRate(i+0x08, float(samplerate));
       ndspChnSetFormat(i+0x08, codec);
       dspSounds[i] = (ndspWaveBuf*)calloc(1,sizeof(ndspWaveBuf));
       createDspBlock(dspSounds[i], myFile.bytepersample, audiobuf_size, false, (u32*)audiobuffers[i]);
       ndspChnWaveBufAdd(i+0x08, dspSounds[i]);
     }else csndPlaySound(i+0x08, SOUND_LINEAR_INTERP | codec, samplerate, vol, 0.0, (u32*)audiobuffers[i], (u32*)audiobuffers[i], audiobuf_size);
   }
}

Where:

Code:
isPlayingCallback = ndspChnIsPlaying;
     clearCallback = ndspChnWaveBufClear;
 

TheCruel

Developer
Banned
Joined
Dec 6, 2013
Messages
1,350
Trophies
2
XP
3,131
Country
United States
Not sure, but one problem is that you using "i + 0x8" for ndsp channels. The functions expect values 0-23. The internal array is a buf[24] so it likely crashes with channel value > 23. Though I doubt that's your problem since that would only crash if you use were using more than like a dozen channels at the same time with this code, and you're probably only using a few.

If I had to guess, it's perhaps the fact that the ndsp audio loop is run in another thread and you are using ndspChnIsPlaying to find an open channel. If you run this function twice in a row, it may not yield time to the other thread to give it time to process the queue and play a sound to occupy it. So then you're messing up the first buffer on your second call. Try hardcoding a couple different channels or something to test, or at least do a couple printf to see if it is indeed trying to play them on the same channel.
 
Last edited by TheCruel,

Rinnegatamante

Well-Known Member
Member
Joined
Nov 24, 2014
Messages
3,162
Trophies
2
Age
29
Location
Bologna
Website
rinnegatamante.it
XP
4,858
Country
Italy
Not sure, but one problem is that you using "i + 0x8" for ndsp channels. The functions expect values 0-23. The internal array is a buf[24] so it likely crashes with channel value > 23. Though I doubt that's your problem since that would only crash if you use were using more than like a dozen channels at the same time with this code, and you're probably only using a few.

If I had to guess, it's perhaps the fact that the ndsp audio loop is run in another thread and you are using ndspChnIsPlaying to find an open channel. If you run this function twice in a row, it may not yield time to the other thread to give it time to process the queue and play a sound to occupy it. So then you're messing up the first buffer on your second call. Try hardcoding a couple different channels or something to test, or at least do a couple printf to see if it is indeed trying to play them on the same channel.

It looks like it crashes at the third sound that tries to get played with channels taken in this order: (first sound 0x08, second sound 0x09, third sound 0x08).
 

YugamiSekai

Mr. Picross
Member
Joined
Dec 24, 2014
Messages
2,015
Trophies
1
Age
22
XP
2,387
Country
United States
Not only, it can also open notifications and dump them (text + MPO image).
Also, can you tell me what's wrong with this code?

*path*/main.c: In function 'main':
*path*/main.c:27:24: error: 'Test' undeclared (first use in this function)
NEWS_AddNotification(Test, 1, Test, 4, NULL, 0, NULL);
^
*path*/main.c:27:24: note: each undeclared identifier is reported only once for each function it appears in
make[1]: *** [main.o] Error 1
make: *** [build] Error 2
#include <3ds.h>
#include <3ds/services/news.h>
#include <stdio.h>


int main(int argc, char **argv)
{
//Initialize gfx (note: not needed if you're using SF2Dlib)
gfxInitDefault();

newsInit();

while (aptMainLoop())
{

u32 kDown = hidKeysDown();

if (kDown & KEY_START) break; // break in order to return to hbmenu

// Flush and swap framebuffers, this is needed for rendering these will not be needed when using SF2D lib
gfxFlushBuffers();
gfxSwapBuffers();

//Wait for VBlank, this is needed for rendering these will not be needed when using SF2D lib
gspWaitForVBlank();

NEWS_AddNotification(Test, 1, Test, 4, NULL, 0, NULL);

newsExit();
}
gfxExit();
return 0;
}
 

MasterFeizz

Well-Known Member
Member
Joined
Oct 15, 2015
Messages
1,098
Trophies
1
Age
29
XP
3,710
Country
United States
Also, can you tell me what's wrong with this code?

*path*/main.c: In function 'main':
*path*/main.c:27:24: error: 'Test' undeclared (first use in this function)
NEWS_AddNotification(Test, 1, Test, 4, NULL, 0, NULL);
^
*path*/main.c:27:24: note: each undeclared identifier is reported only once for each function it appears in
make[1]: *** [main.o] Error 1
make: *** [build] Error 2
#include <3ds.h>
#include <3ds/services/news.h>
#include <stdio.h>


int main(int argc, char **argv)
{
//Initialize gfx (note: not needed if you're using SF2Dlib)
gfxInitDefault();

newsInit();

while (aptMainLoop())
{

u32 kDown = hidKeysDown();

if (kDown & KEY_START) break; // break in order to return to hbmenu

// Flush and swap framebuffers, this is needed for rendering these will not be needed when using SF2D lib
gfxFlushBuffers();
gfxSwapBuffers();

//Wait for VBlank, this is needed for rendering these will not be needed when using SF2D lib
gspWaitForVBlank();

NEWS_AddNotification(Test, 1, Test, 4, NULL, 0, NULL);

newsExit();
}
gfxExit();
return 0;
}

There are many things wrong with the code. Like rinnegatamante said, you haven't declared nor defined Test, which needs to be a utf-16 string. Second you are calling newExit() inside a while loop, and you are also calling NEWS_AddNotification inside that loop which will "flood" your inbox. Lastly you are not using hidScanInput() so you will never be able to get out of that loop, since START will never be pressed
 

MasterFeizz

Well-Known Member
Member
Joined
Oct 15, 2015
Messages
1,098
Trophies
1
Age
29
XP
3,710
Country
United States

Rinnegatamante

Well-Known Member
Member
Joined
Nov 24, 2014
Messages
3,162
Trophies
2
Age
29
Location
Bologna
Website
rinnegatamante.it
XP
4,858
Country
Italy
I don't think there are any tutorials, but it has relatively simple instructions set: https://github.com/fincs/picasso/blob/master/Manual.md
I have written a few shaders but am no expert, if you need help for a specific shader I can give you better information.

That could be really wonderful, i need a specific shader that should execute a texture operation called HARD_LIGHT since executing it with CPU results in a massive framedrop.

You can find much more information about how this work (and also you can ask directly to Ghabry which will probably help you a lot compared to what i can do <.< ) here: https://github.com/Rinnegatamante/easyrpg-player-3ds/issues/11
(It should be used with sf2dlib. I'll obviously add a custom function in sf2dlib to change shaderprogram on the fly cause the shader needs to be used only in certain circumstances)
 

MasterFeizz

Well-Known Member
Member
Joined
Oct 15, 2015
Messages
1,098
Trophies
1
Age
29
XP
3,710
Country
United States
That could be really wonderful, i need a specific shader that should execute a texture operation called HARD_LIGHT since executing it with CPU results in a massive framedrop.

You can find much more information about how this work (and also you can ask directly to Ghabry which will probably help you a lot compared to what i can do <.< ) here: https://github.com/Rinnegatamante/easyrpg-player-3ds/issues/11
(It should be used with sf2dlib. I'll obviously add a custom function in sf2dlib to change shaderprogram on the fly cause the shader needs to be used only in certain circumstances)

I just looked into it, you don't need a special shader since the HARD_LIGHT operand seams to be just a simple blending operation. The simplest way to achieve what you need is to replace the toneblit function with a simple GPU rendered function that configures the diffuse color and texture blending function, that way the texture and color will blend giving you the same effect.

Edit: I may have confused you, take a look at this function in ctrulib: GPU_SetTexEnv
 
Last edited by MasterFeizz,

Rinnegatamante

Well-Known Member
Member
Joined
Nov 24, 2014
Messages
3,162
Trophies
2
Age
29
Location
Bologna
Website
rinnegatamante.it
XP
4,858
Country
Italy
I just looked into it, you don't need a special shader since the HARD_LIGHT operand seams to be just a simple blending operation. The simplest way to achieve what you need is to replace the toneblit function with a simple GPU rendered function that configures the diffuse color and texture blending function, that way the texture and color will blend giving you the same effect.

Are you sure this will perform the same effect of HARD_LIGHT?
I cannot see a proper cominefunc for this:

Code:
GPU_COMBINEFUNC {
  GPU_REPLACE = 0x00,
  GPU_MODULATE = 0x01,
  GPU_ADD = 0x02,
  GPU_ADD_SIGNED = 0x03,
  GPU_INTERPOLATE = 0x04,
  GPU_SUBTRACT = 0x05,
  GPU_DOT3_RGB = 0x06,
  GPU_MULTIPLY_ADD = 0x08,
  GPU_ADD_MULTIPLY = 0x09
}
 
Last edited by Rinnegatamante,

MasterFeizz

Well-Known Member
Member
Joined
Oct 15, 2015
Messages
1,098
Trophies
1
Age
29
XP
3,710
Country
United States
Are you sure this will perform the same effect of HARD_LIGHT?
I cannot see a proper cominefunc for this:

Code:
GPU_COMBINEFUNC {
  GPU_REPLACE = 0x00,
  GPU_MODULATE = 0x01,
  GPU_ADD = 0x02,
  GPU_ADD_SIGNED = 0x03,
  GPU_INTERPOLATE = 0x04,
  GPU_SUBTRACT = 0x05,
  GPU_DOT3_RGB = 0x06,
  GPU_MULTIPLY_ADD = 0x08,
  GPU_ADD_MULTIPLY = 0x09
}
Modulate will multiply the 2, should give the same effect I believe
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • K3Nv2 @ K3Nv2:
    Got two new stds in one night
    +1
  • BigOnYa @ BigOnYa:
    Giggity
    +1
  • The Catboy @ The Catboy:
    I don't bite! Minus the times when I did bite
  • The Catboy @ The Catboy:
    Like 5 minutes ago
  • K3Nv2 @ K3Nv2:
    Billie needs her lunch
  • K3Nv2 @ K3Nv2:
    Ffs papa brought back the cheeseburger pizza it's like the only decent pie they had since the 80s
  • BigOnYa @ BigOnYa:
    I'm not a fan of papa johns, but that does sound good. We hardly order out pizza, I like making my own, but when we do its donatoes
  • K3Nv2 @ K3Nv2:
    I get them like once every two months anymore
  • K3Nv2 @ K3Nv2:
    Just because it's half a mile from where I live
  • BigOnYa @ BigOnYa:
    Request next time you order, that Shaq deliver it to you
  • K3Nv2 @ K3Nv2:
    I want him to buy me a chain also
  • K3Nv2 @ K3Nv2:
    Open it right next to the one we have
    +1
  • BakerMan @ BakerMan:
    guys should i make a new thread and just count the amount of posts until kyle, luke or leo joins the thread for fun?
  • BakerMan @ BakerMan:
    kyle's fine, just waiting for that wario joke

    luke and leo though, they yap until the thread's enjoyability is about halved
  • K3Nv2 @ K3Nv2:
    Leo is Luke's alterego when he gets hard
  • BigOnYa @ BigOnYa:
    Luke is gone, he got banned. And I'm surprised Leo hasn't yet
  • K3Nv2 @ K3Nv2:
    Subway was actually pretty decent tonight
  • BigOnYa @ BigOnYa:
    Wut you get, a seafood and psi salad sub
  • K3Nv2 @ K3Nv2:
    Psi had my footlong meatball special
    +1
  • PandaPandel @ PandaPandel:
    i want a meatball sandwich
    now
  • K3Nv2 @ K3Nv2:
    Gay
  • BigOnYa @ BigOnYa:
    Bout time you came out and admitted it
    +1
  • K3Nv2 @ K3Nv2:
    Bigonya talks to himself often
    +1
  • btei @ btei:
    papa johns makes me SHIT
  • S @ salazarcosplay:
    hello everyone
    S @ salazarcosplay: hello everyone