Index: ChangeLog =================================================================== RCS file: /sources/gap/gap/user-apps/Cynthiune/ChangeLog,v retrieving revision 1.49 diff -u -r1.49 ChangeLog --- ChangeLog 19 May 2012 20:01:10 -0000 1.49 +++ ChangeLog 20 May 2012 14:00:10 -0000 @@ -1,3 +1,16 @@ +2012-05-20 Philippe Roussel + + * Bundles/ALSA/ALSA.m + * Bundles/ALSA/ALSA.h + Device parameters need to be set when they change from one + song to another. In that case prepareDeviceWithChannels: is + called with an open device so check for pcm_handle and set + params if it's not NULL. + prepareDeviceWithChannels: is always called before openDevice + so we can handle endianness in there. + ALSA device is used by 2 threads, protect it with a lock. + 2012-05-19 Riccardo Mottola * Cynthiune.nib Index: Bundles/ALSA/ALSA.h =================================================================== RCS file: /sources/gap/gap/user-apps/Cynthiune/Bundles/ALSA/ALSA.h,v retrieving revision 1.2 diff -u -r1.2 ALSA.h --- Bundles/ALSA/ALSA.h 12 May 2012 22:29:17 -0000 1.2 +++ Bundles/ALSA/ALSA.h 20 May 2012 14:00:10 -0000 @@ -29,12 +29,13 @@ { id parentPlayer; snd_pcm_t *pcm_handle; + snd_pcm_format_t en; + NSLock *devLock; BOOL stopRequested; unsigned int channels; unsigned long rate; - Endianness endianness; unsigned char buffer[DEFAULT_BUFFER_SIZE]; } Index: Bundles/ALSA/ALSA.m =================================================================== RCS file: /sources/gap/gap/user-apps/Cynthiune/Bundles/ALSA/ALSA.m,v retrieving revision 1.2 diff -u -r1.2 ALSA.m --- Bundles/ALSA/ALSA.m 12 May 2012 22:29:17 -0000 1.2 +++ Bundles/ALSA/ALSA.m 20 May 2012 14:00:10 -0000 @@ -75,6 +75,7 @@ channels = 0; rate = 0; stopRequested = NO; + devLock = [NSLock new]; } return self; @@ -84,14 +85,6 @@ { int err; BOOL result = NO; - snd_pcm_format_t en; - - if (endianness == BigEndian) - en = SND_PCM_FORMAT_S16_BE; - else if (endianness == LittleEndian) - en = SND_PCM_FORMAT_S16_LE; - else - en = SND_PCM_FORMAT_S16; if ((err = snd_pcm_open (&pcm_handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) @@ -119,10 +112,25 @@ andRate: (unsigned long) sampleRate withEndianness: (Endianness) e { + int err; + channels = numberOfChannels; rate = sampleRate; - endianness = e; + if (e == BigEndian) + en = SND_PCM_FORMAT_S16_BE; + else if (e == LittleEndian) + en = SND_PCM_FORMAT_S16_LE; + else + en = SND_PCM_FORMAT_S16; + [devLock lock]; + if (pcm_handle) { + if ((err = snd_pcm_set_params(pcm_handle, en, + SND_PCM_ACCESS_RW_INTERLEAVED, + channels, rate, 1, 100000)) < 0) + NSLog(LOCALIZED (@"Failed to set device parameters:%s"), snd_strerror (err)); + } + [devLock unlock]; return YES; } @@ -131,6 +139,7 @@ while (stopRequested) [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.1]]; snd_pcm_close (pcm_handle); + pcm_handle = NULL; } - (void) threadLoop @@ -145,7 +154,7 @@ bufferSize = [parentPlayer readNextChunk: buffer withSize: DEFAULT_BUFFER_SIZE]; - + [devLock lock]; if (bufferSize > 0) { frames = snd_pcm_bytes_to_frames (pcm_handle, bufferSize); @@ -158,7 +167,7 @@ snd_pcm_recover (pcm_handle, written, 0); } } - + [devLock unlock]; if ([pool autoreleaseCount] > 50) [pool emptyPool]; }