diff options
| author | Calvin Morrison <calvin@pobox.com> | 2026-05-12 21:32:53 -0400 |
|---|---|---|
| committer | Calvin Morrison <calvin@pobox.com> | 2026-05-12 21:32:53 -0400 |
| commit | f6f7c36909fa161efe53c40e9b4c34856e751536 (patch) | |
| tree | eff44527b0be61eb2e19c9f483ed38b72879af11 /src/model/pulsedevice.cpp | |
Initial tmix skeleton — model layer + basic UI
PulseModel: stable PulseDevice objects keyed by PA index, updated
in-place via postEvent reconciliation. No bulk rebuilds. Three signals:
deviceAdded, deviceRemoved (device changed handled per-device via
volumeChanged/muteChanged/nameChanged).
MixerWindow: four-tab layout (Output/Input/Playback/Recording), adds
and removes individual DeviceWidgets in response to model signals.
Builds and links cleanly against TQt3/TDE + libpulse.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'src/model/pulsedevice.cpp')
| -rw-r--r-- | src/model/pulsedevice.cpp | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/src/model/pulsedevice.cpp b/src/model/pulsedevice.cpp new file mode 100644 index 0000000..e0f84ab --- /dev/null +++ b/src/model/pulsedevice.cpp @@ -0,0 +1,101 @@ +#include "pulsedevice.h" +#include "../ui/devicewidget.h" +#include <tqwidget.h> + +PulseDevice::PulseDevice( AudioDevice::Category cat, uint32_t paIndex, TQObject *parent ) + : AudioDevice(parent), + m_category(cat), m_paIndex(paIndex), + m_volume(0), m_muted(false), + m_context(0), m_mainloop(0) +{ +} + +void PulseDevice::setPAContext( pa_context *ctx, pa_threaded_mainloop *mainloop ) +{ + m_context = ctx; + m_mainloop = mainloop; +} + +void PulseDevice::update( const TQString &name, int volume, bool muted ) +{ + bool nameChange = ( name != m_name ); + bool volumeChange = ( volume != m_volume ); + bool muteChange = ( muted != m_muted ); + + m_name = name; + m_volume = volume; + m_muted = muted; + + if ( nameChange ) emit nameChanged( m_name ); + if ( volumeChange ) emit volumeChanged( m_volume ); + if ( muteChange ) emit muteChanged( m_muted ); +} + +// ---- write back to PA ------------------------------------------------------- + +static pa_volume_t percentToPA( int pct ) +{ + if ( pct <= 0 ) return 0; + if ( pct >= 100 ) return PA_VOLUME_NORM; + return (pa_volume_t)( (double)pct / 100.0 * PA_VOLUME_NORM + 0.5 ); +} + +void PulseDevice::setVolume( int v ) +{ + if ( !m_context ) return; + v = v < 0 ? 0 : v > 100 ? 100 : v; + + pa_cvolume cv; + pa_cvolume_set( &cv, 2, percentToPA(v) ); + + pa_threaded_mainloop_lock( m_mainloop ); + pa_operation *op = 0; + switch ( m_category ) { + case Output: + op = pa_context_set_sink_volume_by_index( m_context, m_paIndex, &cv, 0, 0 ); + break; + case Input: + op = pa_context_set_source_volume_by_index( m_context, m_paIndex, &cv, 0, 0 ); + break; + case Playback: + op = pa_context_set_sink_input_volume( m_context, m_paIndex, &cv, 0, 0 ); + break; + case Recording: + op = pa_context_set_source_output_volume( m_context, m_paIndex, &cv, 0, 0 ); + break; + } + if ( op ) pa_operation_unref( op ); + pa_threaded_mainloop_unlock( m_mainloop ); +} + +void PulseDevice::setMuted( bool m ) +{ + if ( !m_context ) return; + + pa_threaded_mainloop_lock( m_mainloop ); + pa_operation *op = 0; + int mute = m ? 1 : 0; + switch ( m_category ) { + case Output: + op = pa_context_set_sink_mute_by_index( m_context, m_paIndex, mute, 0, 0 ); + break; + case Input: + op = pa_context_set_source_mute_by_index( m_context, m_paIndex, mute, 0, 0 ); + break; + case Playback: + op = pa_context_set_sink_input_mute( m_context, m_paIndex, mute, 0, 0 ); + break; + case Recording: + op = pa_context_set_source_output_mute( m_context, m_paIndex, mute, 0, 0 ); + break; + } + if ( op ) pa_operation_unref( op ); + pa_threaded_mainloop_unlock( m_mainloop ); +} + +TQWidget *PulseDevice::createWidget( TQWidget *parent ) +{ + return new DeviceWidget( this, parent ); +} + +#include "pulsedevice.moc" |
