added struct OutputBufferChunk
To make access to OutputBuffer easier, move everything which belongs to a chunk into its own structure, namely OutputBufferChunk. git-svn-id: https://svn.musicpd.org/mpd/trunk@7269 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:

committed by
Eric Wong

parent
68a625b5b8
commit
74910df0f3
35
src/decode.c
35
src/decode.c
@@ -491,6 +491,8 @@ static void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer *
|
|||||||
if (pause)
|
if (pause)
|
||||||
player_sleep();
|
player_sleep();
|
||||||
else if (!outputBufferEmpty(cb) && cb->begin != next) {
|
else if (!outputBufferEmpty(cb) && cb->begin != next) {
|
||||||
|
OutputBufferChunk *beginChunk =
|
||||||
|
outputBufferGetChunk(cb, cb->begin);
|
||||||
unsigned int fadePosition;
|
unsigned int fadePosition;
|
||||||
if (doCrossFade == 1 && next >= 0 &&
|
if (doCrossFade == 1 && next >= 0 &&
|
||||||
(fadePosition = outputBufferRelative(cb, next))
|
(fadePosition = outputBufferRelative(cb, next))
|
||||||
@@ -506,18 +508,20 @@ static void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer *
|
|||||||
}
|
}
|
||||||
nextChunk = outputBufferAbsolute(cb, crossFadeChunks);
|
nextChunk = outputBufferAbsolute(cb, crossFadeChunks);
|
||||||
if (nextChunk >= 0) {
|
if (nextChunk >= 0) {
|
||||||
pcm_mix(outputBufferChunkData(cb, cb->begin),
|
OutputBufferChunk *fadeChunk =
|
||||||
outputBufferChunkData(cb, nextChunk),
|
outputBufferGetChunk(cb, nextChunk);
|
||||||
cb->chunkSize[cb->begin],
|
pcm_mix(beginChunk->data,
|
||||||
cb->chunkSize[nextChunk],
|
fadeChunk->data,
|
||||||
|
beginChunk->chunkSize,
|
||||||
|
fadeChunk->chunkSize,
|
||||||
&(cb->audioFormat),
|
&(cb->audioFormat),
|
||||||
((float)fadePosition) /
|
((float)fadePosition) /
|
||||||
crossFadeChunks);
|
crossFadeChunks);
|
||||||
if (cb->chunkSize[nextChunk] >
|
if (fadeChunk->chunkSize >
|
||||||
cb->chunkSize[cb->begin]
|
beginChunk->chunkSize
|
||||||
) {
|
) {
|
||||||
cb->chunkSize[cb->begin]
|
beginChunk->chunkSize
|
||||||
= cb->chunkSize[nextChunk];
|
= fadeChunk->chunkSize;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* there are not enough
|
/* there are not enough
|
||||||
@@ -535,18 +539,17 @@ static void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer *
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* play the current chunk */
|
/* play the current chunk */
|
||||||
pc->elapsedTime = cb->times[cb->begin];
|
pc->elapsedTime = beginChunk->times;
|
||||||
pc->bitRate = cb->bitRate[cb->begin];
|
pc->bitRate = beginChunk->bitRate;
|
||||||
pcm_volumeChange(cb->chunks + cb->begin *
|
pcm_volumeChange(beginChunk->data,
|
||||||
CHUNK_SIZE,
|
beginChunk->chunkSize,
|
||||||
cb->chunkSize[cb->begin],
|
|
||||||
&(cb->audioFormat),
|
&(cb->audioFormat),
|
||||||
pc->softwareVolume);
|
pc->softwareVolume);
|
||||||
if (playAudio(cb->chunks + cb->begin * CHUNK_SIZE,
|
if (playAudio(beginChunk->data,
|
||||||
cb->chunkSize[cb->begin]) < 0)
|
beginChunk->chunkSize) < 0)
|
||||||
break;
|
break;
|
||||||
pc->totalPlayTime +=
|
pc->totalPlayTime +=
|
||||||
sizeToTime * cb->chunkSize[cb->begin];
|
sizeToTime * beginChunk->chunkSize;
|
||||||
if ((unsigned)cb->begin + 1 >= buffered_chunks) {
|
if ((unsigned)cb->begin + 1 >= buffered_chunks) {
|
||||||
cb->begin = 0;
|
cb->begin = 0;
|
||||||
} else
|
} else
|
||||||
|
@@ -28,16 +28,10 @@
|
|||||||
|
|
||||||
static mpd_sint16 currentChunk = -1;
|
static mpd_sint16 currentChunk = -1;
|
||||||
|
|
||||||
void initOutputBuffer(OutputBuffer * cb, char *chunks)
|
void initOutputBuffer(OutputBuffer * cb, OutputBufferChunk * chunks)
|
||||||
{
|
{
|
||||||
memset(&cb->convState, 0, sizeof(ConvState));
|
memset(&cb->convState, 0, sizeof(ConvState));
|
||||||
cb->chunks = chunks;
|
cb->chunks = chunks;
|
||||||
cb->chunkSize = (mpd_uint16 *) (((char *)cb->chunks) +
|
|
||||||
buffered_chunks * CHUNK_SIZE);
|
|
||||||
cb->bitRate = (mpd_uint16 *) (((char *)cb->chunkSize) +
|
|
||||||
buffered_chunks * sizeof(mpd_sint16));
|
|
||||||
cb->times = (float *)(((char *)cb->bitRate) +
|
|
||||||
buffered_chunks * sizeof(mpd_sint8));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearOutputBuffer(OutputBuffer * cb)
|
void clearOutputBuffer(OutputBuffer * cb)
|
||||||
@@ -92,11 +86,11 @@ int outputBufferAbsolute(const OutputBuffer * cb, unsigned relative)
|
|||||||
return (int)i;
|
return (int)i;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * outputBufferChunkData(const OutputBuffer * cb, unsigned i)
|
OutputBufferChunk * outputBufferGetChunk(const OutputBuffer * cb, unsigned i)
|
||||||
{
|
{
|
||||||
assert(i < buffered_chunks);
|
assert(i < buffered_chunks);
|
||||||
|
|
||||||
return cb->chunks + i * CHUNK_SIZE;
|
return &cb->chunks[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,6 +107,7 @@ static int tailChunk(OutputBuffer * cb, InputStream * inStream,
|
|||||||
float data_time, mpd_uint16 bitRate)
|
float data_time, mpd_uint16 bitRate)
|
||||||
{
|
{
|
||||||
unsigned int next;
|
unsigned int next;
|
||||||
|
OutputBufferChunk *chunk;
|
||||||
|
|
||||||
if (currentChunk == cb->end)
|
if (currentChunk == cb->end)
|
||||||
return currentChunk;
|
return currentChunk;
|
||||||
@@ -140,9 +135,10 @@ static int tailChunk(OutputBuffer * cb, InputStream * inStream,
|
|||||||
return OUTPUT_BUFFER_DC_STOP;
|
return OUTPUT_BUFFER_DC_STOP;
|
||||||
|
|
||||||
currentChunk = cb->end;
|
currentChunk = cb->end;
|
||||||
cb->chunkSize[currentChunk] = 0;
|
chunk = outputBufferGetChunk(cb, currentChunk);
|
||||||
cb->bitRate[currentChunk] = bitRate;
|
chunk->chunkSize = 0;
|
||||||
cb->times[currentChunk] = data_time;
|
chunk->bitRate = bitRate;
|
||||||
|
chunk->times = data_time;
|
||||||
|
|
||||||
return currentChunk;
|
return currentChunk;
|
||||||
}
|
}
|
||||||
@@ -183,22 +179,24 @@ int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
|
|||||||
normalizeData(data, datalen, &cb->audioFormat);
|
normalizeData(data, datalen, &cb->audioFormat);
|
||||||
|
|
||||||
while (datalen) {
|
while (datalen) {
|
||||||
|
OutputBufferChunk *chunk;
|
||||||
int chunk_index = tailChunk(cb, inStream,
|
int chunk_index = tailChunk(cb, inStream,
|
||||||
dc, seekable,
|
dc, seekable,
|
||||||
data_time, bitRate);
|
data_time, bitRate);
|
||||||
if (chunk_index < 0)
|
if (chunk_index < 0)
|
||||||
return chunk_index;
|
return chunk_index;
|
||||||
|
|
||||||
chunkLeft = CHUNK_SIZE - cb->chunkSize[chunk_index];
|
chunk = outputBufferGetChunk(cb, chunk_index);
|
||||||
|
|
||||||
|
chunkLeft = CHUNK_SIZE - chunk->chunkSize;
|
||||||
dataToSend = datalen > chunkLeft ? chunkLeft : datalen;
|
dataToSend = datalen > chunkLeft ? chunkLeft : datalen;
|
||||||
|
|
||||||
memcpy(cb->chunks + chunk_index * CHUNK_SIZE +
|
memcpy(chunk->data + chunk->chunkSize, data, dataToSend);
|
||||||
cb->chunkSize[chunk_index], data, dataToSend);
|
chunk->chunkSize += dataToSend;
|
||||||
cb->chunkSize[chunk_index] += dataToSend;
|
|
||||||
datalen -= dataToSend;
|
datalen -= dataToSend;
|
||||||
data += dataToSend;
|
data += dataToSend;
|
||||||
|
|
||||||
if (cb->chunkSize[chunk_index] == CHUNK_SIZE) {
|
if (chunk->chunkSize == CHUNK_SIZE) {
|
||||||
flushOutputBuffer(cb);
|
flushOutputBuffer(cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,15 +32,19 @@
|
|||||||
/* pick 1020 since its devisible for 8,16,24, and 32-bit audio */
|
/* pick 1020 since its devisible for 8,16,24, and 32-bit audio */
|
||||||
#define CHUNK_SIZE 1020
|
#define CHUNK_SIZE 1020
|
||||||
|
|
||||||
|
typedef struct _OutputBufferChunk {
|
||||||
|
volatile mpd_uint16 chunkSize;
|
||||||
|
volatile mpd_uint16 bitRate;
|
||||||
|
volatile float times;
|
||||||
|
char data[CHUNK_SIZE];
|
||||||
|
} OutputBufferChunk;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A ring set of buffers where the decoder appends data after the end,
|
* A ring set of buffers where the decoder appends data after the end,
|
||||||
* and the player consumes data from the beginning.
|
* and the player consumes data from the beginning.
|
||||||
*/
|
*/
|
||||||
typedef struct _OutputBuffer {
|
typedef struct _OutputBuffer {
|
||||||
char *volatile chunks;
|
OutputBufferChunk *chunks;
|
||||||
mpd_uint16 *volatile chunkSize;
|
|
||||||
mpd_uint16 *volatile bitRate;
|
|
||||||
float *volatile times;
|
|
||||||
|
|
||||||
/** the index of the first decoded chunk */
|
/** the index of the first decoded chunk */
|
||||||
mpd_uint16 volatile begin;
|
mpd_uint16 volatile begin;
|
||||||
@@ -52,7 +56,7 @@ typedef struct _OutputBuffer {
|
|||||||
ConvState convState;
|
ConvState convState;
|
||||||
} OutputBuffer;
|
} OutputBuffer;
|
||||||
|
|
||||||
void initOutputBuffer(OutputBuffer * cb, char *chunks);
|
void initOutputBuffer(OutputBuffer * cb, OutputBufferChunk * chunks);
|
||||||
|
|
||||||
void clearOutputBuffer(OutputBuffer * cb);
|
void clearOutputBuffer(OutputBuffer * cb);
|
||||||
|
|
||||||
@@ -76,7 +80,7 @@ unsigned availableOutputBuffer(const OutputBuffer * cb);
|
|||||||
*/
|
*/
|
||||||
int outputBufferAbsolute(const OutputBuffer * cb, unsigned relative);
|
int outputBufferAbsolute(const OutputBuffer * cb, unsigned relative);
|
||||||
|
|
||||||
char * outputBufferChunkData(const OutputBuffer * cb, unsigned i);
|
OutputBufferChunk * outputBufferGetChunk(const OutputBuffer * cb, unsigned i);
|
||||||
|
|
||||||
/* we send inStream for buffering the inputStream while waiting to
|
/* we send inStream for buffering the inputStream while waiting to
|
||||||
send the next chunk */
|
send the next chunk */
|
||||||
|
@@ -74,7 +74,7 @@ void initPlayerData(void)
|
|||||||
buffered_before_play = buffered_chunks;
|
buffered_before_play = buffered_chunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
allocationSize = buffered_chunks * CHUNK_SIZE; /*actual buffer */
|
allocationSize = buffered_chunks * sizeof(OutputBufferChunk); /*actual buffer */
|
||||||
allocationSize += buffered_chunks * sizeof(float); /*for times */
|
allocationSize += buffered_chunks * sizeof(float); /*for times */
|
||||||
allocationSize += buffered_chunks * sizeof(mpd_sint16); /*for chunkSize */
|
allocationSize += buffered_chunks * sizeof(mpd_sint16); /*for chunkSize */
|
||||||
allocationSize += buffered_chunks * sizeof(mpd_sint16); /*for bitRate */
|
allocationSize += buffered_chunks * sizeof(mpd_sint16); /*for bitRate */
|
||||||
@@ -94,7 +94,7 @@ void initPlayerData(void)
|
|||||||
allocationSize - device_array_size;
|
allocationSize - device_array_size;
|
||||||
|
|
||||||
initOutputBuffer(&(playerData_pd->buffer),
|
initOutputBuffer(&(playerData_pd->buffer),
|
||||||
((char *)playerData_pd) + sizeof(PlayerData));
|
(OutputBufferChunk*)(((char *)playerData_pd) + sizeof(PlayerData)));
|
||||||
|
|
||||||
playerData_pd->playerControl.stop = 0;
|
playerData_pd->playerControl.stop = 0;
|
||||||
playerData_pd->playerControl.pause = 0;
|
playerData_pd->playerControl.pause = 0;
|
||||||
|
Reference in New Issue
Block a user