예제 #1
0
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
}
예제 #2
0
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;
}
예제 #3
0
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);
}
예제 #4
0
void SoundTouch_putSamples(void *stouch, float *samples, unsigned int numSamples) 
{
    SoundTouch *soundTouch = (SoundTouch *)stouch;
    soundTouch->putSamples(samples, numSamples);
}