void vc_voice_change(void *st_, float *fbuf, int16_t *data, int samples, int datalen) { SoundTouch *st = (SoundTouch *)st_; #if defined(INTEGER_SAMPLES) || defined(SOUNDTOUCH_INTEGER_SAMPLES) st->putSamples(data, samples); if (st->numSamples() >= samples) { st->receiveSamplesEx(data, samples); } else { memset(data, 0, datalen); } #elif defined(FLOAT_SAMPLES) || defined(SOUNDTOUCH_FLOAT_SAMPLES) slin_to_flin(fbuf, data, samples); st->putSamples(fbuf, samples); if ((int)st->numSamples() >= samples) { st->receiveSamples(fbuf, samples); flin_to_slin(data, fbuf, samples); } else { memset(data, 0, datalen); } #else # error "unknown soundtouch sample type" #endif }
void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) { if (start != next_sample) { // Reset on seek sampler->clear(); next_sample = start; inputReadOffset = (__int64)(sample_multiplier * (long double)start); // Reset at new read position (NOT sample exact :( ). dst_samples_filled=0; } bool buffer_full = false; int samples_filled = 0; do { // Empty buffer if something is still left. if (dst_samples_filled) { int copysamples = min((int)count-samples_filled, dst_samples_filled); // Copy finished samples if (copysamples) { memcpy((BYTE*)buf+vi.BytesFromAudioSamples(samples_filled), (BYTE*)dstbuffer, (size_t)vi.BytesFromAudioSamples(copysamples)); samples_filled += copysamples; dst_samples_filled -= copysamples; // Move non-used samples memcpy(dstbuffer, &dstbuffer[copysamples*2], (size_t)vi.BytesFromAudioSamples(dst_samples_filled)); } if (samples_filled >= count) buffer_full = true; } // If buffer empty - refill if (dst_samples_filled==0) { // Read back samples from filter int samples_out = 0; int gotsamples = 0; do { gotsamples = sampler->receiveSamples(&dstbuffer[vi.BytesFromAudioSamples(samples_out)], BUFFERSIZE - samples_out); samples_out += gotsamples; } while (gotsamples > 0); dst_samples_filled = samples_out; if (!dst_samples_filled) { // We didn't get any samples // Feed new samples to filter child->GetAudio(dstbuffer, inputReadOffset, BUFFERSIZE, env); inputReadOffset += BUFFERSIZE; sampler->putSamples(dstbuffer, BUFFERSIZE); } // End if no samples } // end if empty buffer } while (!buffer_full); next_sample += count; }
void processAudio(const unsigned char* buffer, unsigned int length) { if (length < primaryBufferBytes) { unsigned int i; for ( i = 0 ; i < length ; i += 4 ) { if(SwapChannels == 0) { /* Left channel */ primaryBuffer[ i ] = buffer[ i + 2 ]; primaryBuffer[ i + 1 ] = buffer[ i + 3 ]; /* Right channel */ primaryBuffer[ i + 2 ] = buffer[ i ]; primaryBuffer[ i + 3 ] = buffer[ i + 1 ]; } else { /* Left channel */ primaryBuffer[ i ] = buffer[ i ]; primaryBuffer[ i + 1 ] = buffer[ i + 1 ]; /* Right channel */ primaryBuffer[ i + 2 ] = buffer[ i + 2 ]; primaryBuffer[ i + 3 ] = buffer[ i + 3 ]; } } } else DebugMessage(M64MSG_WARNING, "processAudio(): Audio primary buffer overflow."); #ifdef FP_ENABLED int numSamples = length/sizeof(short); short* primaryBufferShort = (short*)primaryBuffer; float primaryBufferFloat[numSamples]; for(int index = 0; index < numSamples; ++index) { primaryBufferFloat[index] = static_cast<float>(primaryBufferShort[index])/32767.0; } soundTouch.putSamples((SAMPLETYPE*)primaryBufferFloat, length/N64_SAMPLE_BYTES); #else soundTouch.putSamples((SAMPLETYPE*)primaryBuffer, length/N64_SAMPLE_BYTES); #endif int outSamples = 0; do { outSamples = soundTouch.receiveSamples((SAMPLETYPE*)secondaryBuffers[secondaryBufferIndex], SecondaryBufferSize); if(outSamples != 0 && lock.value > 0) { SLresult result = (*bufferQueue)->Enqueue(bufferQueue, secondaryBuffers[secondaryBufferIndex], outSamples*SLES_SAMPLE_BYTES); if(result != SL_RESULT_SUCCESS) { lock.errors++; } else { --lock.value; ++lock.count; } secondaryBufferIndex++; if(secondaryBufferIndex > (SecondaryBufferNbr-1)) secondaryBufferIndex = 0; } } while (outSamples != 0); }
void SoundTouch_putSamples(void *stouch, float *samples, unsigned int numSamples) { SoundTouch *soundTouch = (SoundTouch *)stouch; soundTouch->putSamples(samples, numSamples); }