mirror of
				https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
				synced 2023-10-10 17:16:51 +00:00 
			
		
		
		
	New audio ring buffer code, now OSS part.
This commit is contained in:
		
							
								
								
									
										7
									
								
								Todo
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								Todo
									
									
									
									
									
								
							| @@ -37,6 +37,7 @@ video: | ||||
|     radio no need to wait on video buffers | ||||
|     starting with radio and own X11 server, shows no video | ||||
|     some low-bandwidth tv channels have hiccups. | ||||
|     check start with 24Hz display rate | ||||
|  | ||||
| vdpau: | ||||
|     software decoder path not working | ||||
| @@ -73,10 +74,8 @@ x11: | ||||
|     support embedded mode | ||||
|  | ||||
| audio: | ||||
|     Combine alsa+oss ringbuffer code. | ||||
|     Make alsa thread/polled and oss thread/polled output module runtime | ||||
|     selectable. | ||||
|     software volume support (could be done with asound.conf) | ||||
|     Mute should do a real mute and not only set volume to zero. | ||||
|     Starting suspended and muted, didn't register the mute. | ||||
|     Relaxed audio sync checks at end of packet and already in sync | ||||
| @@ -84,12 +83,10 @@ audio: | ||||
|     only wait for video start, if video is running. | ||||
|     Not primary device, don't use and block audio/video. | ||||
|     multiple open of audio device, reduce them. | ||||
|     Not all channel conversions are written (f.e. 2->3 ... 5->6 ...) | ||||
|  | ||||
| audio/alsa: | ||||
|     better downmix of >2 channels on 2 channel hardware | ||||
|     remix support of unsupported sample rates | ||||
|     libav supports only resample of mono to 2 channels | ||||
|     ffmpeg didn't support resample of 5 to 2 channels | ||||
|  | ||||
| audio/oss: | ||||
|     alsa oss emulation mixer "pcm" not working | ||||
|   | ||||
							
								
								
									
										378
									
								
								audio.c
									
									
									
									
									
								
							
							
						
						
									
										378
									
								
								audio.c
									
									
									
									
									
								
							| @@ -35,13 +35,12 @@ | ||||
| /// | ||||
| /// | ||||
| ///	@todo FIXME: there can be problems with little/big endian. | ||||
| ///	@todo FIXME: can combine OSS and alsa ring buffer | ||||
| /// | ||||
|  | ||||
| //#define USE_ALSA			///< enable alsa support | ||||
| //#define USE_OSS			///< enable OSS support | ||||
| #define USE_AUDIO_THREAD		///< use thread for audio playback | ||||
| #define USE_AUDIORING			///< new audio ring code (incomplete) | ||||
| #define USE_AUDIORING			///< new audio ring code (testing) | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdint.h> | ||||
| @@ -107,12 +106,16 @@ typedef struct _audio_module_ | ||||
|     const char *Name;			///< audio output module name | ||||
|  | ||||
|     int (*const Thread) (void);		///< module thread handler | ||||
| #ifndef USE_AUDIORING | ||||
|     void (*const Enqueue) (const void *, int);	///< enqueue samples for output | ||||
|     void (*const VideoReady) (void);	///< video ready, start audio | ||||
| #endif | ||||
|     void (*const FlushBuffers) (void);	///< flush sample buffers | ||||
| #ifndef USE_AUDIORING | ||||
|     void (*const Poller) (void);	///< output poller | ||||
|     int (*const FreeBytes) (void);	///< number of bytes free in buffer | ||||
|     int (*const UsedBytes) (void);	///< number of bytes used in buffer | ||||
| #endif | ||||
|      int64_t(*const GetDelay) (void);	///< get current audio delay | ||||
|     void (*const SetVolume) (int);	///< set output volume | ||||
|     int (*const Setup) (int *, int *, int);	///< setup channels, samplerate | ||||
| @@ -142,13 +145,14 @@ static char AudioDoingInit;		///> flag in init, reduce error | ||||
| static volatile char AudioRunning;	///< thread running / stopped | ||||
| static volatile char AudioPaused;	///< audio paused | ||||
| static volatile char AudioVideoIsReady;	///< video ready start early | ||||
|  | ||||
| #ifndef USE_AUDIORING | ||||
| static unsigned AudioSampleRate;	///< audio sample rate in Hz | ||||
| static unsigned AudioChannels;		///< number of audio channels | ||||
| static const int AudioBytesProSample = 2;	///< number of bytes per sample | ||||
| static int64_t AudioPTS;		///< audio pts clock | ||||
|  | ||||
| #ifndef USE_AUDIO_THREAD | ||||
| #endif | ||||
| static const int AudioBytesProSample = 2;	///< number of bytes per sample | ||||
|  | ||||
| static int AudioBufferTime = 336;	///< audio buffer time in ms | ||||
|  | ||||
| #ifdef USE_AUDIO_THREAD | ||||
| @@ -170,7 +174,7 @@ static int AudioMaxNormalize;		///< max. normalize factor | ||||
| static int AudioCompressionFactor;	///< current compression factor | ||||
| static int AudioMaxCompression;		///< max. compression factor | ||||
| static int AudioStereoDescent;		///< volume descent for stereo | ||||
| static int AudioVolume;			///< volume (0 .. 1000) | ||||
| static int AudioVolume;			///< current volume (0 .. 1000) | ||||
|  | ||||
| extern int VideoAudioDelay;		///< import audio/video delay | ||||
|  | ||||
| @@ -752,14 +756,15 @@ static int AlsaRatio;			///< internal -> mixer ratio * 1000 | ||||
| static int AlsaPlayRingbuffer(void) | ||||
| { | ||||
|     int first; | ||||
|     int avail; | ||||
|     int n; | ||||
|     int err; | ||||
|     int frames; | ||||
|     const void *p; | ||||
|  | ||||
|     first = 1; | ||||
|     for (;;) {				// loop for ring buffer wrap | ||||
| 	int avail; | ||||
| 	int n; | ||||
| 	int err; | ||||
| 	int frames; | ||||
| 	const void *p; | ||||
|  | ||||
| 	// how many bytes can be written? | ||||
| 	n = snd_pcm_avail_update(AlsaPCMHandle); | ||||
| 	if (n < 0) { | ||||
| @@ -821,6 +826,7 @@ static int AlsaPlayRingbuffer(void) | ||||
| 	if (AudioSoftVolume && !AudioRing[AudioRingRead].UseAc3) { | ||||
| 	    // FIXME: quick&dirty cast | ||||
| 	    AudioSoftAmplifier((int16_t *) p, avail); | ||||
| 	    // FIXME: if not all are written, we double amplify them | ||||
| 	} | ||||
| 	frames = snd_pcm_bytes_to_frames(AlsaPCMHandle, avail); | ||||
|  | ||||
| @@ -1658,9 +1664,9 @@ static int64_t AlsaGetDelay(void) | ||||
| /** | ||||
| **	Setup alsa audio for requested format. | ||||
| ** | ||||
| **	@param freq	sample frequency | ||||
| **	@param channels	number of channels | ||||
| **	@param use_ac3	use ac3/pass-through device | ||||
| **	@param freq		sample frequency | ||||
| **	@param channels		number of channels | ||||
| **	@param use_ac3		use ac3/pass-through device | ||||
| ** | ||||
| **	@retval 0	everything ok | ||||
| **	@retval 1	didn't support frequency/channels combination | ||||
| @@ -2209,14 +2215,104 @@ static const AudioModule AlsaModule = { | ||||
| static int OssPcmFildes = -1;		///< pcm file descriptor | ||||
| static int OssMixerFildes = -1;		///< mixer file descriptor | ||||
| static int OssMixerChannel;		///< mixer channel index | ||||
| static RingBuffer *OssRingBuffer;	///< audio ring buffer | ||||
| static int OssFragmentTime;		///< fragment time in ms | ||||
|  | ||||
| #ifndef USE_AUDIORING | ||||
| static RingBuffer *OssRingBuffer;	///< audio ring buffer | ||||
| static unsigned OssStartThreshold;	///< start play, if filled | ||||
| #endif | ||||
|  | ||||
| #ifdef USE_AUDIO_THREAD | ||||
| static volatile char OssFlushBuffer;	///< flag empty buffer | ||||
| #endif | ||||
|  | ||||
| #ifdef USE_AUDIORING | ||||
|  | ||||
| //---------------------------------------------------------------------------- | ||||
| //	OSS pcm | ||||
| //---------------------------------------------------------------------------- | ||||
|  | ||||
| /** | ||||
| **	Play samples from ringbuffer. | ||||
| ** | ||||
| **	@retval	0	ok | ||||
| **	@retval 1	ring buffer empty | ||||
| **	@retval -1	underrun error | ||||
| */ | ||||
| static int OssPlayRingbuffer(void) | ||||
| { | ||||
|     int first; | ||||
|  | ||||
|     first = 1; | ||||
|     for (;;) { | ||||
| 	audio_buf_info bi; | ||||
| 	const void *p; | ||||
| 	int n; | ||||
|  | ||||
| 	if (ioctl(OssPcmFildes, SNDCTL_DSP_GETOSPACE, &bi) == -1) { | ||||
| 	    Error(_("audio/oss: ioctl(SNDCTL_DSP_GETOSPACE): %s\n"), | ||||
| 		strerror(errno)); | ||||
| 	    return -1; | ||||
| 	} | ||||
| 	Debug(4, "audio/oss: %d bytes free\n", bi.bytes); | ||||
|  | ||||
| 	n = RingBufferGetReadPointer(AudioRing[AudioRingRead].RingBuffer, &p); | ||||
| 	if (!n) {			// ring buffer empty | ||||
| 	    if (first) {		// only error on first loop | ||||
| 		return 1; | ||||
| 	    } | ||||
| 	    return 0; | ||||
| 	} | ||||
| 	if (n < bi.bytes) {		// not enough bytes in ring buffer | ||||
| 	    bi.bytes = n; | ||||
| 	} | ||||
| 	if (bi.bytes <= 0) {		// full or buffer empty | ||||
| 	    break;			// bi.bytes could become negative! | ||||
| 	} | ||||
|  | ||||
| 	if (AudioSoftVolume && !AudioRing[AudioRingRead].UseAc3) { | ||||
| 	    // FIXME: quick&dirty cast | ||||
| 	    AudioSoftAmplifier((int16_t *) p, bi.bytes); | ||||
| 	    // FIXME: if not all are written, we double amplify them | ||||
| 	} | ||||
| 	for (;;) { | ||||
| 	    n = write(OssPcmFildes, p, bi.bytes); | ||||
| 	    if (n != bi.bytes) { | ||||
| 		if (n < 0) { | ||||
| 		    if (n == EAGAIN) { | ||||
| 			continue; | ||||
| 		    } | ||||
| 		    Error(_("audio/oss: write error: %s\n"), strerror(errno)); | ||||
| 		    return 1; | ||||
| 		} | ||||
| 		Warning(_("audio/oss: error not all bytes written\n")); | ||||
| 	    } | ||||
| 	    break; | ||||
| 	} | ||||
| 	// advance how many could written | ||||
| 	RingBufferReadAdvance(AudioRing[AudioRingRead].RingBuffer, n); | ||||
| 	first = 0; | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /** | ||||
| **	Flush OSS buffers. | ||||
| */ | ||||
| static void OssFlushBuffers(void) | ||||
| { | ||||
|     if (OssPcmFildes != -1) { | ||||
| 	// flush kernel buffers | ||||
| 	if (ioctl(OssPcmFildes, SNDCTL_DSP_HALT_OUTPUT, NULL) < 0) { | ||||
| 	    Error(_("audio/oss: ioctl(SNDCTL_DSP_HALT_OUTPUT): %s\n"), | ||||
| 		strerror(errno)); | ||||
| 	} | ||||
|     } | ||||
| } | ||||
|  | ||||
| #else | ||||
|  | ||||
| //---------------------------------------------------------------------------- | ||||
| //	OSS pcm | ||||
| //---------------------------------------------------------------------------- | ||||
| @@ -2392,12 +2488,71 @@ static int OssUsedBytes(void) | ||||
|     return OssRingBuffer ? RingBufferUsedBytes(OssRingBuffer) : 0; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #ifdef USE_AUDIO_THREAD | ||||
|  | ||||
| //---------------------------------------------------------------------------- | ||||
| //	thread playback | ||||
| //---------------------------------------------------------------------------- | ||||
|  | ||||
| #ifdef USE_AUDIORING | ||||
|  | ||||
| /** | ||||
| **	OSS thread | ||||
| ** | ||||
| **	@retval -1	error | ||||
| **	@retval 0	underrun | ||||
| **	@retval 1	running | ||||
| */ | ||||
| static int OssThread(void) | ||||
| { | ||||
|     int err; | ||||
|  | ||||
|     if (!OssPcmFildes) { | ||||
| 	usleep(OssFragmentTime * 1000); | ||||
| 	return -1; | ||||
|     } | ||||
|     for (;;) { | ||||
| 	struct pollfd fds[1]; | ||||
|  | ||||
| 	pthread_testcancel(); | ||||
| 	if (AudioPaused) { | ||||
| 	    return 1; | ||||
| 	} | ||||
| 	// wait for space in kernel buffers | ||||
| 	fds[0].fd = OssPcmFildes; | ||||
| 	fds[0].events = POLLOUT | POLLERR; | ||||
| 	// wait for space in kernel buffers | ||||
| 	err = poll(fds, 1, OssFragmentTime); | ||||
| 	if (err < 0) { | ||||
| 	    if (err == EAGAIN) { | ||||
| 		continue; | ||||
| 	    } | ||||
| 	    Error(_("audio/oss: error poll %s\n"), strerror(errno)); | ||||
| 	    usleep(OssFragmentTime * 1000); | ||||
| 	    return -1; | ||||
| 	} | ||||
| 	break; | ||||
|     } | ||||
|     if (!err || AudioPaused) {		// timeout or some commands | ||||
| 	return 1; | ||||
|     } | ||||
|  | ||||
|     if ((err = OssPlayRingbuffer())) {	// empty / error | ||||
| 	if (err < 0) {			// underrun error | ||||
| 	    return -1; | ||||
| 	} | ||||
| 	pthread_yield(); | ||||
| 	usleep(OssFragmentTime * 1000);	// let fill/empty the buffers | ||||
| 	return 0; | ||||
|     } | ||||
|  | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| #else | ||||
|  | ||||
| /** | ||||
| **	OSS thread | ||||
| */ | ||||
| @@ -2499,6 +2654,7 @@ static void OssThreadFlushBuffers(void) | ||||
|     } | ||||
| } | ||||
|  | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| //---------------------------------------------------------------------------- | ||||
| @@ -2519,7 +2675,10 @@ static int OssOpenPCM(int use_ac3) | ||||
| 	&& !(device = AudioPCMDevice) && !(device = getenv("OSS_AUDIODEV"))) { | ||||
| 	device = "/dev/dsp"; | ||||
|     } | ||||
|     Info(_("audio/oss: using %sdevice '%s'\n"), use_ac3 ? "ac3" : "", device); | ||||
|     if (!AudioDoingInit) { | ||||
| 	Info(_("audio/oss: using %sdevice '%s'\n"), use_ac3 ? "ac3 " : "", | ||||
| 	    device); | ||||
|     } | ||||
|  | ||||
|     if ((fildes = open(device, O_WRONLY)) < 0) { | ||||
| 	Error(_("audio/oss: can't open dsp device '%s': %s\n"), device, | ||||
| @@ -2626,6 +2785,171 @@ static void OssInitMixer(void) | ||||
| //	OSS API | ||||
| //---------------------------------------------------------------------------- | ||||
|  | ||||
| #ifdef USE_AUDIORING | ||||
|  | ||||
| /** | ||||
| **	Get OSS audio delay in time stamps. | ||||
| ** | ||||
| **	@returns audio delay in time stamps. | ||||
| */ | ||||
| static int64_t OssGetDelay(void) | ||||
| { | ||||
|     int delay; | ||||
|     int64_t pts; | ||||
|  | ||||
|     // setup failure | ||||
|     if (OssPcmFildes == -1 || !AudioRing[AudioRingRead].HwSampleRate) { | ||||
| 	return 0L; | ||||
|     } | ||||
|     if (!AudioRunning) {		// audio not running | ||||
| 	Error(_("audio/oss: should not happen\n")); | ||||
| 	return 0L; | ||||
|     } | ||||
|     // delay in bytes in kernel buffers | ||||
|     delay = -1; | ||||
|     if (ioctl(OssPcmFildes, SNDCTL_DSP_GETODELAY, &delay) == -1) { | ||||
| 	Error(_("audio/oss: ioctl(SNDCTL_DSP_GETODELAY): %s\n"), | ||||
| 	    strerror(errno)); | ||||
| 	return 0L; | ||||
|     } | ||||
|     if (delay < 0) { | ||||
| 	delay = 0; | ||||
|     } | ||||
|  | ||||
|     pts = ((int64_t) delay * 90 * 1000) | ||||
| 	/ (AudioRing[AudioRingRead].HwSampleRate * | ||||
| 	AudioRing[AudioRingRead].HwChannels * AudioBytesProSample); | ||||
|  | ||||
|     return pts; | ||||
| } | ||||
|  | ||||
| /** | ||||
| **	Setup OSS audio for requested format. | ||||
| ** | ||||
| **	@param sample_rate		sample rate/frequency | ||||
| **	@param channels		number of channels | ||||
| **	@param use_ac3		use ac3/pass-through device | ||||
| ** | ||||
| **	@retval 0	everything ok | ||||
| **	@retval 1	didn't support frequency/channels combination | ||||
| **	@retval -1	something gone wrong | ||||
| */ | ||||
| static int OssSetup(int *sample_rate, int *channels, int use_ac3) | ||||
| { | ||||
|     int ret; | ||||
|     int tmp; | ||||
|     int delay; | ||||
|     audio_buf_info bi; | ||||
|  | ||||
|     if (OssPcmFildes == -1) {		// OSS not ready | ||||
| 	// FIXME: if open fails for ac3, we never recover | ||||
| 	return -1; | ||||
|     } | ||||
|  | ||||
|     if (1) {				// close+open for pcm / ac3 | ||||
| 	int fildes; | ||||
|  | ||||
| 	fildes = OssPcmFildes; | ||||
| 	OssPcmFildes = -1; | ||||
| 	close(fildes); | ||||
| 	if (!(fildes = OssOpenPCM(use_ac3))) { | ||||
| 	    return -1; | ||||
| 	} | ||||
| 	OssPcmFildes = fildes; | ||||
|     } | ||||
|  | ||||
|     ret = 0; | ||||
|  | ||||
|     tmp = AFMT_S16_NE;			// native 16 bits | ||||
|     if (ioctl(OssPcmFildes, SNDCTL_DSP_SETFMT, &tmp) == -1) { | ||||
| 	Error(_("audio/oss: ioctl(SNDCTL_DSP_SETFMT): %s\n"), strerror(errno)); | ||||
| 	// FIXME: stop player, set setup failed flag | ||||
| 	return -1; | ||||
|     } | ||||
|     if (tmp != AFMT_S16_NE) { | ||||
| 	Error(_("audio/oss: device doesn't support 16 bit sample format.\n")); | ||||
| 	// FIXME: stop player, set setup failed flag | ||||
| 	return -1; | ||||
|     } | ||||
|  | ||||
|     tmp = *channels; | ||||
|     if (ioctl(OssPcmFildes, SNDCTL_DSP_CHANNELS, &tmp) == -1) { | ||||
| 	Error(_("audio/oss: ioctl(SNDCTL_DSP_CHANNELS): %s\n"), | ||||
| 	    strerror(errno)); | ||||
| 	return -1; | ||||
|     } | ||||
|     if (tmp != *channels) { | ||||
| 	Warning(_("audio/oss: device doesn't support %d channels.\n"), | ||||
| 	    *channels); | ||||
| 	*channels = tmp; | ||||
| 	ret = 1; | ||||
|     } | ||||
|  | ||||
|     tmp = *sample_rate; | ||||
|     if (ioctl(OssPcmFildes, SNDCTL_DSP_SPEED, &tmp) == -1) { | ||||
| 	Error(_("audio/oss: ioctl(SNDCTL_DSP_SPEED): %s\n"), strerror(errno)); | ||||
| 	return -1; | ||||
|     } | ||||
|     if (tmp != *sample_rate) { | ||||
| 	Warning(_("audio/oss: device doesn't support %dHz sample rate.\n"), | ||||
| 	    *sample_rate); | ||||
| 	*sample_rate = tmp; | ||||
| 	ret = 1; | ||||
|     } | ||||
| #ifdef SNDCTL_DSP_POLICY | ||||
|     tmp = 3; | ||||
|     if (ioctl(OssPcmFildes, SNDCTL_DSP_POLICY, &tmp) == -1) { | ||||
| 	Error(_("audio/oss: ioctl(SNDCTL_DSP_POLICY): %s\n"), strerror(errno)); | ||||
|     } else { | ||||
| 	Info("audio/oss: set policy to %d\n", tmp); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     if (ioctl(OssPcmFildes, SNDCTL_DSP_GETOSPACE, &bi) == -1) { | ||||
| 	Error(_("audio/oss: ioctl(SNDCTL_DSP_GETOSPACE): %s\n"), | ||||
| 	    strerror(errno)); | ||||
| 	bi.fragsize = 4096; | ||||
| 	bi.fragstotal = 16; | ||||
|     } else { | ||||
| 	Debug(3, "audio/oss: %d bytes buffered\n", bi.bytes); | ||||
|     } | ||||
|  | ||||
|     OssFragmentTime = (bi.fragsize * 1000) | ||||
| 	/ (*sample_rate * *channels * AudioBytesProSample); | ||||
|  | ||||
|     Debug(3, "audio/oss: buffer size %d %dms, fragment size %d %dms\n", | ||||
| 	bi.fragsize * bi.fragstotal, (bi.fragsize * bi.fragstotal * 1000) | ||||
| 	/ (*sample_rate * *channels * AudioBytesProSample), bi.fragsize, | ||||
| 	OssFragmentTime); | ||||
|  | ||||
|     // start when enough bytes for initial write | ||||
|     AudioStartThreshold = (bi.fragsize - 1) * bi.fragstotal; | ||||
|  | ||||
|     // buffer time/delay in ms | ||||
|     delay = AudioBufferTime + 300; | ||||
|     if (VideoAudioDelay > 0) { | ||||
| 	delay += VideoAudioDelay / 90; | ||||
|     } | ||||
|     if (AudioStartThreshold < | ||||
| 	(*sample_rate * *channels * AudioBytesProSample * delay) / 1000U) { | ||||
| 	AudioStartThreshold = | ||||
| 	    (*sample_rate * *channels * AudioBytesProSample * delay) / 1000U; | ||||
|     } | ||||
|     // no bigger, than 1/3 the buffer | ||||
|     if (AudioStartThreshold > AudioRingBufferSize / 3) { | ||||
| 	AudioStartThreshold = AudioRingBufferSize / 3; | ||||
|     } | ||||
|  | ||||
|     if (!AudioDoingInit) { | ||||
| 	Info(_("audio/oss: delay %ums\n"), (AudioStartThreshold * 1000) | ||||
| 	    / (*sample_rate * *channels * AudioBytesProSample)); | ||||
|     } | ||||
|  | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| #else | ||||
|  | ||||
| /** | ||||
| **	Get OSS audio delay in time stamps. | ||||
| ** | ||||
| @@ -2795,6 +3119,8 @@ static int OssSetup(int *freq, int *channels, int use_ac3) | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| /** | ||||
| **	Play audio. | ||||
| */ | ||||
| @@ -2814,7 +3140,9 @@ void OssPause(void) | ||||
| */ | ||||
| static void OssInit(void) | ||||
| { | ||||
| #ifndef USE_AUDIORING | ||||
|     OssRingBuffer = RingBufferNew(AudioRingBufferSize); | ||||
| #endif | ||||
|  | ||||
|     OssInitPCM(); | ||||
|     OssInitMixer(); | ||||
| @@ -2843,17 +3171,25 @@ static const AudioModule OssModule = { | ||||
|     .Name = "oss", | ||||
| #ifdef USE_AUDIO_THREAD | ||||
|     .Thread = OssThread, | ||||
| #ifdef USE_AUDIORING | ||||
|     //.Enqueue = OssThreadEnqueue, | ||||
|     //.VideoReady = OssVideoReady, | ||||
|     .FlushBuffers = OssFlushBuffers, | ||||
| #else | ||||
|     .Enqueue = OssThreadEnqueue, | ||||
|     .VideoReady = OssVideoReady, | ||||
|     .FlushBuffers = OssThreadFlushBuffers, | ||||
| #endif | ||||
| #else | ||||
|     .Enqueue = OssEnqueue, | ||||
|     .VideoReady = OssVideoReady, | ||||
|     .FlushBuffers = OssFlushBuffers, | ||||
| #endif | ||||
| #ifndef USE_AUDIORING | ||||
|     .Poller = OssPoller, | ||||
|     .FreeBytes = OssFreeBytes, | ||||
|     .UsedBytes = OssUsedBytes, | ||||
| #endif | ||||
|     .GetDelay = OssGetDelay, | ||||
|     .SetVolume = OssSetVolume, | ||||
|     .Setup = OssSetup, | ||||
| @@ -2869,6 +3205,8 @@ static const AudioModule OssModule = { | ||||
| //	Noop | ||||
| //============================================================================ | ||||
|  | ||||
| #ifndef USE_AUDIORING | ||||
|  | ||||
| /** | ||||
| **	Noop enqueue samples. | ||||
| ** | ||||
| @@ -2897,6 +3235,8 @@ static int NoopUsedBytes(void) | ||||
|     return 0;				// no driver, nothing used | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| /** | ||||
| **	Get audio delay in time stamps. | ||||
| ** | ||||
| @@ -2943,12 +3283,16 @@ static void NoopVoid(void) | ||||
| */ | ||||
| static const AudioModule NoopModule = { | ||||
|     .Name = "noop", | ||||
| #ifndef USE_AUDIORING | ||||
|     .Enqueue = NoopEnqueue, | ||||
|     .VideoReady = NoopVoid, | ||||
| #endif | ||||
|     .FlushBuffers = NoopVoid, | ||||
| #ifndef USE_AUDIORING | ||||
|     .Poller = NoopVoid, | ||||
|     .FreeBytes = NoopFreeBytes, | ||||
|     .UsedBytes = NoopUsedBytes, | ||||
| #endif | ||||
|     .GetDelay = NoopGetDelay, | ||||
|     .SetVolume = NoopSetVolume, | ||||
|     .Setup = NoopSetup, | ||||
| @@ -3388,7 +3732,9 @@ void AudioFlushBuffers(void) | ||||
| */ | ||||
| void AudioPoller(void) | ||||
| { | ||||
| #ifndef USE_AUDIORING | ||||
|     AudioUsedModule->Poller(); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
		Reference in New Issue
	
	Block a user