예제 #1
0
파일: pcm_qsa.c 프로젝트: BaJIeK/brltty
void
awaitPcmOutput (PcmDevice *pcm) {
    int code;
    if ((code = snd_pcm_playback_flush(pcm->handle)) < 0) {
        logPcmError(LOG_WARNING, "flush", code);
    }
}
예제 #2
0
파일: qsa.c 프로젝트: Atom66/tain335
static void flush_qsa(audio_output_t* ao)
{
    qsa_internal_t* userptr;

    userptr=ao->userptr;
    if (userptr!=NULL);
    {
        snd_pcm_playback_flush(userptr->audio_handle);
    }
}
예제 #3
0
파일: alsapmo.cpp 프로젝트: mayhem/freeamp
Error AlsaPMO::Reset(bool user_stop) {

    if (user_stop) 
        snd_pcm_playback_drain(m_handle);
    else
        snd_pcm_playback_flush(m_handle);

    snd_pcm_playback_prepare(m_handle);

    return kError_NoErr;
}
static void *processTones(void *dummy)
{
    bool done;
    int error;
    int length;
    int index;
    Tone *tone, *nextTone;
    snd_pcm_channel_status_t status;


    //pthread_setname_np(pthread_self(), "tonegen");

    // Main loop. Wait for audio driver to need more data
    while( live ) {
        pthread_mutex_lock( &toneMutex );
        if( tone_count == 0 ) {
            // Wait for a tone command to come in
            snd_pcm_playback_flush( playback_handle );
            snd_pcm_plugin_prepare( playback_handle, SND_PCM_CHANNEL_PLAYBACK );

            pthread_cond_wait( &condvar_newtone, &toneMutex );
        }
        if( tone_count == 0 ) {
            pthread_mutex_unlock( &toneMutex );
            continue;
        }
        pthread_mutex_unlock( &toneMutex );

        // Send tone data
        FD_ZERO( &write_handles );
        FD_SET( sample_handle, &write_handles );
        error = select(sample_handle + 1, NULL, &write_handles, NULL, NULL);

        if( error < 0 ) {
            // Select failed.
            slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "processTones select failed %d (%d)\n", error, errno);
            pthread_mutex_unlock( &toneMutex );
            live = DEAD;
            break;
        }

        length = 0;

        // This should always be true
        if( FD_ISSET( sample_handle, &write_handles ) ) {
        	int active_count = 0;
        	for(tone = tones; tone != NULL; tone = tone->next) {
                done = tone->killed || (tonepos > tone->end);
    			//fprintf (stderr,"processTone::writeTone (before active check) tone %ld tone->end %ld active %d done %d tonepos %ld \n", tone, tone->end, tone->active, done, tonepos);
                if( !done ) {
                    // Write the tone
                    error = writeTone(tone, (tone != tones));
                    //error = tone->generator(tone->position, length, sample_frequency, frag_buffer, &tone->data, terminating);
                    if( error != EOK ) {
                        done = true;
                    }
                    active_count++;
                }

                tone->active &= !done;
    			//fprintf (stderr,"processTone::writeTone tone %ld tone->end %ld active %d tonepos %ld \n", tone, tone->end, tone->active, tonepos);
        	}

        	for(index = 0; index < frag_samples; index++) {
        		record_buffer[index*2  ] = stage_buffer[index] / stage_samples[index];
        		record_buffer[index*2+1] = stage_buffer[index] / stage_samples[index];
        	}

        	pthread_mutex_lock(&fillMutex);

        	if (render_buffer != NULL) {
        		memcpy(render_buffer, record_buffer, frame_size);
        	}

        	pthread_mutex_unlock(&fillMutex);

			tonepos += frag_samples;

			if (active_count > 0) {
				fprintf (stderr,"processTone tonepos %ld \n", tonepos);

				error = snd_pcm_plugin_write (playback_handle, record_buffer, frame_size);
				if( error != frame_size ) {
				   memset (&status, 0, sizeof (status));
					status.channel = SND_PCM_CHANNEL_PLAYBACK;
					if ((error = snd_pcm_plugin_status (playback_handle, &status)) < 0)
					{
						slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "retrieving audio interface status failed (%s)\n", snd_strerror (error));
					} else if (status.status == SND_PCM_STATUS_READY ||
							   status.status == SND_PCM_STATUS_UNDERRUN ||
							   status.status == SND_PCM_STATUS_CHANGE)
					{
						if ((error = snd_pcm_plugin_prepare (playback_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0) {
							slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "cannot prepare audio interface for use (%s)\n", snd_strerror (error));
						}
					} else {
						slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "non-underrun write failure (%s)\n", snd_strerror (error));
					}
					// Retry now that we're prepared
					error = snd_pcm_plugin_write (playback_handle, record_buffer, frame_size);
				}
				if( error != frame_size ) {
					slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "write to audio interface failed (%s) %d\n", snd_strerror (error), error);
				}
			}

        } else {
            slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unknown file handle activated" );
        }

		pthread_mutex_lock( &toneMutex );


		//fprintf (stderr,"processTone::delete tones %lx count %d \n", tones, tone_count);

        int delete_count;
        do {
        	delete_count = 0;
			for(tone = tones; tone != NULL; tone = tone->next) {
				done = tone->killed || (tonepos > tone->end);
				if( done || !tone->active ) {
					// Remove the tone from the list
					if (tone->prev != NULL) {
						tone->prev->next = tone->next;
					} else {
						tones = tone->next;
					}
					if (tone->next != NULL) {
						tone->next->prev = tone->prev;
					}

					tone_count--;

					free(tone);

					delete_count++;

					fprintf (stderr,"processTone::delete tone %lx tones %lx count %d \n", tone, tones, tone_count);

					break;
				}
			}
        } while (delete_count > 0);

		pthread_mutex_unlock( &toneMutex );

        if (tone_count == 0) {
        	memset(record_buffer, 0, frame_size);
        }
    }

    return NULL;
}