// 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; } }
// 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 }