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.
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.
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.
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.
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
}
}
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.
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.
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.
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).
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.
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.