Beispiel #1
0
gc_int32 gauX_sample_source_wav_read(void* in_context, void* in_dst, gc_int32 in_numSamples,
                                     tOnSeekFunc in_onSeekFunc, void* in_seekContext)
{
  gau_SampleSourceWavContext* ctx = &((gau_SampleSourceWav*)in_context)->context;
  gc_int32 numRead = 0;
  gc_int32 totalSamples = ctx->wavHeader.dataSize / ctx->sampleSize;
  gc_mutex_lock(ctx->posMutex);
  if(ctx->pos + in_numSamples > totalSamples)
    in_numSamples = totalSamples - ctx->pos;
  if(in_numSamples > 0)
  {
    numRead = ga_data_source_read(ctx->dataSrc, in_dst, ctx->sampleSize, in_numSamples);
    ctx->pos += numRead;
  }
  gc_mutex_unlock(ctx->posMutex);
  return numRead;
}
Beispiel #2
0
gc_int32 gauX_sample_source_sound_read(void* in_context, void* in_dst, gc_int32 in_numSamples,
                                       tOnSeekFunc in_onSeekFunc, void* in_seekContext)
{
  gau_SampleSourceSoundContext* ctx = &((gau_SampleSourceSound*)in_context)->context;
  ga_Sound* snd = ctx->sound;
  char* src;
  gc_int32 pos;
  gc_int32 avail;
  gc_int32 numRead;
  gc_mutex_lock(ctx->posMutex);
  pos = ctx->pos;
  avail = ctx->numSamples - pos;
  numRead = in_numSamples > avail ? avail : in_numSamples;
  ctx->pos += numRead;
  gc_mutex_unlock(ctx->posMutex);
  src = (char*)ga_sound_data(snd) + pos * ctx->sampleSize;
  memcpy(in_dst, src, numRead * ctx->sampleSize);
  return numRead;
}
Beispiel #3
0
void ga_stream_manager_buffer(ga_StreamManager* in_mgr)
{
  gc_Link* link = in_mgr->streamList.next;
  while(link != &in_mgr->streamList)
  {
    gc_int32 streamDead;
    gaX_StreamLink* streamLink;
    streamLink = (gaX_StreamLink*)link->data;
    link = link->next;
    streamDead = gaX_stream_link_produce(streamLink);
    if(streamDead)
    {
      gc_mutex_lock(in_mgr->streamListMutex);
      gc_list_unlink((gc_Link*)streamLink);
      gc_mutex_unlock(in_mgr->streamListMutex);
      gaX_stream_link_release(streamLink);
    }
  }
}
Beispiel #4
0
gc_int32 gauX_sample_source_loop_read(void* in_context, void* in_dst, gc_int32 in_numSamples,
                                      tOnSeekFunc in_onSeekFunc, void* in_seekContext)
{
  gau_SampleSourceLoopContext* ctx = &((gau_SampleSourceLoop*)in_context)->context;
  gc_int32 numRead = 0;
  gc_int32 triggerSample, targetSample;
  gc_int32 pos, total;
  gc_int32 sampleSize;
  gc_int32 totalRead = 0;
  ga_SampleSource* ss = ctx->innerSrc;
  gc_mutex_lock(ctx->loopMutex);
  triggerSample = ctx->triggerSample;
  targetSample = ctx->targetSample;
  gc_mutex_unlock(ctx->loopMutex);
  pos = ga_sample_source_tell(ss, &total);
  if((targetSample < 0 && triggerSample <= 0))
    return ga_sample_source_read(ss, in_dst, in_numSamples, 0, 0);
  if(triggerSample <= 0)
    triggerSample = total;
  if(pos > triggerSample)
    return ga_sample_source_read(ss, in_dst, in_numSamples, 0, 0);
  sampleSize = ctx->sampleSize;
  while(in_numSamples)
  {
    gc_int32 avail = triggerSample - pos;
    gc_int32 doSeek = avail <= in_numSamples;
    gc_int32 toRead = doSeek ? avail : in_numSamples;
    numRead = ga_sample_source_read(ss, in_dst,  toRead, 0, 0);
    totalRead += numRead;
    in_numSamples -= numRead;
    in_dst = (char*)in_dst + numRead * sampleSize;
    if(doSeek && toRead == numRead)
    {
      ga_sample_source_seek(ss, targetSample);
      ++ctx->loopCount;
      if(in_onSeekFunc)
        in_onSeekFunc(totalRead, targetSample - triggerSample, in_seekContext);
    }
    pos = ga_sample_source_tell(ss, &total);
  }
  return totalRead;
}
Beispiel #5
0
gc_int32 gauX_sample_source_ogg_read(void* in_context, void* in_dst, gc_int32 in_numSamples,
                                     tOnSeekFunc in_onSeekFunc, void* in_seekContext)
{
  gau_SampleSourceOggContext* ctx = &((gau_SampleSourceOgg*)in_context)->context;
  gc_int32 samplesLeft = in_numSamples;
  gc_int32 samplesRead;
  gc_int32 channels = ctx->oggInfo->channels;
  gc_int32 totalSamples = 0;
  size_t dataSizeOff = 0;
  do{
    gc_int32 bitStream;
    gc_float32** samples;
    gc_int32 i;
    gc_int16* dst;
    gc_int32 channel;
    gc_mutex_lock(ctx->oggMutex);
    samplesRead = ov_read_float(&ctx->oggFile, &samples, samplesLeft, &bitStream);
    if(samplesRead == 0)
      ctx->endOfSamples = 1;
    gc_mutex_unlock(ctx->oggMutex);
    if(samplesRead > 0)
    {
      samplesLeft -= samplesRead;
      dst = (gc_int16*)(in_dst) + totalSamples * channels;
      totalSamples += samplesRead;
      for(i = 0; i < samplesRead; ++i)
      {
        for(channel = 0; channel < channels; ++channel, ++dst)
        {
          gc_float32 sample = samples[channel][i] * 32768.0f;
          gc_int32 int32Sample = (gc_int32)sample;
          gc_int16 int16Sample;
          int32Sample = int32Sample > 32767 ? 32767 : int32Sample < -32768 ? -32768 : int32Sample;
          int16Sample = (gc_int16)int32Sample;
          *dst = int16Sample;
        }
      }
    }
  } while (samplesRead > 0 && samplesLeft);
  return totalSamples;
}
Beispiel #6
0
gc_int32 gauX_data_source_memory_read(void* in_context, void* in_dst, gc_int32 in_size, gc_int32 in_count)
{
  gau_DataSourceMemoryContext* ctx = (gau_DataSourceMemoryContext*)in_context;
  gc_int32 ret = 0;
  gc_int32 dataSize = ga_memory_size(ctx->memory);
  gc_int32 toRead = in_size * in_count;
  gc_int32 remaining;

  gc_mutex_lock(ctx->memMutex);
  remaining = dataSize - ctx->pos;
  toRead = toRead < remaining ? toRead : remaining;
  toRead = toRead - (toRead % in_size);
  if(toRead)
  {
    memcpy(in_dst, (char*)ga_memory_data(ctx->memory) + ctx->pos, toRead);
    ctx->pos += toRead;
    ret = toRead / in_size;
  }
  gc_mutex_unlock(ctx->memMutex);
  return ret;
}
Beispiel #7
0
gc_int32 gauX_data_source_file_arc_seek(void* in_context, gc_int32 in_offset, gc_int32 in_origin)
{
  /* TODO: What is the best way to resolve the seeking-OOB cases? */
  gau_DataSourceFileArcContext* ctx = (gau_DataSourceFileArcContext*)in_context;
  gc_mutex_lock(ctx->fileMutex);
  switch(in_origin)
  {
  case GA_SEEK_ORIGIN_SET:
    if(ctx->size > 0 && in_offset > ctx->size)
    {
      gc_mutex_unlock(ctx->fileMutex);
      return -1;
    }
    fseek(ctx->f, ctx->offset + in_offset, SEEK_SET);
    break;
  case GA_SEEK_ORIGIN_CUR:
    {
      gc_int32 curPos = ftell(ctx->f) - ctx->offset;
      gc_int32 newPos = curPos + in_offset;
      if(newPos < 0 || (ctx->size > 0 && newPos > ctx->size))
      {
        gc_mutex_unlock(ctx->fileMutex);
        return -1;
      }
      fseek(ctx->f, in_offset, SEEK_CUR);
    }
    break;
  case GA_SEEK_ORIGIN_END:
    if(ctx->size <= 0)
    {
      gc_mutex_unlock(ctx->fileMutex);
      return -1;
    }
    fseek(ctx->f, ctx->offset + ctx->size + in_offset, SEEK_SET);
    break;
  }
  gc_mutex_unlock(ctx->fileMutex);
  return 0;
}
Beispiel #8
0
void ga_stream_acquire(ga_BufferedStream* in_stream)
{
  gc_mutex_lock(in_stream->refMutex);
  ++in_stream->refCount;
  gc_mutex_unlock(in_stream->refMutex);
}
Beispiel #9
0
void gaX_stream_link_acquire(gaX_StreamLink* in_streamLink)
{
  gc_mutex_lock(in_streamLink->refMutex);
  ++in_streamLink->refCount;
  gc_mutex_unlock(in_streamLink->refMutex);
}
Beispiel #10
0
void gaX_stream_link_kill(gaX_StreamLink* in_streamLink)
{
  gc_mutex_lock(in_streamLink->produceMutex);
  in_streamLink->stream = 0;
  gc_mutex_unlock(in_streamLink->produceMutex);
}
Beispiel #11
0
Datei: ga.c Projekt: 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);
          }
        }
      }
    }
  }
}
Beispiel #12
0
Datei: ga.c Projekt: Botyto/Core
void ga_sound_acquire(ga_Sound* in_sound)
{
  gc_mutex_lock(in_sound->refMutex);
  ++in_sound->refCount;
  gc_mutex_unlock(in_sound->refMutex);
}
Beispiel #13
0
Datei: ga.c Projekt: Botyto/Core
void ga_memory_acquire(ga_Memory* in_mem)
{
  gc_mutex_lock(in_mem->refMutex);
  ++in_mem->refCount;
  gc_mutex_unlock(in_mem->refMutex);
}
Beispiel #14
0
Datei: ga.c Projekt: Botyto/Core
void ga_sample_source_acquire(ga_SampleSource* in_sampleSrc)
{
  gc_mutex_lock(in_sampleSrc->refMutex);
  ++in_sampleSrc->refCount;
  gc_mutex_unlock(in_sampleSrc->refMutex);
}
Beispiel #15
0
Datei: ga.c Projekt: Botyto/Core
void ga_data_source_acquire(ga_DataSource* in_dataSrc)
{
  gc_mutex_lock(in_dataSrc->refMutex);
  ++in_dataSrc->refCount;
  gc_mutex_unlock(in_dataSrc->refMutex);
}