~ubuntu-branches/ubuntu/hardy/lmms/hardy

« back to all changes in this revision

Viewing changes to src/midi/midi_alsa_seq.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Tobias Doerffel
  • Date: 2007-09-17 15:00:24 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070917150024-mo0zk4ks81jawqii
Tags: 0.3.0-1ubuntu1
* Resynchronized with Debian (LP: #139759, LP: #90806, LP: #102639,
  LP: #113447, LP: #121172, LP: #124890)
* reverted changes from 0.2.1-1.1ubuntu1 as upstream merged/included them

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
/*
4
4
 * midi_alsa_seq.cpp - ALSA-sequencer-client
5
5
 *
6
 
 * Copyright (c) 2005-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
 
6
 * Copyright (c) 2005-2007 Tobias Doerffel <tobydox/at/users.sourceforge.net>
7
7
 * 
8
8
 * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
9
9
 *
19
19
 *
20
20
 * You should have received a copy of the GNU General Public
21
21
 * License along with this program (see COPYING); if not, write to the
22
 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23
 
 * Boston, MA 02111-1307, USA.
 
22
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
23
 * Boston, MA 02110-1301 USA.
24
24
 *
25
25
 */
26
26
 
43
43
 
44
44
#include "midi_alsa_seq.h"
45
45
#include "config_mgr.h"
 
46
#include "engine.h"
46
47
#include "gui_templates.h"
47
48
#include "song_editor.h"
48
49
#include "midi_port.h"
52
53
#ifdef ALSA_SUPPORT
53
54
 
54
55
 
55
 
midiALSASeq::midiALSASeq( engine * _engine ) :
56
 
#ifndef QT4
57
 
        QObject(),
58
 
#endif
59
 
        midiClient( _engine ),
60
 
        QThread(),
 
56
midiALSASeq::midiALSASeq( void ) :
61
57
        m_seqHandle( NULL ),
62
58
        m_queueID( -1 ),
63
59
        m_quit( FALSE ),
64
 
        m_portListUpdateTimer( this ),
65
 
        m_readablePorts(),
66
 
        m_writeablePorts()
 
60
        m_portListUpdateTimer( this )
67
61
{
68
62
        int err;
69
63
        if( ( err = snd_seq_open( &m_seqHandle,
84
78
        snd_seq_queue_tempo_t * tempo;
85
79
        snd_seq_queue_tempo_alloca( &tempo );
86
80
        snd_seq_queue_tempo_set_tempo( tempo, 6000000 /
87
 
                                        eng()->getSongEditor()->getTempo() );
 
81
                                        engine::getSongEditor()->getTempo() );
88
82
        snd_seq_queue_tempo_set_ppq( tempo, 16 );
89
83
        snd_seq_set_queue_tempo( m_seqHandle, m_queueID, tempo );
90
84
 
91
85
        snd_seq_start_queue( m_seqHandle, m_queueID, NULL );
92
 
        changeQueueTempo( eng()->getSongEditor()->getTempo() );
93
 
        connect( eng()->getSongEditor(), SIGNAL( tempoChanged( bpm_t ) ),
 
86
        changeQueueTempo( engine::getSongEditor()->getTempo() );
 
87
        connect( engine::getSongEditor(), SIGNAL( tempoChanged( bpm_t ) ),
94
88
                        this, SLOT( changeQueueTempo( bpm_t ) ) );
95
89
 
96
90
        // initial list-update
101
95
        // we check for port-changes every second
102
96
        m_portListUpdateTimer.start( 1000 );
103
97
 
 
98
        // use a pipe to detect shutdown
 
99
        if( pipe( m_pipe ) == -1 )
 
100
        {
 
101
                perror( __FILE__ ": pipe" );
 
102
        }
 
103
 
104
104
        start( 
105
105
#if QT_VERSION >= 0x030505
106
106
                QThread::IdlePriority 
116
116
        if( isRunning() )
117
117
        {
118
118
                m_quit = TRUE;
 
119
                // wake up input queue
 
120
                write( m_pipe[1], "\n", 1 );
119
121
                wait( 1000 );
120
 
                terminate();
121
122
 
122
123
                snd_seq_stop_queue( m_seqHandle, m_queueID, NULL );
123
124
                snd_seq_free_queue( m_seqHandle, m_queueID );
185
186
                                                _me.velocity() );
186
187
                        break;
187
188
 
188
 
                case PITCH_BEND:
189
 
                        snd_seq_ev_set_pitchbend( &ev,
 
189
                case CONTROL_CHANGE:
 
190
                        snd_seq_ev_set_controller( &ev,
190
191
                                                _port->outputChannel(),
191
 
                                                _me.m_data.m_param[0] - 8192 );
 
192
                                                _me.m_data.m_param[0],
 
193
                                                _me.m_data.m_param[1] );
192
194
                        break;
193
195
 
194
196
                case PROGRAM_CHANGE:
203
205
                                                _me.m_data.m_param[0] );
204
206
                        break;
205
207
 
 
208
                case PITCH_BEND:
 
209
                        snd_seq_ev_set_pitchbend( &ev,
 
210
                                                _port->outputChannel(),
 
211
                                                _me.m_data.m_param[0] - 8192 );
 
212
                        break;
 
213
 
206
214
                default:
207
215
                        printf( "ALSA-sequencer: unhandled output event %d\n",
208
216
                                                        (int) _me.m_type );
437
445
 
438
446
void midiALSASeq::run( void )
439
447
{
 
448
        // watch the pipe and sequencer input events
 
449
        int pollfd_count = snd_seq_poll_descriptors_count( m_seqHandle,
 
450
                                                                POLLIN );
 
451
        struct pollfd * pollfd_set = new struct pollfd[pollfd_count + 1];
 
452
        snd_seq_poll_descriptors( m_seqHandle, pollfd_set + 1, pollfd_count,
 
453
                                                                POLLIN );
 
454
        pollfd_set[0].fd = m_pipe[0];
 
455
        pollfd_set[0].events = POLLIN;
 
456
        ++pollfd_count;
 
457
 
440
458
        while( m_quit == FALSE )
441
459
        {
 
460
                if( poll( pollfd_set, pollfd_count, -1 ) == -1 )
 
461
                {
 
462
                        // gdb may interrupt the poll
 
463
                        if( errno == EINTR )
 
464
                        {
 
465
                                continue;
 
466
                        }
 
467
                        perror( __FILE__ ": poll" );
 
468
                }
 
469
                // shutdown?
 
470
                if( pollfd_set[0].revents )
 
471
                {
 
472
                        break;
 
473
                }
442
474
                snd_seq_event_t * ev;
443
475
                snd_seq_event_input( m_seqHandle, &ev );
444
476
 
488
520
                                                        ), midiTime() );
489
521
                                break;
490
522
 
 
523
                        case SND_SEQ_EVENT_CONTROLLER:
 
524
                                dest->processInEvent( midiEvent( CONTROL_CHANGE,
 
525
                                                ev->data.control.channel,
 
526
                                                ev->data.control.param,
 
527
                                                ev->data.control.value ),
 
528
                                                                midiTime() );
 
529
                                break;
 
530
 
 
531
                        case SND_SEQ_EVENT_PGMCHANGE:
 
532
                                dest->processInEvent( midiEvent( PROGRAM_CHANGE,
 
533
                                                ev->data.control.channel,
 
534
                                                ev->data.control.param,
 
535
                                                ev->data.control.value ),
 
536
                                                                midiTime() );
 
537
                                break;
 
538
 
 
539
                        case SND_SEQ_EVENT_CHANPRESS:
 
540
                                dest->processInEvent( midiEvent(
 
541
                                                        CHANNEL_PRESSURE,
 
542
                                                ev->data.control.channel,
 
543
                                                ev->data.control.param,
 
544
                                                ev->data.control.value ),
 
545
                                                                midiTime() );
 
546
                                break;
 
547
 
 
548
                        case SND_SEQ_EVENT_PITCHBEND:
 
549
                                dest->processInEvent( midiEvent( PITCH_BEND,
 
550
                                                ev->data.control.channel,
 
551
                                                ev->data.control.value + 8192,
 
552
                                                        0 ), midiTime() );
 
553
                                break;
 
554
 
491
555
                        case SND_SEQ_EVENT_SENSING:
492
556
                        case SND_SEQ_EVENT_CLOCK:
493
557
                                break;
500
564
 
501
565
        }
502
566
 
 
567
        delete[] pollfd_set;
503
568
}
504
569
 
505
570