Beispiel #1
0
static const char *
ao_filter_chunk(struct audio_output *ao, const struct music_chunk *chunk,
                size_t *length_r)
{
    GError *error = NULL;

    size_t length;
    const char *data = ao_chunk_data(ao, chunk, ao->replay_gain_filter,
                                     &ao->replay_gain_serial, &length);
    if (data == NULL)
        return NULL;

    if (length == 0) {
        /* empty chunk, nothing to do */
        *length_r = 0;
        return data;
    }

    /* cross-fade */

    if (chunk->other != NULL) {
        size_t other_length;
        const char *other_data =
            ao_chunk_data(ao, chunk->other,
                          ao->other_replay_gain_filter,
                          &ao->other_replay_gain_serial,
                          &other_length);
        if (other_data == NULL)
            return NULL;

        if (other_length == 0) {
            *length_r = 0;
            return data;
        }

        /* if the "other" chunk is longer, then that trailer
           is used as-is, without mixing; it is part of the
           "next" song being faded in, and if there's a rest,
           it means cross-fading ends here */

        if (length > other_length)
            length = other_length;

        char *dest = pcm_buffer_get(&ao->cross_fade_buffer,
                                    other_length);
        memcpy(dest, other_data, other_length);
        pcm_mix(dest, data, length, &ao->in_audio_format,
                1.0 - chunk->mix_ratio);

        data = dest;
        length = other_length;
    }

    /* apply filter chain */

    data = filter_filter(ao->filter, data, length, &length, &error);
    if (data == NULL) {
        g_warning("\"%s\" [%s] failed to filter: %s",
                  ao->name, ao->plugin->name, error->message);
        g_error_free(error);
        return NULL;
    }

    *length_r = length;
    return data;
}
Beispiel #2
0
void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
	int pause = 0;
	int quit = 0;
	int bbp = buffered_before_play;
	int doCrossFade = 0;
	int crossFadeChunks = 0;
	int fadePosition;
	int nextChunk = -1;
	int test;
        int decodeWaitedOn = 0;
	char silence[CHUNK_SIZE] = { 0 };
	int previousMetadataChunk = -1;
	MetadataChunk currentMetadataChunk;
	int currentChunkSent = 1;
	int end;
	int next = -1;

//		fprintf(stderr,"In decode.c decodeParent func :\r\n");
	if(waitOnDecode(pc,dc,cb,&decodeWaitedOn)<0) return;

        pc->elapsedTime = 0;
	pc->state = PLAYER_STATE_PLAY;
	pc->play = 0;
	kill(getppid(),SIGUSR1);

	while(mpm_get_id(MPM_DECODE)>0 && cb->end-cb->begin<bbp && 
				cb->end!=buffered_chunks-1 &&
				dc->state!=DECODE_STATE_STOP) 
	{
		processDecodeInput();
		if(quit) return;
		playSilenceOrSleep();
	}

	while(!quit) {
		processDecodeInput();
                handleDecodeStart();
		handleMetadata(cb, pc, &previousMetadataChunk, 
				&currentChunkSent, &currentMetadataChunk);
		if(dc->state==DECODE_STATE_STOP && 
			pc->queueState==PLAYER_QUEUE_FULL &&
			pc->queueLockState==PLAYER_QUEUE_UNLOCKED) 
		{
			next = cb->end;
			dc->start = 1;
			pc->queueState = PLAYER_QUEUE_DECODE;
			kill(getppid(),SIGUSR1);
		}
		if(next>=0 && doCrossFade==0 && !dc->start && 
				dc->state!=DECODE_STATE_START) 
		{
			nextChunk = -1;
			if(isCurrentAudioFormat(&(cb->audioFormat))) {
				doCrossFade = 1;
				crossFadeChunks = 
				calculateCrossFadeChunks(pc,
                                        &(cb->audioFormat));
				if(!crossFadeChunks ||
						pc->crossFade>=dc->totalTime) 
				{
					doCrossFade = -1;
				}
			}
			else doCrossFade = -1;
		}

		/* copy thse to locale variables to prevent any potential
			race conditions and weirdness */
		end = cb->end;

		if(pause) my_usleep(10000);
		else if(cb->begin!=end && cb->begin!=next) {
			if(doCrossFade==1 && next>=0 &&
					((next>cb->begin && 
					(fadePosition=next-cb->begin)
					<=crossFadeChunks) || 
					(cb->begin>next &&
					(fadePosition=next-cb->begin+
					buffered_chunks)<=crossFadeChunks)))
			{
				if(nextChunk<0) {
					crossFadeChunks = fadePosition;
				}
				test = end;
				if(end < cb->begin) test+=buffered_chunks;
				nextChunk = cb->begin+crossFadeChunks;
				if(nextChunk<test) {
					if(nextChunk>=buffered_chunks)
					{
						nextChunk -=  buffered_chunks;  
					}
					pcm_mix(cb->chunks+cb->begin*CHUNK_SIZE,
							cb->chunks+nextChunk*
							CHUNK_SIZE,
							cb->chunkSize[
								cb->begin],
							cb->chunkSize[
								nextChunk],
							&(cb->audioFormat),
							((float)fadePosition)/
							crossFadeChunks);
					if(cb->chunkSize[nextChunk]>
							cb->chunkSize[cb->begin]
							)
					{
						cb->chunkSize[cb->begin]
								= cb->chunkSize
								[nextChunk];
					}
				}
				else {
					if(dc->state==DECODE_STATE_STOP)
					{
						doCrossFade = -1;
					}
					else continue;
				}
			}
			pc->elapsedTime = cb->times[cb->begin];
			pc->bitRate = cb->bitRate[cb->begin];
			pcm_volumeChange(cb->chunks+cb->begin*
				CHUNK_SIZE,
				cb->chunkSize[cb->begin],
				&(cb->audioFormat),
				pc->softwareVolume);
			if(playAudio(cb->chunks+cb->begin*CHUNK_SIZE,
				cb->chunkSize[cb->begin])<0) 
			{
				quit = 1;
			}
			if( cb->begin+1 >= buffered_chunks ) {
				cb->begin = 0;
			}
			else cb->begin++;
		}
		else if(next==cb->begin) {
			if(doCrossFade==1 && nextChunk>=0) {
				nextChunk = cb->begin+crossFadeChunks;
				test = cb->end;
				if(end < cb->begin) test+=buffered_chunks;
				if(nextChunk<test) {
					if(nextChunk>=buffered_chunks)
					{
						nextChunk -= buffered_chunks;
					}
					advanceOutputBufferTo(cb, pc, 
						&previousMetadataChunk,
						&currentChunkSent, 
						&currentMetadataChunk, 
						nextChunk);
				}	
			}
			while(pc->queueState==PLAYER_QUEUE_DECODE ||
					pc->queueLockState==PLAYER_QUEUE_LOCKED)
			{
				processDecodeInput();
				if(quit) {
					quitDecode(pc,dc);
					return;
				}
		fprintf(stderr,"In decode.c decodeParent while loop with my_usleep\r\n");
//				my_usleep(10000);
			}
			if(pc->queueState!=PLAYER_QUEUE_PLAY) {
				quit = 1;
				break;
			}
			else {
				next = -1;
				if(waitOnDecode(pc,dc,cb,&decodeWaitedOn)<0) {
                                        return;
                                }
				nextChunk = -1;
				doCrossFade = 0;
				crossFadeChunks = 0;
				pc->queueState = PLAYER_QUEUE_EMPTY;
				kill(getppid(),SIGUSR1);
			}
		}
		else if(mpm_get_id(MPM_DECODE)<=0 || 
				(dc->state==DECODE_STATE_STOP && !dc->start)) 
		{
			quit = 1;
			break;
		}
		else {
			if(playAudio(silence, CHUNK_SIZE) < 0) quit = 1;
		}
	}

	quitDecode(pc,dc);
}