예제 #1
0
// A C version of mix_mmx
// mix_mmx is 2.5 times as fast on Pentium 4
// NOTE : we always want this defined, even when using MMX, for the purpose of
// testing (see releasetest)
void mix_c()
{
    unsigned int uSamplesToMix = g_uBytesToMix >> 1;
    Uint8 *stream              = g_pSampleDst;
    unsigned int sample = 0, val_to_store = 0;

    for (sample = 0; sample < uSamplesToMix; sample += 2) {
        int mixed_sample_1 = 0, mixed_sample_2 = 0; // left/right channels
        struct mix_s *cur = g_pMixBufs;

        // mix all sound chips
        while (cur) {
            mixed_sample_1 += LOAD_LIL_SINT16(((short *)cur->pMixBuf) + sample);
            mixed_sample_2 += LOAD_LIL_SINT16(((short *)cur->pMixBuf) + sample + 1);
            cur = cur->pNext;
        }

        DO_CLIP(mixed_sample_1);
        DO_CLIP(mixed_sample_2);

        // note: sample2 needs to be on top because this is little endian, hence
        // LSB
        val_to_store = (((unsigned short)mixed_sample_2) << 16) |
                       ((unsigned short)mixed_sample_1);

        STORE_LIL_UINT32(stream, val_to_store);
        stream += 4;
    }
}
예제 #2
0
// called from sound mixer to get audio stream
void samples_get_stream(Uint8 *stream, int length, int unused)
{
#ifdef DEBUG
	assert (length % 4 == 0);	// make sure it's divisible by 4
#endif

	// (each sample is 4 bytes, which is why we divide length by 4)
	unsigned int uTotalSamples = length >> 2;

	// clear buffer so that our addition will work
	memset(stream, 0, length);

	unsigned int u = 0;

	// check to see if any sample is playing ...
	for (u = 0; u < MAX_DYNAMIC_SAMPLES; ++u)
	{
		sample_data_s *data = &g_SampleStates[u];

		if (data->bActive)
		{
			Uint8 *ptrStream = stream;

			// do each sample
			for (unsigned int uSample = 0; uSample < uTotalSamples; ++uSample)
			{
				// if there is still some sample data to be mixed to this stream
				if (data->uPos < data->uLength)
				{
					int iMixedSample1 = LOAD_LIL_SINT16((Sint16 *) ptrStream);
					int iMixedSample2 = LOAD_LIL_SINT16(((Sint16 *) ptrStream) + 1);

					Sint16 i16Sample1 = LOAD_LIL_SINT16(data->pu8Buf + data->uPos);
					iMixedSample1 += i16Sample1;
					data->uPos += 2;

					// if this is a stereo sample
					if (data->uChannels == 2)
					{
						iMixedSample2 += LOAD_LIL_SINT16(data->pu8Buf + data->uPos);
						data->uPos += 2;
					}
					// else this is a mono sample, so just duplicate the last sample we read in
					else
					{
						iMixedSample2 += i16Sample1;
					}

					DO_CLIP(iMixedSample1);	// prevent overflow
					DO_CLIP(iMixedSample2);

					// yes, sample2 should be the most significant, sample1 least significant.. releasetest tests this
					unsigned int val_to_store = (((Uint16) iMixedSample2) << 16) | (Uint16) iMixedSample1;
					STORE_LIL_UINT32(ptrStream, val_to_store);
					ptrStream += 4;
				}
				// else this sample is done, so get rid of the entry ...
				else
				{
					data->bActive = false;

					// if caller has requested to be notified when this sample is done ...
					if (data->finishedCallback != NULL)
					{
						data->finishedCallback(data->pu8Buf, u);
					}
					break;
				}
			} // end going through stream buffer
		} // end while we have states to be addressed
	} // end looping through all sample slots
}