summaryrefslogtreecommitdiffstats
path: root/kttsd/players/alsaplayer/alsaplayer.h
blob: acd465cb602a4c5a903b777fbd41846eeac6f602 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/***************************************************** vim:set ts=4 sw=4 sts=4:
  ALSA player.
  -------------------
  Copyright:
  (C) 2005 by Gary Cramblitt <garycramblitt@comcast.net>
  -------------------
  Original author: Gary Cramblitt <garycramblitt@comcast.net>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ******************************************************************************/

#ifndef ALSAPLAYER_H
#define ALSAPLAYER_H

// System includes.
#include <alsa/asoundlib.h>
#include <sys/poll.h>

// Qt includes.
#include <qstring.h>
#include <qobject.h>
#include <qthread.h>
#include <qfile.h>
#include <qmutex.h>

// KDE includes.
#include <config.h>
#include <kdemacros.h>
#include "kdeexportfix.h"
#include <kurl.h>

// AlsaPlayer includes.
#include "formats.h"
#include "player.h"

#ifndef LLONG_MAX
#define LLONG_MAX    9223372036854775807LL
#endif

#define DEFAULT_FORMAT		SND_PCM_FORMAT_U8
#define DEFAULT_SPEED 		8000

#define FORMAT_DEFAULT		-1
#define FORMAT_RAW		0
#define FORMAT_VOC		1
#define FORMAT_WAVE		2
#define FORMAT_AU		3

static snd_pcm_sframes_t (*readi_func)(snd_pcm_t *handle, void *buffer, snd_pcm_uframes_t size);
static snd_pcm_sframes_t (*writei_func)(snd_pcm_t *handle, const void *buffer, snd_pcm_uframes_t size);
static snd_pcm_sframes_t (*readn_func)(snd_pcm_t *handle, void **bufs, snd_pcm_uframes_t size);
static snd_pcm_sframes_t (*writen_func)(snd_pcm_t *handle, void **bufs, snd_pcm_uframes_t size);

class KDE_EXPORT AlsaPlayer : public Player, QThread
{
    Q_OBJECT

public:
    AlsaPlayer(QObject* parent = 0, const char* name = 0, const QStringList& args=QStringList());
    ~AlsaPlayer();

    virtual void startPlay(const QString& file);
    virtual void pause();
    virtual void stop();

    virtual void setVolume(float volume = 1.0);
    virtual float volume() const;

    virtual bool playing() const;
    virtual bool paused() const;

    virtual int totalTime() const;
    virtual int currentTime() const;
    virtual int position() const; // in this case not really the percent

    virtual void seek(int seekTime);
    virtual void seekPosition(int position);

    virtual QStringList getPluginList( const QCString& classname );
    virtual void setSinkName(const QString &sinkName);

    virtual void setDebugLevel(uint level) { m_debugLevel = level; }
    virtual void setPeriodSize(uint periodSize) { m_defPeriodSize = periodSize; }
    virtual void setPeriods(uint periods) { m_defPeriods = periods; }

protected:
    virtual void run();

private slots:

private:
    void init();
    void cleanup();
    void stopAndExit();
    int wait_for_poll(int draining);

    QString timestamp() const;

    ssize_t safe_read(int fd, void *buf, size_t count);
    int test_vocfile(void *buffer);
    size_t test_wavefile_read(int fd, char *buffer, size_t *size, size_t reqsize, int line);
    ssize_t test_wavefile(int fd, char *_buffer, size_t size);
    int test_au(int fd, char *buffer);
    void set_params(void);
    void xrun();
    void suspend(void);
    void compute_max_peak(char *data, size_t count);
    ssize_t pcm_write(char *data, size_t count);
    ssize_t voc_pcm_write(u_char *data, size_t count);
    void voc_write_silence(unsigned x);
    void voc_pcm_flush(void);
    void voc_play(int fd, int ofs, const char *name);
    void init_raw_data(void);
    off64_t calc_count(void);
    void header(int rtype, const char *name);
    void playback_go(int fd, size_t loaded, off64_t count, int rtype, const char *name);
    void playback(int fd);

    KURL m_currentURL;
    float m_currentVolume;
    QString m_pcmName;
    char* pcm_name;
    mutable QMutex m_mutex;

    QFile audiofile;
    QString name;
    bool canPause;

    snd_pcm_t *handle;
    struct {
        snd_pcm_format_t format;
        unsigned int channels;
        unsigned int rate;
    } hwdata, rhwdata;
    int timelimit;
    int file_type;
    unsigned int sleep_min;
    int open_mode;
    snd_pcm_stream_t stream;
    int mmap_flag;
    int interleaved;
    QByteArray audioBuffer;
    char *audiobuf;
    snd_pcm_uframes_t chunk_size;
    snd_pcm_uframes_t period_frames;
    unsigned period_time;
    unsigned buffer_time;
    snd_pcm_uframes_t buffer_size;
    int avail_min;
    int start_delay;
    int stop_delay;
    int buffer_pos;
    size_t bits_per_sample;
    size_t bits_per_frame;
    size_t chunk_bytes;
    snd_output_t *log;
    int fd;
    off64_t pbrec_count;
    off64_t fdcount;
    int vocmajor;
    int vocminor;

    int alsa_stop_pipe[2];          /* Pipe for communication about stop requests*/
    int alsa_fd_count;              /* Counter of descriptors to poll */
    QByteArray alsa_poll_fds_barray;
    struct pollfd *alsa_poll_fds;   /* Descriptors to poll */
    unsigned int m_defPeriodSize;
    unsigned int m_defPeriods;
    unsigned int m_debugLevel;
    bool m_simulatedPause;
};

#endif              // ALSAPLAYER_H

// vim: sw=4 ts=8 et