Questions of multi-threading

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Tydude4Christ
Posts: 8
Joined: Thu Aug 24, 2006 12:30 pm
Location: St. Louis, MO, U.S.A.

Questions of multi-threading

Post by Tydude4Christ »

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.
NoEffex
Posts: 106
Joined: Thu Nov 27, 2008 6:48 am

Post by NoEffex »

(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
Tydude4Christ
Posts: 8
Joined: Thu Aug 24, 2006 12:30 pm
Location: St. Louis, MO, U.S.A.

Post by Tydude4Christ »

Thanks, I tried it and got it to compile with no errors but I'm not getting any sound. Here's my code.

Code: Select all

#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&#91;16*1024&#93;  __attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41;;
short	pcmBuf&#91;16*&#40;1152/2&#41;&#93;  __attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41;;

int fillStreamBuffer&#40;int fd, int handle&#41;
&#123;
	char* dst;
	int write;
	int pos;

	// Get Info on the stream &#40;where to fill to, how much to fill, where to fill from&#41;
	sceMp3GetInfoToAddStreamData&#40; handle, &dst, &write, &pos&#41;;
	// Seek file to position requested
  sceIoLseek32&#40;fd, pos, SEEK_SET&#41;;
	// Read the amount of data
	int read = sceIoRead&#40;fd, dst, write&#41;;
	if &#40;!read&#41;
		return 0;
	// Notify mp3 library about how much we really wrote to the stream buffer
	sceMp3NotifyAddStreamData&#40;handle, read&#41;;
	return &#40;pos>0&#41;;
&#125;

int audio&#40;&#41;
&#123;
  static int channel = -1;
	static int lastDecoded = 0;
	static int volume = PSP_AUDIO_VOLUME_MAX;

  if &#40;sceMp3CheckStreamDataNeeded&#40;handle&#41; > 0&#41;
    fillStreamBuffer&#40;fd, handle&#41;;
	// Decode some samples
  short* buf;
  int bytesDecoded;
  bytesDecoded = sceMp3Decode&#40;handle, &buf&#41;;
  if &#40;bytesDecoded<=0&#41;
    sceMp3CheckStreamDataNeeded&#40;handle&#41;;
  // Nothing more to decode? Must have reached end of input buffer
  if &#40;bytesDecoded==0 || bytesDecoded==0x80671402&#41;
    sceMp3ResetPlayPosition&#40;handle&#41;;
  else
  &#123;
    // Reserve the Audio channel for our output if not yet done
    if &#40;channel<0 || lastDecoded != bytesDecoded&#41;
    &#123;
      if &#40;channel>=0&#41;
        sceAudioSRCChRelease&#40;&#41;;
      channel = sceAudioSRCChReserve&#40;bytesDecoded / &#40;2 * numChannels&#41;, samplingRate, numChannels&#41;;
    &#125;
    // Output the decoded samples and accumulate the number of played samples to get the playtime
    sceAudioSRCOutputBlocking&#40;volume, buf&#41;;
  &#125;
  return 0;
&#125;

int setupAudio&#40;&#41;
&#123;
  // Load modules
	sceUtilityLoadModule&#40;PSP_MODULE_AV_AVCODEC&#41;;
	sceUtilityLoadModule&#40;PSP_MODULE_AV_MP3&#41;;
	
	// Init mp3 resources
	sceMp3InitResource&#40;&#41;;

  // Open the input file
  fd = sceIoOpen&#40;MP3FILE, PSP_O_RDONLY, 0777&#41;;
	
	// Reserve a mp3 handle for our playback
	SceMp3InitArg mp3Init;
	mp3Init.mp3StreamStart = 0;
	mp3Init.mp3StreamEnd = sceIoLseek32&#40;fd, 0, SEEK_END&#41;;
	mp3Init.unk1 = 0;
	mp3Init.unk2 = 0;
	mp3Init.mp3Buf = mp3Buf;
	mp3Init.mp3BufSize = sizeof&#40;mp3Buf&#41;;
	mp3Init.pcmBuf = pcmBuf;
	mp3Init.pcmBufSize = sizeof&#40;pcmBuf&#41;;
	
	handle = sceMp3ReserveMp3Handle&#40;&mp3Init&#41;;
	
	// Fill the stream buffer with some data so that sceMp3Init has something to work with
	fillStreamBuffer&#40;fd, handle&#41;;
	
	sceMp3Init&#40;handle&#41;;

  samplingRate = sceMp3GetSamplingRate&#40;handle&#41;;
	numChannels = sceMp3GetMp3ChannelNum&#40;handle&#41;;

  int thid = 0;
  thid = sceKernelCreateThread&#40;"audio_thread", audio, 0x06, 0x10000, 0, 0&#41;;
  if&#40;thid >= 0&#41;
  &#123;
	  sceKernelStartThread&#40;thid, 0, 0&#41;;
  &#125;
  return 0;
&#125;
I call setupAudio() before entering my main loop. Any suggestions.
NoEffex
Posts: 106
Joined: Thu Nov 27, 2008 6:48 am

Post by NoEffex »

Does your audio thing have to be in a loop?

For example:

http://pastebin.com/m6faebce
Programming with:
Geany + Latest PSPSDK from svn
Tydude4Christ
Posts: 8
Joined: Thu Aug 24, 2006 12:30 pm
Location: St. Louis, MO, U.S.A.

Post by Tydude4Christ »

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.
Tydude4Christ
Posts: 8
Joined: Thu Aug 24, 2006 12:30 pm
Location: St. Louis, MO, U.S.A.

Post by Tydude4Christ »

Ok, I figured it out. I just needed a sceKernelDelayThread(); in my main while loop. Thanks for the help guys.
User avatar
jean
Posts: 489
Joined: Sat Jan 05, 2008 2:44 am

Post by jean »

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.
Viper8896
Posts: 110
Joined: Thu Jan 26, 2006 6:20 pm

Post by Viper8896 »

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?
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

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.
Post Reply