/***************************************************************************
         PlayBack-OSS.h  -  playback device for standard linux OSS
                             -------------------
    begin                : Sat May 19 2001
    copyright            : (C) 2001 by Thomas Eschenbacher
    email                : Thomas.Eschenbacher@gmx.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef PLAY_BACK_OSS_H
#define PLAY_BACK_OSS_H

#include "config.h"
#ifdef HAVE_OSS_SUPPORT

#include <QByteArray>
#include <QList>
#include <QString>

#include "libkwave/PlayBackDevice.h"
#include "libkwave/SampleArray.h"
#include "libkwave/SampleFormat.h"

namespace Kwave
{

    class SampleEncoder;

    class PlayBackOSS: public Kwave::PlayBackDevice
    {
    public:

        /** Default constructor */
        PlayBackOSS();

        /** Destructor */
        virtual ~PlayBackOSS() Q_DECL_OVERRIDE;

        /**
         * Opens the device for playback.
         * @see PlayBackDevice::open
         */
        virtual QString open(const QString &device, double rate,
                             unsigned int channels, unsigned int bits,
                             unsigned int bufbase) Q_DECL_OVERRIDE;

        /**
         * Writes an array of samples to the output device.
         * @see PlayBackDevice::write
         */
        virtual int write(const Kwave::SampleArray &samples) Q_DECL_OVERRIDE;

        /**
         * Closes the output device.
         * @see PlayBackDevice::close
         */
        virtual int close() Q_DECL_OVERRIDE;

        /** return a string list with supported device names */
        virtual QStringList supportedDevices() Q_DECL_OVERRIDE;

        /** return a string suitable for a "File Open..." dialog */
        virtual QString fileFilter() Q_DECL_OVERRIDE;

        /**
         * returns a list of supported bits per sample resolutions
         * of a given device.
         *
         * @param device filename of the device
         * @return list of supported bits per sample, or empty on errors
         */
        virtual QList<unsigned int> supportedBits(const QString &device)
            Q_DECL_OVERRIDE;

        /**
         * Detect the minimum and maximum number of channels.
         * If the detection fails, minimum and maximum are set to zero.
         *
         * @param device filename of the device
         * @param min receives the lowest supported number of channels
         * @param max receives the highest supported number of channels
         * @return zero or positive number if ok,
         *         negative error number if failed
         */
        virtual int detectChannels(const QString &device,
                                   unsigned int &min, unsigned int &max)
            Q_DECL_OVERRIDE;

    protected:

        /**
         * split a device format bitmask into its parameters.
         * (copied from playback plugin)
         *
         * @param format the device specific format
         * @param compression receives a compression type
         * @see Compression
         * @param bits receives the number of bits per sample, related
         *        to the decoded stream
         * @param sample_format receives the sample format, as defined in
         *        libaudiofile (signed or unsigned)
         */
        void format2mode(int format, int &compression,
                         int &bits,
                         Kwave::SampleFormat::Format &sample_format) const;

        /**
         * Opens a physical device and returns its file descriptor
         *
         * @param device filename of the device
         * @return file descriptor >= 0 or negative value on errors
         */
        int openDevice(const QString &device);

        /** Writes the output buffer to the device */
        void flush();

        /** Name of the output device */
        QString m_device_name;

        /** Handle of the output device */
        int m_handle;

        /** Playback rate [samples/second] */
        double m_rate;

        /** Number of channels */
        unsigned int m_channels;

        /** Resolution in bits per sample */
        unsigned int m_bits;

        /** Exponent of the buffer size */
        unsigned int m_bufbase;

        /** buffer with samples data */
        Kwave::SampleArray m_buffer;

        /** buffer with raw data */
        QByteArray m_raw_buffer;

        /** Buffer size on bytes */
        unsigned int m_buffer_size;

        /** number of bytes in the buffer */
        unsigned int m_buffer_used;

        /** encoder for converting from samples to raw format */
        Kwave::SampleEncoder *m_encoder;

        /** OSS driver version */
        int m_oss_version;
    };
}

#endif /* HAVE_OSS_SUPPORT */

#endif /* PLAY_BACK_OSS_H */

//***************************************************************************
//***************************************************************************
