src/audio/SDL_audio.c
changeset 3336 00fab0ebfe54
parent 3283 1ed5d432e468
child 3537 e897a4a9f578
equal deleted inserted replaced
3335:b8d313de8a65 3336:00fab0ebfe54
   324     Uint8 *stream;
   324     Uint8 *stream;
   325     int stream_len;
   325     int stream_len;
   326     void *udata;
   326     void *udata;
   327     void (SDLCALL * fill) (void *userdata, Uint8 * stream, int len);
   327     void (SDLCALL * fill) (void *userdata, Uint8 * stream, int len);
   328     int silence;
   328     int silence;
       
   329     Uint32 delay;
   329 
   330 
   330     /* For streaming when the buffer sizes don't match up */
   331     /* For streaming when the buffer sizes don't match up */
   331     Uint8 *istream;
   332     Uint8 *istream;
   332     int istream_len;
   333     int istream_len;
   333 
   334 
   377     } else {
   378     } else {
   378         silence = device->spec.silence;
   379         silence = device->spec.silence;
   379         stream_len = device->spec.size;
   380         stream_len = device->spec.size;
   380     }
   381     }
   381 
   382 
       
   383     /* Calculate the delay while paused */
       
   384     delay = ((device->spec.samples * 1000) / device->spec.freq);
       
   385 
   382     /* Determine if the streamer is necessary here */
   386     /* Determine if the streamer is necessary here */
   383     if (device->use_streamer == 1) {
   387     if (device->use_streamer == 1) {
   384         /* This code is almost the same as the old code. The difference is, instead of reding
   388         /* This code is almost the same as the old code. The difference is, instead of reading
   385            directly from the callback into "stream", then converting and sending the audio off,
   389            directly from the callback into "stream", then converting and sending the audio off,
   386            we go: callback -> "istream" -> (conversion) -> streamer -> stream -> device.
   390            we go: callback -> "istream" -> (conversion) -> streamer -> stream -> device.
   387            However, reading and writing with streamer are done separately:
   391            However, reading and writing with streamer are done separately:
   388            - We only call the callback and write to the streamer when the streamer does not
   392            - We only call the callback and write to the streamer when the streamer does not
   389            contain enough samples to output to the device.
   393            contain enough samples to output to the device.
   392            This allows us to perform resampling in the conversion step, where the output of the
   396            This allows us to perform resampling in the conversion step, where the output of the
   393            resampling process can be any number. We will have to see what a good size for the
   397            resampling process can be any number. We will have to see what a good size for the
   394            stream's maximum length is, but I suspect 2*max(len_cvt, stream_len) is a good figure.
   398            stream's maximum length is, but I suspect 2*max(len_cvt, stream_len) is a good figure.
   395          */
   399          */
   396         while (device->enabled) {
   400         while (device->enabled) {
       
   401 
       
   402             if (device->paused) {
       
   403                 SDL_Delay(delay);
       
   404                 continue;
       
   405             }
       
   406 
   397             /* Only read in audio if the streamer doesn't have enough already (if it does not have enough samples to output) */
   407             /* Only read in audio if the streamer doesn't have enough already (if it does not have enough samples to output) */
   398             if (SDL_StreamLength(&device->streamer) < stream_len) {
   408             if (SDL_StreamLength(&device->streamer) < stream_len) {
   399                 /* Set up istream */
   409                 /* Set up istream */
   400                 if (device->convert.needed) {
   410                 if (device->convert.needed) {
   401                     if (device->convert.buf) {
   411                     if (device->convert.buf) {
   402                         istream = device->convert.buf;
   412                         istream = device->convert.buf;
   403                     } else {
   413                     } else {
   404                         continue;
   414                         continue;
   405                     }
   415                     }
   406                 } else {
   416                 } else {
       
   417 /* FIXME: Ryan, this is probably wrong.  I imagine we don't want to get
       
   418  * a device buffer both here and below in the stream output.
       
   419  */
   407                     istream = current_audio.impl.GetDeviceBuf(device);
   420                     istream = current_audio.impl.GetDeviceBuf(device);
   408                     if (istream == NULL) {
   421                     if (istream == NULL) {
   409                         istream = device->fake_stream;
   422                         istream = device->fake_stream;
   410                     }
   423                     }
   411                 }
   424                 }
   412 
   425 
   413                 /* Read from the callback into the _input_ stream */
   426                 /* Read from the callback into the _input_ stream */
   414                 if (!device->paused) {
   427                 SDL_mutexP(device->mixer_lock);
   415                     SDL_mutexP(device->mixer_lock);
   428                 (*fill) (udata, istream, istream_len);
   416                     (*fill) (udata, istream, istream_len);
   429                 SDL_mutexV(device->mixer_lock);
   417                     SDL_mutexV(device->mixer_lock);
       
   418                 }
       
   419 
   430 
   420                 /* Convert the audio if necessary and write to the streamer */
   431                 /* Convert the audio if necessary and write to the streamer */
   421                 if (device->convert.needed) {
   432                 if (device->convert.needed) {
   422                     SDL_ConvertAudio(&device->convert);
   433                     SDL_ConvertAudio(&device->convert);
   423                     if (istream == NULL) {
   434                     if (istream == NULL) {
   449 
   460 
   450                 /* Now read from the streamer */
   461                 /* Now read from the streamer */
   451                 SDL_StreamRead(&device->streamer, stream, stream_len);
   462                 SDL_StreamRead(&device->streamer, stream, stream_len);
   452 
   463 
   453                 /* Ready current buffer for play and change current buffer */
   464                 /* Ready current buffer for play and change current buffer */
   454                 if (stream != device->fake_stream && !device->paused) {
   465                 if (stream != device->fake_stream) {
   455                     current_audio.impl.PlayDevice(device);
   466                     current_audio.impl.PlayDevice(device);
   456                     /* Wait for an audio buffer to become available */
   467                     /* Wait for an audio buffer to become available */
   457                     current_audio.impl.WaitDevice(device);
   468                     current_audio.impl.WaitDevice(device);
   458                 } else {
   469                 } else {
   459                     SDL_Delay((device->spec.samples * 1000) /
   470                     SDL_Delay(delay);
   460                               device->spec.freq);
       
   461                 }
   471                 }
   462             }
   472             }
   463 
   473 
   464         }
   474         }
   465     } else {
   475     } else {
   466         /* Otherwise, do not use the streamer. This is the old code. */
   476         /* Otherwise, do not use the streamer. This is the old code. */
   467 
   477 
   468         /* Loop, filling the audio buffers */
   478         /* Loop, filling the audio buffers */
   469         while (device->enabled) {
   479         while (device->enabled) {
       
   480 
       
   481             if (device->paused) {
       
   482                 SDL_Delay(delay);
       
   483                 continue;
       
   484             }
   470 
   485 
   471             /* Fill the current buffer with sound */
   486             /* Fill the current buffer with sound */
   472             if (device->convert.needed) {
   487             if (device->convert.needed) {
   473                 if (device->convert.buf) {
   488                 if (device->convert.buf) {
   474                     stream = device->convert.buf;
   489                     stream = device->convert.buf;
   480                 if (stream == NULL) {
   495                 if (stream == NULL) {
   481                     stream = device->fake_stream;
   496                     stream = device->fake_stream;
   482                 }
   497                 }
   483             }
   498             }
   484 
   499 
   485             if (!device->paused) {
   500             SDL_mutexP(device->mixer_lock);
   486                 SDL_mutexP(device->mixer_lock);
   501             (*fill) (udata, stream, stream_len);
   487                 (*fill) (udata, stream, stream_len);
   502             SDL_mutexV(device->mixer_lock);
   488                 SDL_mutexV(device->mixer_lock);
       
   489             }
       
   490 
   503 
   491             /* Convert the audio if necessary */
   504             /* Convert the audio if necessary */
   492             if (device->convert.needed) {
   505             if (device->convert.needed) {
   493                 SDL_ConvertAudio(&device->convert);
   506                 SDL_ConvertAudio(&device->convert);
   494                 stream = current_audio.impl.GetDeviceBuf(device);
   507                 stream = current_audio.impl.GetDeviceBuf(device);
   498                 SDL_memcpy(stream, device->convert.buf,
   511                 SDL_memcpy(stream, device->convert.buf,
   499                            device->convert.len_cvt);
   512                            device->convert.len_cvt);
   500             }
   513             }
   501 
   514 
   502             /* Ready current buffer for play and change current buffer */
   515             /* Ready current buffer for play and change current buffer */
   503             if (stream != device->fake_stream && !device->paused) {
   516             if (stream != device->fake_stream) {
   504                 current_audio.impl.PlayDevice(device);
   517                 current_audio.impl.PlayDevice(device);
   505                 /* Wait for an audio buffer to become available */
   518                 /* Wait for an audio buffer to become available */
   506                 current_audio.impl.WaitDevice(device);
   519                 current_audio.impl.WaitDevice(device);
   507             } else {
   520             } else {
   508                 SDL_Delay((device->spec.samples * 1000) / device->spec.freq);
   521                 SDL_Delay(delay);
   509             }
   522             }
   510         }
   523         }
   511     }
   524     }
   512 
   525 
   513     /* Wait for the audio to drain.. */
   526     /* Wait for the audio to drain.. */