示例#1
0
AudioAlsa::AudioAlsa( bool & _success_ful, Mixer*  _mixer ) :
	AudioDevice( tLimit<ch_cnt_t>(
		ConfigManager::inst()->value( "audioalsa", "channels" ).toInt(),
					DEFAULT_CHANNELS, SURROUND_CHANNELS ),
								_mixer ),
	m_handle( NULL ),
	m_hwParams( NULL ),
	m_swParams( NULL ),
	m_convertEndian( false )
{
	_success_ful = false;

	int err;

	if( ( err = snd_pcm_open( &m_handle,
					probeDevice().toLatin1().constData(),
						SND_PCM_STREAM_PLAYBACK,
						0 ) ) < 0 )
	{
		printf( "Playback open error: %s\n", snd_strerror( err ) );
		return;
	}

	snd_pcm_hw_params_malloc( &m_hwParams );
	snd_pcm_sw_params_malloc( &m_swParams );

	if( ( err = setHWParams( channels(),
					SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 )
	{
		printf( "Setting of hwparams failed: %s\n",
							snd_strerror( err ) );
		return;
	}
	if( ( err = setSWParams() ) < 0 )
	{
		printf( "Setting of swparams failed: %s\n",
							snd_strerror( err ) );
		return;
	}

	// set FD_CLOEXEC flag for all file descriptors so forked processes
	// do not inherit them
	struct pollfd * ufds;
	int count = snd_pcm_poll_descriptors_count( m_handle );
	ufds = new pollfd[count];
	snd_pcm_poll_descriptors( m_handle, ufds, count );
	for( int i = 0; i < qMax( 3, count ); ++i )
	{
		const int fd = ( i >= count ) ? ufds[0].fd+i : ufds[i].fd;
		int oldflags = fcntl( fd, F_GETFD, 0 );
		if( oldflags < 0 )
			continue;
		oldflags |= FD_CLOEXEC;
		fcntl( fd, F_SETFD, oldflags );
	}
	delete[] ufds;
	_success_ful = true;
}
示例#2
0
文件: AudioAlsa.cpp 项目: uro5h/lmms
void AudioAlsa::applyQualitySettings()
{
	if( hqAudio() )
	{
		setSampleRate( Engine::mixer()->processingSampleRate() );

		if( m_handle != NULL )
		{
			snd_pcm_close( m_handle );
		}

		int err;
		if( ( err = snd_pcm_open( &m_handle,
					probeDevice().toLatin1().constData(),
						SND_PCM_STREAM_PLAYBACK,
								0 ) ) < 0 )
		{
			printf( "Playback open error: %s\n",
							snd_strerror( err ) );
			return;
		}

		if( ( err = setHWParams( channels(),
					SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 )
		{
			printf( "Setting of hwparams failed: %s\n",
							snd_strerror( err ) );
			return;
		}
		if( ( err = setSWParams() ) < 0 )
		{
			printf( "Setting of swparams failed: %s\n",
							snd_strerror( err ) );
			return;
		}
	}

	AudioDevice::applyQualitySettings();
}
void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource,
                  int encoding, float sampleRate, int sampleSizeInBits,
                  int frameSize, int channels,
                  int isSigned, int isBigEndian, int bufferSizeInBytes) {
    snd_pcm_format_mask_t* formatMask;
    snd_pcm_format_t format;
    int dir;
    int ret = 0;
    AlsaPcmInfo* info = NULL;
    /* snd_pcm_uframes_t is 64 bit on 64-bit systems */
    snd_pcm_uframes_t alsaPeriodSize = 0;
    snd_pcm_uframes_t alsaBufferSizeInFrames = 0;


    TRACE0("> DAUDIO_Open\n");
#ifdef USE_TRACE
    // for using ALSA debug dump methods
    if (ALSA_OUTPUT == NULL) {
        snd_output_stdio_attach(&ALSA_OUTPUT, stdout, 0);
    }
#endif

    info = (AlsaPcmInfo*) malloc(sizeof(AlsaPcmInfo));
    if (!info) {
        ERROR0("Out of memory\n");
        return NULL;
    }
    memset(info, 0, sizeof(AlsaPcmInfo));

    ret = openPCMfromDeviceID(deviceID, &(info->handle), isSource, FALSE /* do open device*/);
    if (ret == 0) {
        // set to blocking mode
        snd_pcm_nonblock(info->handle, 0);
        ret = snd_pcm_hw_params_malloc(&(info->hwParams));
        if (ret != 0) {
            ERROR1("  snd_pcm_hw_params_malloc returned error %d\n", ret);
        } else {
            ret = -1;
            if (getAlsaFormatFromFormat(&format, frameSize / channels, sampleSizeInBits,
                                        isSigned, isBigEndian, encoding)) {
                if (setHWParams(info,
                                sampleRate,
                                channels,
                                bufferSizeInBytes / frameSize,
                                format)) {
                    info->frameSize = frameSize;
#ifdef ALSA_PCM_NEW_HW_PARAMS_API
                    ret = snd_pcm_hw_params_get_period_size(info->hwParams, &alsaPeriodSize, &dir);
                    info->periodSize = (int) alsaPeriodSize;
                    if (ret < 0) {
                        ERROR1("ERROR: snd_pcm_hw_params_get_period: %s\n", snd_strerror(ret));
                    }
                    snd_pcm_hw_params_get_periods(info->hwParams, &(info->periods), &dir);
                    snd_pcm_hw_params_get_buffer_size(info->hwParams, &alsaBufferSizeInFrames);
                    info->bufferSizeInBytes = (int) alsaBufferSizeInFrames * frameSize;
#else
                    info->periodSize = snd_pcm_hw_params_get_period_size(info->hwParams, &dir);
                    info->periods = snd_pcm_hw_params_get_periods(info->hwParams, &dir);
                    info->bufferSizeInBytes = snd_pcm_hw_params_get_buffer_size(info->hwParams) * frameSize;
                    ret = 0;
#endif
                    TRACE3("  DAUDIO_Open: period size = %d frames, periods = %d. Buffer size: %d bytes.\n",
                           (int) info->periodSize, info->periods, info->bufferSizeInBytes);
                }
            }
        }
        if (ret == 0) {
            // set software parameters
            ret = snd_pcm_sw_params_malloc(&(info->swParams));
            if (ret != 0) {
                ERROR1("snd_pcm_hw_params_malloc returned error %d\n", ret);
            } else {
                if (!setSWParams(info)) {
                    ret = -1;
                }
            }
        }
        if (ret == 0) {
            // prepare device
            ret = snd_pcm_prepare(info->handle);
            if (ret < 0) {
                ERROR1("ERROR: snd_pcm_prepare: %s\n", snd_strerror(ret));
            }
        }

#ifdef GET_POSITION_METHOD2
        if (ret == 0) {
            ret = snd_pcm_status_malloc(&(info->positionStatus));
            if (ret != 0) {
                ERROR1("ERROR in snd_pcm_status_malloc: %s\n", snd_strerror(ret));
            }
        }
#endif
    }
    if (ret != 0) {
        DAUDIO_Close((void*) info, isSource);
        info = NULL;
    } else {
        // set to non-blocking mode
        snd_pcm_nonblock(info->handle, 1);
        TRACE1("< DAUDIO_Open: Opened device successfully. Handle=%p\n",
               (void*) info->handle);
    }
    return (void*) info;
}