summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/audiodevice.cpp
Unidiff
Diffstat (limited to 'core/multimedia/opieplayer/audiodevice.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/audiodevice.cpp153
1 files changed, 69 insertions, 84 deletions
diff --git a/core/multimedia/opieplayer/audiodevice.cpp b/core/multimedia/opieplayer/audiodevice.cpp
index 8861015..59136af 100644
--- a/core/multimedia/opieplayer/audiodevice.cpp
+++ b/core/multimedia/opieplayer/audiodevice.cpp
@@ -17,7 +17,11 @@
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20// L.J.Potter added better error code Fri 02-15-2002 14:37:47
21
22
20#include <stdlib.h> 23#include <stdlib.h>
24#include <stdio.h>
21#include <qpe/qpeapplication.h> 25#include <qpe/qpeapplication.h>
22#include <qpe/config.h> 26#include <qpe/config.h>
23#include "audiodevice.h" 27#include "audiodevice.h"
@@ -105,17 +109,18 @@ void AudioDevice::getVolume( unsigned int& leftVolume, unsigned int& rightVolume
105 formatData.wBitsPerSample = 16; 109 formatData.wBitsPerSample = 16;
106 waveOutOpen(&handle, WAVE_MAPPER, &formatData, 0L, 0L, CALLBACK_NULL); 110 waveOutOpen(&handle, WAVE_MAPPER, &formatData, 0L, 0L, CALLBACK_NULL);
107 if ( waveOutGetVolume( handle, (LPDWORD)&volume ) ) 111 if ( waveOutGetVolume( handle, (LPDWORD)&volume ) )
108 qDebug( "get volume of audio device failed" ); 112 qDebug( "get volume of audio device failed" );
109 waveOutClose( handle ); 113 waveOutClose( handle );
110 leftVolume = volume & 0xFFFF; 114 leftVolume = volume & 0xFFFF;
111 rightVolume = volume >> 16; 115 rightVolume = volume >> 16;
112#else 116#else
113 int mixerHandle = open( "/dev/mixer", O_RDWR ); 117 int mixerHandle = open( "/dev/mixer", O_RDWR );
114 if ( mixerHandle >= 0 ) { 118 if ( mixerHandle >= 0 ) {
115 ioctl( mixerHandle, MIXER_READ(0), &volume ); 119 if(ioctl( mixerHandle, MIXER_READ(0), &volume )==-1)
120 perror("ioctl(\"MIXER_READ\")");
116 close( mixerHandle ); 121 close( mixerHandle );
117 } else 122 } else
118 qDebug( "get volume of audio device failed" ); 123 perror("open(\"/dev/mixer\")");
119 leftVolume = ((volume & 0x00FF) << 16) / 101; 124 leftVolume = ((volume & 0x00FF) << 16) / 101;
120 rightVolume = ((volume & 0xFF00) << 8) / 101; 125 rightVolume = ((volume & 0xFF00) << 8) / 101;
121#endif 126#endif
@@ -125,13 +130,13 @@ void AudioDevice::getVolume( unsigned int& leftVolume, unsigned int& rightVolume
125void AudioDevice::setVolume( unsigned int leftVolume, unsigned int rightVolume, bool muted ) { 130void AudioDevice::setVolume( unsigned int leftVolume, unsigned int rightVolume, bool muted ) {
126 AudioDevicePrivate::muted = muted; 131 AudioDevicePrivate::muted = muted;
127 if ( muted ) { 132 if ( muted ) {
128 AudioDevicePrivate::leftVolume = leftVolume; 133 AudioDevicePrivate::leftVolume = leftVolume;
129 AudioDevicePrivate::rightVolume = rightVolume; 134 AudioDevicePrivate::rightVolume = rightVolume;
130 leftVolume = 0; 135 leftVolume = 0;
131 rightVolume = 0; 136 rightVolume = 0;
132 } else { 137 } else {
133 leftVolume = ( (int) leftVolume < 0 ) ? 0 : (( leftVolume > 0xFFFF ) ? 0xFFFF : leftVolume ); 138 leftVolume = ( (int) leftVolume < 0 ) ? 0 : (( leftVolume > 0xFFFF ) ? 0xFFFF : leftVolume );
134 rightVolume = ( (int)rightVolume < 0 ) ? 0 : (( rightVolume > 0xFFFF ) ? 0xFFFF : rightVolume ); 139 rightVolume = ( (int)rightVolume < 0 ) ? 0 : (( rightVolume > 0xFFFF ) ? 0xFFFF : rightVolume );
135 } 140 }
136#ifdef Q_OS_WIN32 141#ifdef Q_OS_WIN32
137 HWAVEOUT handle; 142 HWAVEOUT handle;
@@ -146,7 +151,7 @@ void AudioDevice::setVolume( unsigned int leftVolume, unsigned int rightVolume,
146 waveOutOpen(&handle, WAVE_MAPPER, &formatData, 0L, 0L, CALLBACK_NULL); 151 waveOutOpen(&handle, WAVE_MAPPER, &formatData, 0L, 0L, CALLBACK_NULL);
147 unsigned int volume = (rightVolume << 16) | leftVolume; 152 unsigned int volume = (rightVolume << 16) | leftVolume;
148 if ( waveOutSetVolume( handle, volume ) ) 153 if ( waveOutSetVolume( handle, volume ) )
149 qDebug( "set volume of audio device failed" ); 154 qDebug( "set volume of audio device failed" );
150 waveOutClose( handle ); 155 waveOutClose( handle );
151#else 156#else
152 // Volume can be from 0 to 100 which is 101 distinct values 157 // Volume can be from 0 to 100 which is 101 distinct values
@@ -157,10 +162,12 @@ void AudioDevice::setVolume( unsigned int leftVolume, unsigned int rightVolume,
157 unsigned int volume = ((rV << 8) & 0xFF00) | (lV & 0x00FF); 162 unsigned int volume = ((rV << 8) & 0xFF00) | (lV & 0x00FF);
158 int mixerHandle = 0; 163 int mixerHandle = 0;
159 if ( ( mixerHandle = open( "/dev/mixer", O_RDWR ) ) >= 0 ) { 164 if ( ( mixerHandle = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
160 ioctl( mixerHandle, MIXER_WRITE(0), &volume ); 165 if(ioctl( mixerHandle, MIXER_WRITE(0), &volume ) ==-1)
166 perror("ioctl(\"MIXER_WRITE\")");
161 close( mixerHandle ); 167 close( mixerHandle );
162 } else 168 } else
163 qDebug( "set volume of audio device failed" ); 169 perror("open(\"/dev/mixer\")");
170
164# else 171# else
165 // This is the way this has to be done now I guess, doesn't allow for 172 // This is the way this has to be done now I guess, doesn't allow for
166 // independant right and left channel setting, or setting for different outputs 173 // independant right and left channel setting, or setting for different outputs
@@ -185,68 +192,47 @@ AudioDevice::AudioDevice( unsigned int f, unsigned int chs, unsigned int bps ) {
185 d->frequency = f; 192 d->frequency = f;
186 d->channels = chs; 193 d->channels = chs;
187 d->bytesPerSample = bps; 194 d->bytesPerSample = bps;
195 qDebug("%d",bps);
196 int format=0;
197 if( bps == 8) format = AFMT_U8;
198 else if( bps <= 0) format = AFMT_S16_LE;
199 else format = AFMT_S16_LE;
188 200
201 qDebug("AD- freq %d, channels %d, b/sample %d, bitrate %d",f,chs,bps,format);
189 connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( volumeChanged(bool) ) ); 202 connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( volumeChanged(bool) ) );
190 203
191#ifdef Q_OS_WIN32
192 UINT result;
193 WAVEFORMATEX formatData;
194 formatData.cbSize = sizeof(WAVEFORMATEX);
195/*
196 // Other possible formats windows supports
197 formatData.wFormatTag = WAVE_FORMAT_MPEG;
198 formatData.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
199 formatData.wFormatTag = WAVE_FORMAT_ADPCM;
200*/
201 formatData.wFormatTag = WAVE_FORMAT_PCM;
202 formatData.nAvgBytesPerSec = bps * chs * f;
203 formatData.nBlockAlign = bps * chs;
204 formatData.nChannels = chs;
205 formatData.nSamplesPerSec = f;
206 formatData.wBitsPerSample = bps * 8;
207 // Open a waveform device for output
208 if (result = waveOutOpen((LPHWAVEOUT)&d->handle, WAVE_MAPPER, &formatData, 0L, 0L, CALLBACK_NULL)) {
209 QString errorMsg = "error opening audio device.\nReason: %i - ";
210 switch (result) {
211 case MMSYSERR_ALLOCATED:errorMsg += "Specified resource is already allocated."; break;
212 case MMSYSERR_BADDEVICEID:errorMsg += "Specified device identifier is out of range."; break;
213 case MMSYSERR_NODRIVER:errorMsg += "No device driver is present."; break;
214 case MMSYSERR_NOMEM:errorMsg += "Unable to allocate or lock memory."; break;
215 case WAVERR_BADFORMAT:errorMsg += "Attempted to open with an unsupported waveform-audio format."; break;
216 case WAVERR_SYNC: errorMsg += "The device is synchronous but waveOutOpen was called without using the WAVE_ALLOWSYNC flag."; break;
217 default: errorMsg += "Undefined error"; break;
218 }
219 qDebug( errorMsg, result );
220 }
221
222 d->bufferSize = sound_fragment_bytes;
223#else
224 204
225 int fragments = 0x10000 * 8 + sound_fragment_shift; 205 int fragments = 0x10000 * 8 + sound_fragment_shift;
226 int format = AFMT_S16_LE;
227 int capabilities = 0; 206 int capabilities = 0;
228 207
229#ifdef KEEP_DEVICE_OPEN 208#ifdef KEEP_DEVICE_OPEN
230 if ( AudioDevicePrivate::dspFd == 0 ) { 209 if ( AudioDevicePrivate::dspFd == 0 ) {
231#endif 210#endif
232 if ( ( d->handle = ::open( "/dev/dsp", O_WRONLY ) ) < 0 ) { 211 if ( ( d->handle = ::open( "/dev/dsp", O_WRONLY ) ) < 0 ) {
233 qDebug( "error opening audio device /dev/dsp, sending data to /dev/null instead" ); 212 perror("open(\"/dev/dsp\") sending to /dev/null instead");
234 d->handle = ::open( "/dev/null", O_WRONLY ); 213 d->handle = ::open( "/dev/null", O_WRONLY );
235 } 214 }
236#ifdef KEEP_DEVICE_OPEN 215#ifdef KEEP_DEVICE_OPEN
237 AudioDevicePrivate::dspFd = d->handle; 216 AudioDevicePrivate::dspFd = d->handle;
238 } else { 217 } else {
239 d->handle = AudioDevicePrivate::dspFd; 218 d->handle = AudioDevicePrivate::dspFd;
240 } 219 }
241#endif 220#endif
242 221
243 ioctl( d->handle, SNDCTL_DSP_GETCAPS, &capabilities ); 222 if(ioctl( d->handle, SNDCTL_DSP_GETCAPS, &capabilities )==-1)
244 ioctl( d->handle, SNDCTL_DSP_SETFRAGMENT, &fragments ); 223 perror("ioctl(\"SNDCTL_DSP_GETCAPS\")");
245 ioctl( d->handle, SNDCTL_DSP_SETFMT, &format ); 224 if(ioctl( d->handle, SNDCTL_DSP_SETFRAGMENT, &fragments )==-1)
246 ioctl( d->handle, SNDCTL_DSP_SPEED, &d->frequency ); 225 perror("ioctl(\"SNDCTL_DSP_SETFRAGMENT\")");
226 if(ioctl( d->handle, SNDCTL_DSP_SETFMT, & format )==-1)
227 perror("ioctl(\"SNDCTL_DSP_SETFMT\")");
228 qDebug("freq %d", d->frequency);
229 if(ioctl( d->handle, SNDCTL_DSP_SPEED, &d->frequency )==-1)
230 perror("ioctl(\"SNDCTL_DSP_SPEED\")");
231 qDebug("channels %d",d->channels);
247 if ( ioctl( d->handle, SNDCTL_DSP_CHANNELS, &d->channels ) == -1 ) { 232 if ( ioctl( d->handle, SNDCTL_DSP_CHANNELS, &d->channels ) == -1 ) {
248 d->channels = ( d->channels == 1 ) ? 2 : d->channels; 233 d->channels = ( d->channels == 1 ) ? 2 : d->channels;
249 ioctl( d->handle, SNDCTL_DSP_CHANNELS, &d->channels ); 234 if(ioctl( d->handle, SNDCTL_DSP_CHANNELS, &d->channels )==-1)
235 perror("ioctl(\"SNDCTL_DSP_CHANNELS\")");
250 } 236 }
251 237
252 d->bufferSize = sound_fragment_bytes; 238 d->bufferSize = sound_fragment_bytes;
@@ -254,13 +240,12 @@ AudioDevice::AudioDevice( unsigned int f, unsigned int chs, unsigned int bps ) {
254 d->unwritten = 0; 240 d->unwritten = 0;
255 d->can_GETOSPACE = TRUE; // until we find otherwise 241 d->can_GETOSPACE = TRUE; // until we find otherwise
256 242
257 //if ( chs != d->channels ) qDebug( "Wanted %d, got %d channels", chs, d->channels ); 243 //if ( chs != d->channels ) qDebug( "Wanted %d, got %d channels", chs, d->channels );
258 //if ( f != d->frequency ) qDebug( "wanted %dHz, got %dHz", f, d->frequency ); 244 //if ( f != d->frequency ) qDebug( "wanted %dHz, got %dHz", f, d->frequency );
259 //if ( capabilities & DSP_CAP_BATCH ) qDebug( "Sound card has local buffer" ); 245 //if ( capabilities & DSP_CAP_BATCH ) qDebug( "Sound card has local buffer" );
260 //if ( capabilities & DSP_CAP_REALTIME )qDebug( "Sound card has realtime sync" ); 246 //if ( capabilities & DSP_CAP_REALTIME )qDebug( "Sound card has realtime sync" );
261 //if ( capabilities & DSP_CAP_TRIGGER ) qDebug( "Sound card has precise trigger" ); 247 //if ( capabilities & DSP_CAP_TRIGGER ) qDebug( "Sound card has precise trigger" );
262 //if ( capabilities & DSP_CAP_MMAP ) qDebug( "Sound card can mmap" ); 248 //if ( capabilities & DSP_CAP_MMAP ) qDebug( "Sound card can mmap" );
263#endif
264} 249}
265 250
266 251
@@ -269,7 +254,7 @@ AudioDevice::~AudioDevice() {
269 waveOutClose( (HWAVEOUT)d->handle ); 254 waveOutClose( (HWAVEOUT)d->handle );
270#else 255#else
271# ifndef KEEP_DEVICE_OPEN 256# ifndef KEEP_DEVICE_OPEN
272 close( d->handle ); // Now it should be safe to shut the handle 257 close( d->handle ); // Now it should be safe to shut the handle
273# endif 258# endif
274 delete d->unwrittenBuffer; 259 delete d->unwrittenBuffer;
275 delete d; 260 delete d;
@@ -296,15 +281,15 @@ void AudioDevice::write( char *buffer, unsigned int length )
296 waveOutPrepareHeader( (HWAVEOUT)d->handle, lpWaveHdr, sizeof(WAVEHDR) ); 281 waveOutPrepareHeader( (HWAVEOUT)d->handle, lpWaveHdr, sizeof(WAVEHDR) );
297 // waveOutWrite returns immediately. the data is sent in the background. 282 // waveOutWrite returns immediately. the data is sent in the background.
298 if ( waveOutWrite( (HWAVEOUT)d->handle, lpWaveHdr, sizeof(WAVEHDR) ) ) 283 if ( waveOutWrite( (HWAVEOUT)d->handle, lpWaveHdr, sizeof(WAVEHDR) ) )
299 qDebug( "failed to write block to audio device" ); 284 qDebug( "failed to write block to audio device" );
300 // emit completedIO(); 285 // emit completedIO();
301#else 286#else
302 int t = ::write( d->handle, buffer, length ); 287 int t = ::write( d->handle, buffer, length );
303 if ( t<0 ) t = 0; 288 if ( t<0 ) t = 0;
304 if ( t != (int)length) { 289 if ( t != (int)length) {
305 qDebug("Ahhh!! memcpys 1"); 290 qDebug("Ahhh!! memcpys 1");
306 memcpy(d->unwrittenBuffer,buffer+t,length-t); 291 memcpy(d->unwrittenBuffer,buffer+t,length-t);
307 d->unwritten = length-t; 292 d->unwritten = length-t;
308 } 293 }
309#endif 294#endif
310} 295}
@@ -340,27 +325,27 @@ unsigned int AudioDevice::canWrite() const
340#else 325#else
341 audio_buf_info info; 326 audio_buf_info info;
342 if ( d->can_GETOSPACE && ioctl(d->handle,SNDCTL_DSP_GETOSPACE,&info) ) { 327 if ( d->can_GETOSPACE && ioctl(d->handle,SNDCTL_DSP_GETOSPACE,&info) ) {
343 d->can_GETOSPACE = FALSE; 328 d->can_GETOSPACE = FALSE;
344 fcntl( d->handle, F_SETFL, O_NONBLOCK ); 329 fcntl( d->handle, F_SETFL, O_NONBLOCK );
345 } 330 }
346 if ( d->can_GETOSPACE ) { 331 if ( d->can_GETOSPACE ) {
347 int t = info.fragments * sound_fragment_bytes; 332 int t = info.fragments * sound_fragment_bytes;
348 return QMIN(t,(int)bufferSize()); 333 return QMIN(t,(int)bufferSize());
349 } else { 334 } else {
350 if ( d->unwritten ) { 335 if ( d->unwritten ) {
351 int t = ::write( d->handle, d->unwrittenBuffer, d->unwritten ); 336 int t = ::write( d->handle, d->unwrittenBuffer, d->unwritten );
352 if ( t<0 ) t = 0; 337 if ( t<0 ) t = 0;
353 if ( (unsigned)t!=d->unwritten ) { 338 if ( (unsigned)t!=d->unwritten ) {
354 memcpy(d->unwrittenBuffer,d->unwrittenBuffer+t,d->unwritten-t); 339 memcpy(d->unwrittenBuffer,d->unwrittenBuffer+t,d->unwritten-t);
355 d->unwritten -= t; 340 d->unwritten -= t;
356 } else { 341 } else {
357 d->unwritten = 0; 342 d->unwritten = 0;
358 } 343 }
359 } 344 }
360 if ( d->unwritten ) 345 if ( d->unwritten )
361 return 0; 346 return 0;
362 else 347 else
363 return d->bufferSize; 348 return d->bufferSize;
364 } 349 }
365#endif 350#endif
366} 351}
@@ -370,15 +355,15 @@ int AudioDevice::bytesWritten() {
370#ifdef Q_OS_WIN32 355#ifdef Q_OS_WIN32
371 MMTIME pmmt = { TIME_BYTES, 0 }; 356 MMTIME pmmt = { TIME_BYTES, 0 };
372 if ( ( waveOutGetPosition( (HWAVEOUT)d->handle, &pmmt, sizeof(MMTIME) ) != MMSYSERR_NOERROR ) || ( pmmt.wType != TIME_BYTES ) ) { 357 if ( ( waveOutGetPosition( (HWAVEOUT)d->handle, &pmmt, sizeof(MMTIME) ) != MMSYSERR_NOERROR ) || ( pmmt.wType != TIME_BYTES ) ) {
373 qDebug( "failed to get audio device position" ); 358 qDebug( "failed to get audio device position" );
374 return -1; 359 return -1;
375 } 360 }
376 return pmmt.u.cb; 361 return pmmt.u.cb;
377#else 362#else
378 int buffered = 0; 363 int buffered = 0;
379 if ( ioctl( d->handle, SNDCTL_DSP_GETODELAY, &buffered ) ) { 364 if ( ioctl( d->handle, SNDCTL_DSP_GETODELAY, &buffered ) ) {
380 qDebug( "failed to get audio device position" ); 365 qDebug( "failed to get audio device position" );
381 return -1; 366 return -1;
382 } 367 }
383 return buffered; 368 return buffered;
384#endif 369#endif