forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Streaming large PCM from the HDD

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PS2 Development
View previous topic :: View next topic  
Author Message
PrimeTime



Joined: 19 Aug 2004
Posts: 25

PostPosted: Sun Aug 22, 2004 5:46 pm    Post subject: Streaming large PCM from the HDD Reply with quote

Hi again,
I'm trying to stream a large PCM audio file from my hard drive.
I'm using the SjPCM library to help. My problem is, the sound output
is very choppy. I am not sure if it is coming from reading the data
from the hard drive, or transferring the data to the right and left
audio channels. Here is the code of my stream algor.

Code:

samples1 = malloc(800);
scr_printf("Loading..  ");

//Just some pre-loading
fileXioRead(fd, (short*)samples1, 800);
for (readIn = 0; readIn < 800; readIn++)
{
   left[readIn] = samples1[readIn];
   if (channels == 2) right[readIn] = samples1[2*readIn+1]; else right[readIn] = samples1[readIn];
}

while (1)
{
   buffered = SjPCM_Buffered();
   if (buffered<1*800)
   {
      SjPCM_Enqueue(left, right, 800, 0); // avoid underrun
      fileXioRead(fd, (short*)samples1, 800);
      for (i=0; i<800; i++)
      {
        left[i] = samples2[i];
        if (channels == 2) right[i] = samples2[2*i+1]; else right[i] = samples2[i];
      }
      wait_vsync();
   }
}

my audio file is the correct format for SjPCM. I've tried different buffer sizes too, ranging from 800 to 768000.
The larger buffersizes pause during rebuffering.

Any ideas?
Thanks,
Ryan
Back to top
View user's profile Send private message
Guest






PostPosted: Sun Aug 22, 2004 7:01 pm    Post subject: Reply with quote

One problem I have looking at your code is that you did not include
any of your variable declarations, such as for:
samples1, samples2, left[], right[], etc...

Its hard to debug other peoples code if you can't make sure their problem
isn't in their variable declarations.

Not that it necessarily is so, I heard a similar problem discussed in
#ps2dev[efnet] recently. Maybe someone else can drop by to offer
some hints, or you could try dropping into the channel and asking.

Gorim
Back to top
PrimeTime



Joined: 19 Aug 2004
Posts: 25

PostPosted: Sun Aug 22, 2004 7:12 pm    Post subject: Reply with quote

sorry about that, made a few typos

Code:

samples1 = malloc(800);
scr_printf("Loading..  ");

//Just some pre-loading
fileXioRead(fd, (short*)samples1, 800);
for (readIn = 0; readIn < 800; readIn++)
{
   left[readIn] = samples1[readIn];
   if (channels == 2) right[readIn] = samples1[2*readIn+1]; else right[readIn] = samples1[readIn];
}

while (1)
{
   buffered = SjPCM_Buffered();
   if (buffered<1*800)
   {
      SjPCM_Enqueue(left, right, 800, 0); // avoid underrun
      fileXioRead(fd, (short*)samples1, 800);
      for (i=0; i<800; i++)
      {
        left[i] = samples1[i];
        if (channels == 2) right[i] = samples1[2*i+1]; else right[i] = samples1[i];
      }
      wait_vsync();
   }
}


samples1 is short*
left and right are static short __attribute__((aligned (64)))[1024]
Back to top
View user's profile Send private message
Saotome



Joined: 03 Apr 2004
Posts: 182

PostPosted: Sun Aug 22, 2004 7:22 pm    Post subject: Reply with quote

i'm not sure if thats the cause for your choppy output, but shouldn't it be:
Code:

for (i=0; i<800; i++)
{
   if (channels == 2) left[i] = samples1[2*i]; //<= !!!
   else left[i] = samples1[i];
   if (channels == 2) right[i] = samples1[2*i+1]; else right[i] = samples1[i];
}

?
_________________
infj
Back to top
View user's profile Send private message
PrimeTime



Joined: 19 Aug 2004
Posts: 25

PostPosted: Sun Aug 22, 2004 7:47 pm    Post subject: Reply with quote

thats incorrect code for 2 channels :D
I'm trying a mono channel right now, so i can just use the left data for both, I have re-written the algorithm, it works a little better, but once the initial buffer is empty it gets choppy.

I can't find anything wrong, but its also late at night.

Code:

short *samples1 = malloc(192000);
fileXioRead(fd, (short*)samples1, 192000);
readIn = 0;
i = 0;

while (1)
{
   left[iSamples] = samples1[readIn];
   if ( (++iSamples == 800)) //800 samples are now in left[]
   {
      wait_vsync();
      SjPCM_Enqueue(left, left, 800, 0); // queue up the 800 samples
      //read 800 more samples in the buffer location i just transferred to left[]
      fileXioRead(fd, (short*)&samples1[i*800], 800);
      i++;  //increment the buffer block
      iSamples = 0;  //reset the queued samples
   }
   if (++readIn == 192000)  // we are at the end of the buffer
   {
      printf("------Getting new data--------\n");
      readIn = 0;
      i = 0;  //since we reread the buffer while we were playing, we should be able to reset the variables and transfer the new buffer
   }
}

Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Mon Aug 23, 2004 11:39 am    Post subject: Reply with quote

Reading 800 samples at a time off the HD won't work. There's no cacheing in the HD code, so it needs to get the data off the drive in non-optimal sizes (not multiples of the blocksize). The HD is incapable of randomly getting 800 samples within one video frame. Some will, and others won't leading to chop. You need to buffer at least a couple seconds ahead.

Create a thread that keeps a two-second buffer full of data which is read (at least) 8K at a time. Have another thread that waits a video frame, then feeds data to the sound.
Back to top
View user's profile Send private message AIM Address
PrimeTime



Joined: 19 Aug 2004
Posts: 25

PostPosted: Mon Aug 23, 2004 3:53 pm    Post subject: Reply with quote

Ah, I figured it out.
I haven't used threads for the streaming yet, but I did get
the file to stream correctly.

My problem was that each sample is 2 bytes which is
stored in one element of a short array
I was treating the short array as it it were an
array of 1 byte elements such as a char array.
So, my output was choppy since i was transferring
only the first portion of the stream and not the second.

Ryan
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Tue Aug 24, 2004 9:48 am    Post subject: Reply with quote

Wow! I'm surprised. That you can pull the data off the HDD one frame at a time says quite a bit for how good the drive code is. I'd have thought for certain you'd need a threaded buffer to keep it smooth. Good to hear otherwise, but I think it'd be much better with a threaded buffer.
Back to top
View user's profile Send private message AIM Address
mrbrown



Joined: 17 Jan 2004
Posts: 1536

PostPosted: Wed Aug 25, 2004 4:12 am    Post subject: Reply with quote

J.F. wrote:
Wow! I'm surprised. That you can pull the data off the HDD one frame at a time says quite a bit for how good the drive code is. I'd have thought for certain you'd need a threaded buffer to keep it smooth. Good to hear otherwise, but I think it'd be much better with a threaded buffer.


Er, it's a hard drive, with <5ms seek time and 20-25MB/s peek transfer speed (at least under PS2/Linux, it's probably more natively).

Why wouldn't it be fast enough?
_________________
"He was warned..."
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Wed Aug 25, 2004 9:21 am    Post subject: Reply with quote

I'd read somewhere else on the forum that the current HD code was SLOW (getting less than 1M/s transfer rates). I guess what we need is a nice test that shows how fast certain types and size of transfers are, and what their latency is.
Back to top
View user's profile Send private message AIM Address
PrimeTime



Joined: 19 Aug 2004
Posts: 25

PostPosted: Wed Aug 25, 2004 11:02 am    Post subject: Reply with quote

Well, either way, I got both the threaded and non-threaded versions
to work :)

Ryan
Back to top
View user's profile Send private message
mrbrown



Joined: 17 Jan 2004
Posts: 1536

PostPosted: Wed Aug 25, 2004 11:15 am    Post subject: Reply with quote

J.F. wrote:
I'd read somewhere else on the forum that the current HD code was SLOW (getting less than 1M/s transfer rates). I guess what we need is a nice test that shows how fast certain types and size of transfers are, and what their latency is.


Well, HDD does compete with SMAP for the same interrupt and DMA channel. If we're still using the older, GPL'd SMAP driver (are we?) then we aren't contending for DMA because that driver doesn't use any. I remember reading the post from the guy that optimized SMAP and ps2ip and he had real abysmal rates transferring to the HDD over the network, IIRC.

I guess it would be worthwhile if someone sat down and benchmarked it.
_________________
"He was warned..."
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PS2 Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
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