// gather list of supported devices // (currently, we rely on proper BIOS detection, which // only works for primary graphics adapter, so multiple // devices won't really work) void Radeon_ProbeDevices( void ) { uint32 pci_index = 0; uint32 count = 0; device_info *di = devices->di; while( count < MAX_DEVICES ) { memset( di, 0, sizeof( *di )); if( (*pci_bus->get_nth_pci_info)(pci_index, &(di->pcii)) != B_NO_ERROR) break; if( probeDevice( di )) { devices->device_names[2*count] = di->name; devices->device_names[2*count+1] = di->video_name; di++; count++; } pci_index++; } devices->count = count; devices->device_names[2*count] = NULL; SHOW_INFO( 0, "%ld supported devices", count ); }
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; }
MidiOss::MidiOss() : MidiClientRaw(), m_midiDev( probeDevice() ), m_quit( false ) { // only start thread, if opening of MIDI-device is successful, // otherwise isRunning()==false indicates error if( m_midiDev.open( QIODevice::ReadWrite ) || m_midiDev.open( QIODevice::ReadOnly ) ) { start( QThread::LowPriority ); } }
MidiAlsaSeq::MidiAlsaSeq() : MidiClient(), m_seqMutex(), m_seqHandle( NULL ), m_queueID( -1 ), m_quit( false ), m_portListUpdateTimer( this ) { int err; if( ( err = snd_seq_open( &m_seqHandle, probeDevice().toLatin1().constData(), SND_SEQ_OPEN_DUPLEX, 0 ) ) < 0 ) { fprintf( stderr, "cannot open sequencer: %s\n", snd_strerror( err ) ); return; } snd_seq_set_client_name( m_seqHandle, "LMMS" ); m_queueID = snd_seq_alloc_queue( m_seqHandle ); snd_seq_queue_tempo_t * tempo; snd_seq_queue_tempo_malloc( &tempo ); snd_seq_queue_tempo_set_tempo( tempo, 6000000 / Engine::getSong()->getTempo() ); snd_seq_queue_tempo_set_ppq( tempo, 16 ); snd_seq_set_queue_tempo( m_seqHandle, m_queueID, tempo ); snd_seq_queue_tempo_free( tempo ); snd_seq_start_queue( m_seqHandle, m_queueID, NULL ); changeQueueTempo( Engine::getSong()->getTempo() ); connect( Engine::getSong(), SIGNAL( tempoChanged( bpm_t ) ), this, SLOT( changeQueueTempo( bpm_t ) ) ); // initial list-update updatePortList(); connect( &m_portListUpdateTimer, SIGNAL( timeout() ), this, SLOT( updatePortList() ) ); // we check for port-changes every second m_portListUpdateTimer.start( 1000 ); // use a pipe to detect shutdown if( pipe( m_pipe ) == -1 ) { perror( __FILE__ ": pipe" ); } start( QThread::IdlePriority ); }
MidiJack::MidiJack() : MidiClientRaw(), m_input_port( NULL ), m_output_port( NULL ), m_quit( false ) { // if jack is used for audio then we share the connection // AudioJack creates and maintains the jack connection // and also handles the callback, we pass it our address // so that we can also process during the callback if(Engine::mixer()->audioDevName() == AudioJack::name() ) { // if a jack connection has been created for audio we use that m_jackAudio = dynamic_cast<AudioJack*>(Engine::mixer()->audioDev())->addMidiClient(this); }else{ m_jackAudio = NULL; m_jackClient = jack_client_open(probeDevice().toLatin1().data(), JackNoStartServer, NULL); if(m_jackClient) { jack_set_process_callback(m_jackClient, JackMidiProcessCallback, this); jack_on_shutdown(m_jackClient, JackMidiShutdown, 0); } } if(jackClient()) { /* jack midi out not implemented JackMidiWrite and sendByte needs to be functional before enabling this m_output_port = jack_port_register( jackClient(), "MIDI out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); */ m_input_port = jack_port_register( jackClient(), "MIDI in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); if(jack_activate(jackClient()) == 0 ) { // only start thread, if we have an active jack client. start( QThread::LowPriority ); } } }
AudioOss::setupWidget::setupWidget( QWidget * _parent ) : AudioDeviceSetupWidget( AudioOss::name(), _parent ) { m_device = new QLineEdit( probeDevice(), this ); m_device->setGeometry( 10, 20, 160, 20 ); QLabel * dev_lbl = new QLabel( tr( "Device" ), this ); dev_lbl->setFont( pointSize<7>( dev_lbl->font() ) ); dev_lbl->setGeometry( 10, 40, 160, 10 ); LcdSpinBoxModel * m = new LcdSpinBoxModel( /* this */ ); m->setRange( DEFAULT_CHANNELS, SURROUND_CHANNELS ); m->setStep( 2 ); m->setValue( ConfigManager::inst()->value( "audiooss", "channels" ).toInt() ); m_channels = new LcdSpinBox( 1, this ); m_channels->setModel( m ); m_channels->setLabel( tr( "Channels" ) ); m_channels->move( 180, 20 ); }
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(); }
MidiSndio::MidiSndio( void ) : MidiClientRaw(), m_quit( false ) { QString dev = probeDevice(); if (dev == "") { m_hdl = mio_open( NULL, MIO_IN | MIO_OUT, 0 ); } else { m_hdl = mio_open( dev.toLatin1().constData(), MIO_IN | MIO_OUT, 0 ); } if( m_hdl == NULL ) { printf( "sndio: failed opening sndio midi device\n" ); return; } start( QThread::LowPriority ); }
MidiAlsaRaw::MidiAlsaRaw() : MidiClientRaw(), m_inputp( &m_input ), m_outputp( &m_output ), m_quit( false ) { int err; if( ( err = snd_rawmidi_open( m_inputp, m_outputp, probeDevice().toLatin1().constData(), 0 ) ) < 0 ) { printf( "cannot open MIDI-device: %s\n", snd_strerror( err ) ); return; } snd_rawmidi_read( m_input, NULL, 0 ); snd_rawmidi_nonblock( m_input, 1 ); m_npfds = snd_rawmidi_poll_descriptors_count( m_input ); m_pfds = new pollfd[m_npfds]; snd_rawmidi_poll_descriptors( m_input, m_pfds, m_npfds ); start( QThread::LowPriority ); }
AudioOss::AudioOss( bool & _success_ful, Mixer* _mixer ) : AudioDevice( tLimit<ch_cnt_t>( ConfigManager::inst()->value( "audiooss", "channels" ).toInt(), DEFAULT_CHANNELS, SURROUND_CHANNELS ), _mixer ), m_convertEndian( false ) { _success_ful = false; m_audioFD = open( probeDevice().toLatin1().constData(), O_WRONLY, 0 ); if( m_audioFD == -1 ) { printf( "AudioOss: failed opening audio-device\n" ); return; } // Make the file descriptor use blocking writes with fcntl() if ( fcntl( m_audioFD, F_SETFL, fcntl( m_audioFD, F_GETFL ) & ~O_NONBLOCK ) < 0 ) { printf( "could not set audio blocking mode\n" ); return; } // set FD_CLOEXEC flag for file descriptor so forked processes // do not inherit it fcntl( m_audioFD, F_SETFD, fcntl( m_audioFD, F_GETFD ) | FD_CLOEXEC ); int frag_spec; for( frag_spec = 0; static_cast<int>( 0x01 << frag_spec ) < mixer()->framesPerPeriod() * channels() * BYTES_PER_INT_SAMPLE; ++frag_spec ) { } frag_spec |= 0x00020000; // two fragments, for low latency if ( ioctl( m_audioFD, SNDCTL_DSP_SETFRAGMENT, &frag_spec ) < 0 ) { perror( "SNDCTL_DSP_SETFRAGMENT" ); printf( "Warning: Couldn't set audio fragment size\n" ); } unsigned int value; // Get a list of supported hardware formats if ( ioctl( m_audioFD, SNDCTL_DSP_GETFMTS, &value ) < 0 ) { perror( "SNDCTL_DSP_GETFMTS" ); printf( "Couldn't get audio format list\n" ); return; } // Set the audio format if( value & AFMT_S16_LE ) { value = AFMT_S16_LE; } else if( value & AFMT_S16_BE ) { value = AFMT_S16_BE; } else { printf(" Soundcard doesn't support signed 16-bit-data\n"); } if ( ioctl( m_audioFD, SNDCTL_DSP_SETFMT, &value ) < 0 ) { perror( "SNDCTL_DSP_SETFMT" ); printf( "Couldn't set audio format\n" ); return; } if( ( isLittleEndian() && ( value == AFMT_S16_BE ) ) || ( !isLittleEndian() && ( value == AFMT_S16_LE ) ) ) { m_convertEndian = true; } // Set the number of channels of output value = channels(); if ( ioctl( m_audioFD, SNDCTL_DSP_CHANNELS, &value ) < 0 ) { perror( "SNDCTL_DSP_CHANNELS" ); printf( "Cannot set the number of channels\n" ); return; } if( value != channels() ) { printf( "Couldn't set number of channels\n" ); return; } // Set the DSP frequency value = sampleRate(); if ( ioctl( m_audioFD, SNDCTL_DSP_SPEED, &value ) < 0 ) { perror( "SNDCTL_DSP_SPEED" ); printf( "Couldn't set audio frequency\n" ); return; } if( value != sampleRate() ) { value = mixer()->baseSampleRate(); if ( ioctl( m_audioFD, SNDCTL_DSP_SPEED, &value ) < 0 ) { perror( "SNDCTL_DSP_SPEED" ); printf( "Couldn't set audio frequency\n" ); return; } setSampleRate( value ); } _success_ful = true; }