コード例 #1
0
ファイル: ga.c プロジェクト: Botyto/Core
ga_Sound* ga_sound_create_sample_source(ga_SampleSource* in_sampleSrc)
{
  ga_Sound* ret = 0;
  ga_Format format;
  gc_int32 dataSize;
  gc_int32 totalSamples;
  ga_SampleSource* sampleSrc = in_sampleSrc;
  gc_int32 sampleSize;
  ga_sample_source_format(sampleSrc, &format);
  sampleSize = ga_format_sampleSize(&format);
  ga_sample_source_tell(sampleSrc, &totalSamples);
  if(totalSamples > 0)
  {
    /* Known total samples*/
    char* data;
    ga_Memory* memory;
    dataSize = sampleSize * totalSamples;
    data = gcX_ops->allocFunc(dataSize);
    ga_sample_source_read(sampleSrc, data, totalSamples, 0, 0);
    memory = gaX_memory_create(data, dataSize, 0);
    if(memory)
    {
      ret = ga_sound_create(memory, &format);
      if(!ret)
        ga_memory_release(memory);
    }
    else
      gcX_ops->freeFunc(data);
  }
  else
  {
    /* Unknown total samples */
    gc_int32 BUFFER_SAMPLES = format.sampleRate * 2;
    char* data = 0;
    ga_Memory* memory;
    totalSamples = 0;
    while(!ga_sample_source_end(sampleSrc))
    {
      gc_int32 numSamplesRead;
      data = gcX_ops->reallocFunc(data, (totalSamples + BUFFER_SAMPLES) * sampleSize);
      numSamplesRead = ga_sample_source_read(sampleSrc, data + (totalSamples * sampleSize), BUFFER_SAMPLES, 0, 0);
      if(numSamplesRead < BUFFER_SAMPLES)
      {
        data = gcX_ops->reallocFunc(data, (totalSamples + numSamplesRead) * sampleSize);
      }
      totalSamples += numSamplesRead;
    }
    memory = gaX_memory_create(data, totalSamples * sampleSize, 0);
    if(memory)
    {
      ret = ga_sound_create(memory, &format);
      if(!ret)
        ga_memory_release(memory);
    }
    else
      gcX_ops->freeFunc(data);
  }
  return ret;
}
コード例 #2
0
ファイル: ga_stream.c プロジェクト: Antranilan/Sparky
void ga_stream_produce(ga_BufferedStream* in_stream)
{
  ga_BufferedStream* s = in_stream;
  gc_CircBuffer* b = s->buffer;
  gc_int32 sampleSize = ga_format_sampleSize(&s->format);
  gc_int32 bytesFree = gc_buffer_bytesFree(b);
  if(s->seek >= 0)
  {
    gc_int32 samplePos;
    gc_mutex_lock(s->readMutex);
    gc_mutex_lock(s->seekMutex);
    if(s->seek >= 0) /* Check again now that we're mutexed */
    {
      samplePos = s->seek;
      s->tell = samplePos;
      s->seek = -1;
      s->nextSample = samplePos;
      ga_sample_source_seek(s->innerSrc, samplePos);
      gc_buffer_consume(s->buffer, gc_buffer_bytesAvail(s->buffer)); /* Clear buffer */
      gauX_tell_jump_clear(&s->tellJumps); /* Clear tell-jump list */
    }
    gc_mutex_unlock(s->seekMutex);
    gc_mutex_unlock(s->readMutex);
  }

  while(bytesFree)
  {
    gc_int32 samplesWritten = 0;
    gc_int32 bytesWritten = 0;
    gc_int32 bytesToWrite = bytesFree;
    samplesWritten = gaX_read_samples_into_stream(s, b, bytesToWrite / sampleSize, s->innerSrc);
    bytesWritten = samplesWritten * sampleSize;
    bytesFree -= bytesWritten;
    s->nextSample += samplesWritten;
    if(bytesWritten < bytesToWrite && ga_sample_source_end(s->innerSrc))
    {
      s->end = 1;
      break;
    }
  }
}
コード例 #3
0
ファイル: gau.c プロジェクト: dazzlex27/S3DGE
gc_int32 gauX_sample_source_loop_end(void* in_context)
{
  gau_SampleSourceLoopContext* ctx = &((gau_SampleSourceLoop*)in_context)->context;
  return ga_sample_source_end(ctx->innerSrc);
}
コード例 #4
0
ファイル: ga.c プロジェクト: Botyto/Core
void gaX_mixer_mix_handle(ga_Mixer* in_mixer, ga_Handle* in_handle, gc_int32 in_numSamples)
{
  ga_Handle* h = in_handle;

  ga_Mixer* m = in_mixer;
  ga_SampleSource* ss = h->sampleSrc;
  if(ga_sample_source_end(ss))
  {
    /* Stream is finished! */
    gc_mutex_lock(h->handleMutex);
    if(h->state < GA_HANDLE_STATE_FINISHED)
      h->state = GA_HANDLE_STATE_FINISHED;
    gc_mutex_unlock(h->handleMutex);
    return;
  }
  else
  {
    if(h->state == GA_HANDLE_STATE_PLAYING)
    {
      ga_Format handleFormat;
      ga_sample_source_format(ss, &handleFormat);
      {
        /* Check if we have enough samples to stream a full buffer */
        gc_int32 srcSampleSize = ga_format_sampleSize(&handleFormat);
        gc_int32 dstSampleSize = ga_format_sampleSize(&m->format);
        gc_float32 oldPitch = h->pitch;
        gc_float32 dstToSrc = handleFormat.sampleRate / (gc_float32)m->format.sampleRate * oldPitch;
        gc_int32 requested = (gc_int32)(in_numSamples * dstToSrc);
        requested = requested / dstToSrc < in_numSamples ? requested + 1 : requested;
        if(requested > 0 && ga_sample_source_ready(ss, requested))
        {
          gc_float32 gain, pan, pitch;
          gc_int32* dstBuffer;
          gc_int32 dstSamples;

          gc_mutex_lock(h->handleMutex);
          gain = h->gain;
          pan = h->pan;
          pitch = h->pitch;
          gc_mutex_unlock(h->handleMutex);

          /* We avoided a mutex lock by using pitch to check if buffer has enough dst samples */
          /* If it has changed since then, we re-test to make sure we still have enough samples */
          if(oldPitch != pitch)
          {
            dstToSrc = handleFormat.sampleRate / (gc_float32)m->format.sampleRate * pitch;
            requested = (gc_int32)(in_numSamples * dstToSrc);
            requested = requested / dstToSrc < in_numSamples ? requested + 1 : requested;
            if(!(requested > 0 && ga_sample_source_ready(ss, requested)))
              return;
          }

          dstBuffer = &m->mixBuffer[0];
          dstSamples = in_numSamples;
          {
            /* TODO: To optimize, we can refactor the _read() interface to be _mix(), avoiding this malloc/copy */
            gc_int32 bufferSize = requested * srcSampleSize;
            void* src = gcX_ops->allocFunc(bufferSize);
            gc_int32 dstBytes = dstSamples * dstSampleSize;
            gc_int32 numRead = 0;
            numRead = ga_sample_source_read(ss, src, requested, 0, 0);
            gaX_mixer_mix_buffer(in_mixer,
                                 src, numRead, &handleFormat,
                                 dstBuffer, dstSamples, &m->format,
                                 gain, pan, pitch);
            gcX_ops->freeFunc(src);
          }
        }
      }
    }
  }
}