~mixxxdevelopers/mixxx/features_library_scanner

« back to all changes in this revision

Viewing changes to mixxx/mixxx/playeralsa.cpp

  • Committer: tuehaste
  • Date: 2002-02-26 11:12:07 UTC
  • Revision ID: vcs-imports@canonical.com-20020226111207-5rly26cj9gdd19ba
Initial revision

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
                          playeralsa.cpp  -  description
 
3
                             -------------------
 
4
    begin                : Wed Feb 20 2002
 
5
    copyright            : (C) 2002 by Tue and Ken Haste Andersen
 
6
    email                : 
 
7
 ***************************************************************************/
 
8
 
 
9
/***************************************************************************
 
10
 *                                                                         *
 
11
 *   This program is free software; you can redistribute it and/or modify  *
 
12
 *   it under the terms of the GNU General Public License as published by  *
 
13
 *   the Free Software Foundation; either version 2 of the License, or     *
 
14
 *   (at your option) any later version.                                   *
 
15
 *                                                                         *
 
16
 ***************************************************************************/
 
17
 
 
18
#include "playeralsa.h"
 
19
 
 
20
PlayerALSA::PlayerALSA(int size) : Player(size)
 
21
{
 
22
    // Open device 0 on card 0
 
23
    int err = snd_pcm_open(&handle, 0, 0, SND_PCM_OPEN_PLAYBACK);
 
24
    if (err != 0) {
 
25
      qFatal("Error opening device (%i): %s",err,snd_strerror(err));
 
26
      std::exit(-1);
 
27
    }
 
28
 
 
29
    // ALSA channel parameters
 
30
    params = new snd_pcm_channel_params_t;
 
31
    params->mode=SND_PCM_MODE_BLOCK;
 
32
    params->start_mode=SND_PCM_START_FULL;
 
33
    params->stop_mode=SND_PCM_STOP_ROLLOVER; // This makes the audio keep playing even
 
34
                                             // if underruns occurs
 
35
    params->buf.block.frag_size = size*SAMPLE_SIZE; // Buffer size in bytes
 
36
    params->buf.block.frags_max=3;
 
37
    params->buf.block.frags_min=1;
 
38
    params->format.interleave=1;
 
39
    params->format.format=SND_PCM_SFMT_S16_LE;
 
40
    params->format.rate=SRATE;
 
41
    params->channel=SND_PCM_CHANNEL_PLAYBACK;
 
42
    params->format.voices=2;
 
43
 
 
44
    err = snd_pcm_channel_params(handle,params);
 
45
    if (err != 0) {
 
46
      // try to close what was opened!
 
47
      snd_pcm_close(handle);
 
48
      qFatal("Error setting parameters for device %i", err);
 
49
      std::exit(-1);
 
50
    }
 
51
    setup = new snd_pcm_channel_setup_t;
 
52
    setup->channel=SND_PCM_CHANNEL_PLAYBACK;
 
53
    err = snd_pcm_channel_setup(handle, setup);
 
54
    if (err>0) {
 
55
      qFatal("Error setting up channel (%i)", err);
 
56
      std::exit(-1);
 
57
    }
 
58
 
 
59
    err = snd_pcm_playback_flush(handle);
 
60
    if (err>0) {
 
61
      qFatal("Error flushing playback buffer %i):%s", err, snd_strerror(err));
 
62
      std::exit(-1);
 
63
    }
 
64
 
 
65
    // The buffer size has possible been changed by the driver. The size returned
 
66
    // by the driver is given in number of bytes, and BUFFER_SIZE indicates the
 
67
    // same size in samples
 
68
    if ((BUFFER_SIZE = setup->buf.block.frag_size/SAMPLE_SIZE) == 0) {
 
69
      qFatal("Driver returned zero buffer size.");
 
70
      std::exit(-1);
 
71
    }
 
72
 
 
73
    qDebug("Using ALSA. Buffer size : %i samples.",BUFFER_SIZE/2);
 
74
        allocate();
 
75
}
 
76
 
 
77
PlayerALSA::~PlayerALSA()
 
78
{
 
79
        // Close audio device
 
80
        snd_pcm_close(handle);
 
81
 
 
82
        // Deallocate objects
 
83
        delete setup;
 
84
        delete params;
 
85
}
 
86
 
 
87
void PlayerALSA::start(EngineBuffer *_reader)
 
88
{
 
89
        Player::start(_reader);
 
90
 
 
91
        // Prepare for playback
 
92
        int err = snd_pcm_channel_prepare(handle, params->channel);
 
93
        if (err>0)
 
94
        {
 
95
                qFatal("Error preparing channel (%i)%s",err , snd_strerror(err));
 
96
        std::exit(-1);
 
97
        }
 
98
 
 
99
        // Start thread
 
100
        QThread::start();
 
101
}
 
102
 
 
103
void PlayerALSA::stop()
 
104
{
 
105
        // Stop audio
 
106
        snd_pcm_playback_drain(handle);
 
107
 
 
108
        QThread::wait();
 
109
        // Terminate synth thread
 
110
        //pthread_cancel(p_thread);
 
111
 
 
112
        // Wait for synth thread to terminate
 
113
        //void *thread_state;
 
114
        //pthread_join(p_thread, &thread_state);
 
115
}
 
116
 
 
117
void PlayerALSA::wait()
 
118
{
 
119
        QThread::wait();
 
120
}
 
121
 
 
122
void PlayerALSA::run()
 
123
{
 
124
        qDebug("PlayerALSA: Beginning of thread.");
 
125
        rt_priority();
 
126
 
 
127
        // Loop the synthesis, and pass the buffers to ALSA
 
128
        int res = 0;
 
129
        int BUFFER_SIZE_BYTES = BUFFER_SIZE*SAMPLE_SIZE;
 
130
        //std::cout << "Starting playback thread\n" << flush;
 
131
        while (res == 0) {
 
132
                res = prepareBuffer();
 
133
                if ((res == 0) && (snd_pcm_write(handle,out_buffer,BUFFER_SIZE_BYTES)
 
134
                                                   != BUFFER_SIZE_BYTES)) {
 
135
                        qFatal("Error writing samples to hardware %i",res);
 
136
                        std::exit(-1);
 
137
                }       
 
138
        }
 
139
}
 
140
 
 
141
void PlayerALSA::rt_priority()
 
142
{
 
143
        // Try to set realtime priority on the current executing thread
 
144
        struct sched_param schp;
 
145
        memset(&schp, 0, sizeof(schp));
 
146
        schp.sched_priority = sched_get_priority_max(SCHED_FIFO);
 
147
        if (sched_setscheduler(0, SCHED_FIFO, &schp) != 0)
 
148
                qWarning("Not possible to give audio I/O thread realtime prioriy.");
 
149
}