 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
Tydude4Christ
Joined: 24 Aug 2006 Posts: 8 Location: St. Louis, MO, U.S.A.
|
Posted: Mon Feb 16, 2009 5:15 am Post subject: Questions of multi-threading |
|
|
| Hello all, I'm creating a homebrew game and I'm trying to add sound to it. I've got it working with the mp3 sample in the sdk, but it is in my main thread so it slows down my game significantly. I was wondering if there was a sample in the sdk that deals with multi-threading or any homebrew that uses multi-threading that I can learn from. Also is there anything I should know about how threads are prioritized so as to get smooth performance. Thanks and sorry if this has been asked before. |
|
| Back to top |
|
 |
NoEffex
Joined: 27 Nov 2008 Posts: 108
|
Posted: Mon Feb 16, 2009 7:00 am Post subject: |
|
|
(Horrible example) but bakon abuses multithreading.
You'd find a place that you need to start the new thread at, then do something like
SceUID new_thid = sceKernelCreateThread("Name", &function, 0x18, 0x512, 0);
if(new_thid) sceKernelStartThread(new_thid, 0, NULL);
or however you did it in your start stuff(Don't have the toolchain installed on this machine, and my memory is kinda iffy atm, flu sucks)
then once you're done, you could do something like
SceUID thid_to_end = sceKernelGetThreadId();
sceKernelTerminateDeleteThread(thid_to_end);
or however. There are more than one way to do it, just depends how you want it set up, I suppose.
Just keep in mind you'll probably need a new loop to send it through, and you'd have to use delays. _________________ Programming with:
Geany + Latest PSPSDK from svn |
|
| Back to top |
|
 |
Tydude4Christ
Joined: 24 Aug 2006 Posts: 8 Location: St. Louis, MO, U.S.A.
|
Posted: Mon Feb 16, 2009 8:08 am Post subject: |
|
|
Thanks, I tried it and got it to compile with no errors but I'm not getting any sound. Here's my code.
| Code: | #include <pspkernel.h>
#include <pspdebug.h>
#include <pspctrl.h>
#include <pspdisplay.h>
#include <stdio.h>
#include <pspaudio.h>
#include <pspmp3.h>
#include <psputility.h>
#define MP3FILE "./Resources/Music/music.mp3"
int fd;
int handle;
int samplingRate;
int numChannels;
// Input and Output buffers
char mp3Buf[16*1024] __attribute__((aligned(64)));
short pcmBuf[16*(1152/2)] __attribute__((aligned(64)));
int fillStreamBuffer(int fd, int handle)
{
char* dst;
int write;
int pos;
// Get Info on the stream (where to fill to, how much to fill, where to fill from)
sceMp3GetInfoToAddStreamData( handle, &dst, &write, &pos);
// Seek file to position requested
sceIoLseek32(fd, pos, SEEK_SET);
// Read the amount of data
int read = sceIoRead(fd, dst, write);
if (!read)
return 0;
// Notify mp3 library about how much we really wrote to the stream buffer
sceMp3NotifyAddStreamData(handle, read);
return (pos>0);
}
int audio()
{
static int channel = -1;
static int lastDecoded = 0;
static int volume = PSP_AUDIO_VOLUME_MAX;
if (sceMp3CheckStreamDataNeeded(handle) > 0)
fillStreamBuffer(fd, handle);
// Decode some samples
short* buf;
int bytesDecoded;
bytesDecoded = sceMp3Decode(handle, &buf);
if (bytesDecoded<=0)
sceMp3CheckStreamDataNeeded(handle);
// Nothing more to decode? Must have reached end of input buffer
if (bytesDecoded==0 || bytesDecoded==0x80671402)
sceMp3ResetPlayPosition(handle);
else
{
// Reserve the Audio channel for our output if not yet done
if (channel<0 || lastDecoded != bytesDecoded)
{
if (channel>=0)
sceAudioSRCChRelease();
channel = sceAudioSRCChReserve(bytesDecoded / (2 * numChannels), samplingRate, numChannels);
}
// Output the decoded samples and accumulate the number of played samples to get the playtime
sceAudioSRCOutputBlocking(volume, buf);
}
return 0;
}
int setupAudio()
{
// Load modules
sceUtilityLoadModule(PSP_MODULE_AV_AVCODEC);
sceUtilityLoadModule(PSP_MODULE_AV_MP3);
// Init mp3 resources
sceMp3InitResource();
// Open the input file
fd = sceIoOpen(MP3FILE, PSP_O_RDONLY, 0777);
// Reserve a mp3 handle for our playback
SceMp3InitArg mp3Init;
mp3Init.mp3StreamStart = 0;
mp3Init.mp3StreamEnd = sceIoLseek32(fd, 0, SEEK_END);
mp3Init.unk1 = 0;
mp3Init.unk2 = 0;
mp3Init.mp3Buf = mp3Buf;
mp3Init.mp3BufSize = sizeof(mp3Buf);
mp3Init.pcmBuf = pcmBuf;
mp3Init.pcmBufSize = sizeof(pcmBuf);
handle = sceMp3ReserveMp3Handle(&mp3Init);
// Fill the stream buffer with some data so that sceMp3Init has something to work with
fillStreamBuffer(fd, handle);
sceMp3Init(handle);
samplingRate = sceMp3GetSamplingRate(handle);
numChannels = sceMp3GetMp3ChannelNum(handle);
int thid = 0;
thid = sceKernelCreateThread("audio_thread", audio, 0x06, 0x10000, 0, 0);
if(thid >= 0)
{
sceKernelStartThread(thid, 0, 0);
}
return 0;
} |
I call setupAudio() before entering my main loop. Any suggestions. |
|
| Back to top |
|
 |
NoEffex
Joined: 27 Nov 2008 Posts: 108
|
Posted: Mon Feb 16, 2009 8:26 am Post subject: |
|
|
Does your audio thing have to be in a loop?
For example:
http://pastebin.com/m6faebce _________________ Programming with:
Geany + Latest PSPSDK from svn |
|
| Back to top |
|
 |
Tydude4Christ
Joined: 24 Aug 2006 Posts: 8 Location: St. Louis, MO, U.S.A.
|
Posted: Mon Feb 16, 2009 10:34 am Post subject: |
|
|
| Indeed, you were correct. I did need it to be in a loop. But my audio thread is still never being executed. Do I need to tell it in my main while function to go to my audio thread, or do I need to make the main while function a thread also. I'm sorry but I'm new to threads and coding for the PSP. Thanks. |
|
| Back to top |
|
 |
Tydude4Christ
Joined: 24 Aug 2006 Posts: 8 Location: St. Louis, MO, U.S.A.
|
Posted: Mon Feb 16, 2009 2:15 pm Post subject: |
|
|
| Ok, I figured it out. I just needed a sceKernelDelayThread(); in my main while loop. Thanks for the help guys. |
|
| Back to top |
|
 |
jean

Joined: 05 Jan 2008 Posts: 489
|
Posted: Mon Feb 16, 2009 10:15 pm Post subject: |
|
|
| I admit i haven't read all the thread, but your last post remembers me we are in a cooperative multithreading environment on PSP...in a first approximation this means no thread can be interrupted but every thread must yield issuing a sleep. |
|
| Back to top |
|
 |
Viper8896
Joined: 26 Jan 2006 Posts: 110
|
Posted: Tue Feb 17, 2009 7:06 pm Post subject: |
|
|
| jean wrote: | | in a first approximation this means no thread can be interrupted but every thread must yield issuing a sleep. |
Some functions cause an implicit context switch like sceAudioOutputBlocking for example. Can someone in the know confirm this though? |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Fri Feb 20, 2009 4:18 am Post subject: |
|
|
Yes, those functions yield the CPU for other threads.
However I've found that unlike what people say, the sceCtrl* stuff DOES NOT yield CPU even if you set a slow sample rate. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|