how can I play two big sound files at the same time ?

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

Moderators: cheriff, TyRaNiD

Post Reply
saulotmalo2
Posts: 43
Joined: Mon Sep 10, 2007 9:32 am

how can I play two big sound files at the same time ?

Post by saulotmalo2 »

Hello, I usually use SDL_mixer when I have to work with sound. But now I'm having a problem. as SDL_mixer uses only one channel for the music i can't play two big music files (such as ogg of about 2 Mb) at the same time because I can't put them on chunks and if I play one on the music then the other one sounds bad.

there is a way on SDL or any other PSP library for get working both musics?

thanks
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

You could always decode one of them yourself, and submit it to SDL as "normal" audio samples.

There are a number of audio compression libs in the sdk - ogg/vorbis, tremor (integer based vorbis), and mad.
saulotmalo2
Posts: 43
Joined: Mon Sep 10, 2007 9:32 am

Post by saulotmalo2 »

I have never worked with sound using sdl only I've ever used SDL_mixer. Do you know where can i find information for do this?

thanks
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

You can start by clicking the "search" button.
saulotmalo2
Posts: 43
Joined: Mon Sep 10, 2007 9:32 am

Post by saulotmalo2 »

before posting I always try to find by myself...
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Well, here's a thread on decoding ogg with tremor (comes right up in search, plus it's on the first page of post).

http://forums.ps2dev.org/viewtopic.php?t=8940

If you already know how to mix sound in sdl/sdl-mixer/whatever, just use the info in that thread (at the bottom) to see how tremor decodes the data.
saulotmalo2
Posts: 43
Joined: Mon Sep 10, 2007 9:32 am

Post by saulotmalo2 »

yes, i saw this code this afternoon but and i dit this code:

Code: Select all

#include <pspkernel.h>

#include <pspdebug.h>

#include <pspctrl.h>

#include <pspdisplay.h>

#include <psppower.h>

#include <psprtc.h>

#include <png.h>

#include <SDL.h>

#include <stdlib.h>

#include <stdio.h>

#include <time.h>

#include <string>

#include <list>

#include <iostream>

#include <fstream>

#include <SDL_mixer.h>
#include <pspaudio.h> 


#include "tremor/ivorbiscodec.h" 
#include "tremor/ivorbisfile.h" 


using namespace std;
using namespace ftr;


PSP_MODULE_INFO&#40;"Test", 0, 1, 1&#41;;

PSP_MAIN_THREAD_ATTR&#40;THREAD_ATTR_USER | THREAD_ATTR_VFPU&#41;;

#define OUTPUT_BUFFER 4*1024

/////////////////////////////////////////////////////////////////////////////////////////
//Globals
/////////////////////////////////////////////////////////////////////////////////////////
int runningFlag = 1;
OggVorbis_File OGG_VorbisFile;
int OGG_eos = 0;
int OGG_audio_channel = 0;
char pcmout&#91;OUTPUT_BUFFER&#93;;        //for ov_read
char pcmoutBlock&#91;OUTPUT_BUFFER&#93;;   //for real output
int bitStream;
static FILE *OGG_file = 0;

int bufferEmpty;
int bufferFull;
long bytesRed = 0; 

///////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
//Globals
/////////////////////////////////////////////////////////////////////////////////////////
int runningFlag2 = 1;
OggVorbis_File OGG_VorbisFile2;
int OGG_eos2 = 0;
int OGG_audio_channel2 = 0;
char pcmout2&#91;OUTPUT_BUFFER&#93;;        //for ov_read
char pcmoutBlock2&#91;OUTPUT_BUFFER&#93;;   //for real output
int bitStream2;
static FILE *OGG_file2 = 0;

int bufferEmpty2;
int bufferFull2;
long bytesRed2 = 0; 

///////////////////////////////////////////////////////////////////////////////////////////

int iteraciones=0;

static bool isrunning = true;

static int curWindow = 1;
int canal;

    Mix_Music *sonido2;

int exit_callback&#40;int arg1, int arg2, void *common&#41; &#123;

   isrunning = false;

   sceKernelExitGame&#40;&#41;;

   return 0;

&#125;



// Callback thread

int CallbackThread&#40;SceSize args, void *argp&#41; &#123;

   int cbid;

   

   cbid = sceKernelCreateCallback&#40;"Exit Callback", exit_callback, NULL&#41;;

   sceKernelRegisterExitCallback&#40;cbid&#41;;

   

   sceKernelSleepThreadCB&#40;&#41;;

    

   return 0;

&#125;



// Sets up the callback thread and returns its thread id

int SetupCallbacks&#40;void&#41; &#123;

   int thid = 0;

    

   thid = sceKernelCreateThread&#40;"update_thread", CallbackThread, 0x11, 0xFA0, 0, 0&#41;;

   if&#40;thid >= 0&#41;

   &#123;

      sceKernelStartThread&#40;thid, 0, 0&#41;;

   &#125;

    

   return thid;

&#125;


SDL_Surface * s;

//Animaciones animaciones;





/////////////////////////////////////////////////////////////////////////////////////////
//Buffer filling
/////////////////////////////////////////////////////////////////////////////////////////
int fillBuffer&#40;SceSize args, void *argp&#41;&#123;

    bufferEmpty = sceKernelCreateSema&#40;"bufferEmpty", 0, 1, 1, 0&#41;;
    while&#40;runningFlag&#41;&#123;
        sceKernelWaitSema&#40;bufferEmpty, 1, 0&#41;;
      bytesRed = ov_read&#40;&OGG_VorbisFile,pcmout,sizeof&#40;pcmout&#41;,&bitStream&#41;;
      switch &#40;bytesRed&#41;&#123;
      case 0&#58;
         //EOF&#58;
         OGG_eos = 1;
         ov_clear&#40;&OGG_VorbisFile&#41;;
         sceKernelSignalSema&#40;bufferFull, 1&#41;;
         break;      
      case OV_HOLE&#58;
      case OV_EBADLINK&#58;
         sceKernelSignalSema&#40;bufferEmpty, 1&#41;;
         break;
      default&#58;
         sceKernelSignalSema&#40;bufferFull, 1&#41;;
         break;
      &#125;
    &#125;
    return 0;
&#125;

/////////////////////////////////////////////////////////////////////////////////////////
//Buffer filling 2
/////////////////////////////////////////////////////////////////////////////////////////
int fillBuffer2&#40;SceSize args, void *argp&#41;&#123;

    bufferEmpty2 = sceKernelCreateSema&#40;"bufferEmpty", 0, 1, 1, 0&#41;;
    while&#40;runningFlag2&#41;&#123;
        sceKernelWaitSema&#40;bufferEmpty2, 1, 0&#41;;
      bytesRed2 = ov_read&#40;&OGG_VorbisFile2,pcmout2,sizeof&#40;pcmout2&#41;,&bitStream2&#41;;
      switch &#40;bytesRed2&#41;&#123;
      case 0&#58;
         //EOF&#58;
         OGG_eos2 = 1;
         ov_clear&#40;&OGG_VorbisFile2&#41;;
         sceKernelSignalSema&#40;bufferFull2, 1&#41;;
         break;      
      case OV_HOLE&#58;
      case OV_EBADLINK&#58;
         sceKernelSignalSema&#40;bufferEmpty2, 1&#41;;
         break;
      default&#58;
         sceKernelSignalSema&#40;bufferFull2, 1&#41;;
         break;
      &#125;
    &#125;
    return 0;
&#125;


/////////////////////////////////////////////////////////////////////////////////////////
//Audio output
/////////////////////////////////////////////////////////////////////////////////////////
int audioOutput&#40;SceSize args, void *argp&#41;&#123;
   bufferFull = sceKernelCreateSema&#40;"bufferFull", 0, 0, 1, 0&#41;;
   while&#40;runningFlag&#41;&#123;
        sceKernelWaitSema&#40;bufferFull, 1, 0&#41;;
        if &#40;OGG_eos&#41;
            break;
      memcpy&#40;pcmoutBlock,pcmout,OUTPUT_BUFFER&#41;;
      sceKernelSignalSema&#40;bufferEmpty, 1&#41;;
      sceAudioSetChannelDataLen&#40;OGG_audio_channel, bytesRed/4&#41;;
        sceAudioOutputBlocking&#40;OGG_audio_channel, PSP_AUDIO_VOLUME_MAX, pcmoutBlock&#41;;
    &#125;
    return 0;
&#125;
//////////////////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////////////////
//Audio output
/////////////////////////////////////////////////////////////////////////////////////////
int audioOutput2&#40;SceSize args, void *argp&#41;&#123;
   bufferFull2 = sceKernelCreateSema&#40;"bufferFull", 0, 0, 1, 0&#41;;
   while&#40;runningFlag2&#41;&#123;
        sceKernelWaitSema&#40;bufferFull2, 1, 0&#41;;
        if &#40;OGG_eos2&#41;
            break;
      memcpy&#40;pcmoutBlock2,pcmout2,OUTPUT_BUFFER&#41;;
      sceKernelSignalSema&#40;bufferEmpty2, 1&#41;;
      sceAudioSetChannelDataLen&#40;OGG_audio_channel2, bytesRed2/4&#41;;
        sceAudioOutputBlocking&#40;OGG_audio_channel2, PSP_AUDIO_VOLUME_MAX, pcmoutBlock2&#41;;
    &#125;
    return 0;
&#125;
//////////////////////////////////////////////////////////////////////////////////////////


void pruebaAlgo&#40;SDL_Event * evento&#41;
&#123;

	iteraciones++;
	cout<<iteraciones<<endl;
    if&#40;iteraciones==50000&#41;&#123;
    int bufferThid2 = sceKernelCreateThread&#40;"bufferFilling", fillBuffer2, 0x12, 0x10000, PSP_THREAD_ATTR_USER, NULL&#41;;
    if&#40;bufferThid2 < 0&#41;&#123;
                   
    &#125;
   sceKernelStartThread&#40;bufferThid2, 0, NULL&#41;;

    //Start audio output thread&#58;
    int audioThid2 = sceKernelCreateThread&#40;"audioOutput", audioOutput2, 0x16, 0x1800, PSP_THREAD_ATTR_USER, NULL&#41;;
    if&#40;audioThid2 < 0&#41; &#123;&#125;
   sceKernelStartThread&#40;audioThid2, 0, NULL&#41;;
                          
    &#125;     
	switch &#40;evento->type&#41;
	&#123;
	case SDL_QUIT&#58;
		exit&#40;0&#41;;
		break;
	
	case SDL_KEYDOWN&#58;
		if &#40;evento->key.keysym.sym == SDLK_q&#41;
		&#123;

			exit&#40;0&#41;;
		&#125;
		//if &#40;evento->key.keysym.sym == SDLK_d&#41;
		//	Aplicacion&#58;&#58;instance&#40;&#41;.setBanderasDepuracion&#40;Aplicacion&#58;&#58;BD_INTERACTIVO&#41;;
		//if &#40;evento->key.keysym.sym == SDLK_s&#41;
		//	Aplicacion&#58;&#58;instance&#40;&#41;.setBanderasDepuracion&#40;Aplicacion&#58;&#58;BD_NADA&#41;;
			

	&#125;	
&#125;



int main&#40;&#41; &#123;

   //Initialize the controler and the PSP Speed
    SDL_Joystick *joystick;
    SceCtrlData pad;
    

    

    scePowerSetClockFrequency&#40;333, 333, 333&#41;;

    sceCtrlSetSamplingCycle&#40;0&#41;;

    sceCtrlSetSamplingMode&#40;PSP_CTRL_MODE_ANALOG&#41;;

   
   
   	//Aplicacion & app = Aplicacion&#58;&#58;instance&#40;&#41;;	

    //app.inicializar&#40;&#41;;

   //Initialize the SDL Library &#40;audio and video&#41;

    if&#40;SDL_Init&#40;SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK &#41; < 0&#41;

      cout << stderr << "Couldn't initialize SDL&#58; " << SDL_GetError&#40;&#41; << endl;




    SDL_Surface *ecran = SDL_SetVideoMode&#40;480, 272, 16, SDL_SWSURFACE &#41;;


  

   // atexit&#40;Mix_CloseAudio&#41;;
    
   

     
	SDL_JoystickEventState&#40;SDL_ENABLE&#41;;
	joystick = SDL_JoystickOpen&#40;0&#41;;







	
    
    pspDebugScreenInit&#40;&#41;;

    SetupCallbacks&#40;&#41;;

   
     //Apro il file OGG&#58;
   OGG_file = fopen&#40;"jump.ogg", "r"&#41;;
   if &#40;&#40;OGG_file&#41; != NULL&#41; &#123;
      ov_open&#40;OGG_file, &OGG_VorbisFile, NULL, 0&#41;;
   &#125;else&#123;

      return -1;
   &#125;  


   OGG_file2 = fopen&#40;"jump.ogg", "r"&#41;;
   if &#40;&#40;OGG_file2&#41; != NULL&#41; &#123;
      ov_open&#40;OGG_file2, &OGG_VorbisFile2, NULL, 0&#41;;
   &#125;else&#123;
      return -1;
   &#125; 



    //Reserve audio channel&#58;
    OGG_audio_channel = sceAudioChReserve&#40;OGG_audio_channel, OUTPUT_BUFFER/4, PSP_AUDIO_FORMAT_STEREO&#41;;

   OGG_audio_channel2 = sceAudioChReserve&#40;OGG_audio_channel2, OUTPUT_BUFFER/4, PSP_AUDIO_FORMAT_STEREO&#41;;

    //Start buffer filling thread&#58;
    int bufferThid = sceKernelCreateThread&#40;"bufferFilling", fillBuffer, 0x12, 0x10000, PSP_THREAD_ATTR_USER, NULL&#41;;
    if&#40;bufferThid < 0&#41;
        return -1;
   sceKernelStartThread&#40;bufferThid, 0, NULL&#41;;

    //Start audio output thread&#58;
    int audioThid = sceKernelCreateThread&#40;"audioOutput", audioOutput, 0x16, 0x1800, PSP_THREAD_ATTR_USER, NULL&#41;;
    if&#40;audioThid < 0&#41;
        return -1;
   sceKernelStartThread&#40;audioThid, 0, NULL&#41;;



    while&#40;isrunning&#41;

    &#123;      

      sceCtrlReadBufferPositive&#40;&pad, 1&#41;;
      SDL_Event evento;
	
	/* Loop waiting for ESC+Mouse_Button */
    while &#40; SDL_PollEvent&#40;&evento&#41; >= 0 &#41; &#123;

          pruebaAlgo&#40;&evento&#41;;

   	&#125;


    &#125;
   


  sceAudioChRelease&#40;OGG_audio_channel&#41;; 
    SDL_Quit&#40;&#41;;

   

    sceKernelSleepThread&#40;&#41;;



    return 0;

&#125;
I have tried to duplicate every thing in the fuction, usually I'm not working this way but I'm in a hurry by trying this proyect it is important for me to have it by the weekend. Well as I was telling, I've tried to make the same that do the threads of filling the buffer but changing the name of everyting. And when the iteration gets 50000 start the new threads... but when I do this sound begins to get bad :(.
gambiting
Posts: 154
Joined: Thu Aug 17, 2006 5:39 pm

Post by gambiting »

Use OSLib,it allows you to play many files at once,without size limit(you can load them to ram or stream from ms).
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

The code above is using old non-working-right code. Use the latest code from the last post I made in the thread indicated. That has all the bugs worked out with proper sounding audio.
saulotmalo2
Posts: 43
Joined: Mon Sep 10, 2007 9:32 am

Post by saulotmalo2 »

thanks both. I'll try tomorow when I get up and my head dodn't tell me to kill me( how it is called in english? resaca yeah you know when you drunk a lot in spanish is called).

truly thanks... tomorrow i'll try both
Post Reply