Streamer in SDL_RunAudio should be totally implemented, but hasn't been tested yet. gsoc2008_audio_resampling
authorAaron Wishnick <schnarf@gmail.com>
Thu, 14 Aug 2008 08:21:25 +0000
branchgsoc2008_audio_resampling
changeset 26674174e511655f
parent 2666 e12ccc6c9576
child 4413 14a08e45a4d3
Streamer in SDL_RunAudio should be totally implemented, but hasn't been tested yet.
src/audio/SDL_audio.c
     1.1 --- a/src/audio/SDL_audio.c	Wed Aug 13 02:50:10 2008 +0000
     1.2 +++ b/src/audio/SDL_audio.c	Thu Aug 14 08:21:25 2008 +0000
     1.3 @@ -319,6 +319,7 @@
     1.4      void *udata;
     1.5      void (SDLCALL * fill) (void *userdata, Uint8 * stream, int len);
     1.6      int silence;
     1.7 +	int stream_max_len;
     1.8  	
     1.9  	/* For streaming when the buffer sizes don't match up */
    1.10  	Uint8 *istream;
    1.11 @@ -332,20 +333,42 @@
    1.12      fill = device->spec.callback;
    1.13      udata = device->spec.userdata;
    1.14  
    1.15 +	/* By default do not stream */
    1.16 +	device->use_streamer = 0;
    1.17 +
    1.18      if (device->convert.needed) {
    1.19          if (device->convert.src_format == AUDIO_U8) {
    1.20              silence = 0x80;
    1.21          } else {
    1.22              silence = 0;
    1.23          }
    1.24 -        stream_len = device->convert.len;
    1.25 +		
    1.26 +		/* If the result of the conversion alters the length, i.e. resampling is being used, use the streamer */
    1.27 +		if(device->convert.len_mult != 1 || device->convert.len_div != 1) {
    1.28 +			/* The streamer's maximum length should be twice whichever is larger: spec.size or len_cvt */
    1.29 +			stream_max_len = 2 * device->spec.size;
    1.30 +			if(device->convert.len_mult > device->convert.len_div) {
    1.31 +				stream_max_len *= device->convert.len_mult;
    1.32 +				stream_max_len /= device->convert.len_div;
    1.33 +			}
    1.34 +			if(SDL_StreamInit(&device->streamer, stream_max_len, silence) < 0) return -1;
    1.35 +			device->use_streamer = 1;
    1.36 +			
    1.37 +			/* istream_len should be the length of what we grab from the callback and feed to conversion,
    1.38 +			    so that we get close to spec_size. I.e. we want device.spec_size = istream_len * u / d
    1.39 +			*/
    1.40 +			istream_len = device->spec.size * device->convert.len_div / device->convert.len_mult;
    1.41 +		}
    1.42 +		
    1.43 +        /* stream_len = device->convert.len; */
    1.44 +		stream_len = device->spec.size;
    1.45      } else {
    1.46          silence = device->spec.silence;
    1.47          stream_len = device->spec.size;
    1.48      }
    1.49  	
    1.50  	/* Determine if the streamer is necessary here */
    1.51 -	if(device->use_streamer) {
    1.52 +	if(device->use_streamer == 1) {
    1.53  		/* This code is almost the same as the old code. The difference is, instead of reding
    1.54  		   directly from the callback into "stream", then converting and sending the audio off,
    1.55  		   we go: callback -> "istream" -> (conversion) -> streamer -> stream -> device.
    1.56 @@ -361,6 +384,20 @@
    1.57  		while (device->enabled) {
    1.58  			/* Only read in audio if the streamer doesn't have enough already (if it does not have enough samples to output) */
    1.59  			if(SDL_StreamLength(&device->streamer) < stream_len) {
    1.60 +				/* Set up istream */
    1.61 +				if (device->convert.needed) {
    1.62 +					if (device->convert.buf) {
    1.63 +						istream = device->convert.buf;
    1.64 +					} else {
    1.65 +						continue;
    1.66 +					}
    1.67 +				} else {
    1.68 +					istream = current_audio.impl.GetDeviceBuf(device);
    1.69 +					if (istream == NULL) {
    1.70 +						istream = device->fake_stream;
    1.71 +					}
    1.72 +				}
    1.73 +			
    1.74  				/* Read from the callback into the _input_ stream */
    1.75  				if (!device->paused) {
    1.76  					SDL_mutexP(device->mixer_lock);
    1.77 @@ -371,12 +408,11 @@
    1.78  				 /* Convert the audio if necessary and write to the streamer */
    1.79  				if (device->convert.needed) {
    1.80  					SDL_ConvertAudio(&device->convert);
    1.81 -					istream = current_audio.impl.GetDeviceBuf(device);
    1.82  					if (istream == NULL) {
    1.83  						istream = device->fake_stream;
    1.84  					}
    1.85 -					SDL_memcpy(istream, device->convert.buf, device->convert.len_cvt);
    1.86 -					SDL_StreamWrite(&device->streamer, istream, device->convert.len_cvt);
    1.87 +					/*SDL_memcpy(istream, device->convert.buf, device->convert.len_cvt);*/
    1.88 +					SDL_StreamWrite(&device->streamer, device->convert.buf, device->convert.len_cvt);
    1.89  				} else {
    1.90  					SDL_StreamWrite(&device->streamer, istream, istream_len);
    1.91  				}
    1.92 @@ -467,6 +503,9 @@
    1.93  
    1.94      /* Wait for the audio to drain.. */
    1.95      current_audio.impl.WaitDone(device);
    1.96 +	
    1.97 +	/* If necessary, deinit the streamer */
    1.98 +	if(device->use_streamer == 1) SDL_StreamDeinit(&device->streamer);
    1.99  
   1.100      return (0);
   1.101  }