19 #ifdef HAVE_ALSA_SUPPORT    36 #define DEFAULT_DEVICE (i18n("DSNOOP plugin") + _("|sound_note"))    39 #define ELEMENTS_OF(__array__) (sizeof(__array__) / sizeof(__array__[0]))    44 #if Q_BYTE_ORDER == Q_BIG_ENDIAN    46 #define SND_PCM_FORMAT_S18_3 SND_PCM_FORMAT_S18_3BE    47 #define SND_PCM_FORMAT_U18_3 SND_PCM_FORMAT_U18_3BE    48 #define SND_PCM_FORMAT_U20_3 SND_PCM_FORMAT_U20_3BE    49 #define SND_PCM_FORMAT_S20_3 SND_PCM_FORMAT_S20_3BE    50 #define SND_PCM_FORMAT_U24_3 SND_PCM_FORMAT_U24_3BE    51 #define SND_PCM_FORMAT_S24_3 SND_PCM_FORMAT_S24_3BE    55 #define SND_PCM_FORMAT_S18_3 SND_PCM_FORMAT_S18_3LE    56 #define SND_PCM_FORMAT_U18_3 SND_PCM_FORMAT_U18_3LE    57 #define SND_PCM_FORMAT_U20_3 SND_PCM_FORMAT_U20_3LE    58 #define SND_PCM_FORMAT_S20_3 SND_PCM_FORMAT_S20_3LE    59 #define SND_PCM_FORMAT_U24_3 SND_PCM_FORMAT_U24_3LE    60 #define SND_PCM_FORMAT_S24_3 SND_PCM_FORMAT_S24_3LE    84     SND_PCM_FORMAT_S16, SND_PCM_FORMAT_S16_LE, SND_PCM_FORMAT_S16_BE,
    85     SND_PCM_FORMAT_U16, SND_PCM_FORMAT_U16_LE, SND_PCM_FORMAT_U16_BE,
   100     SND_PCM_FORMAT_S24, SND_PCM_FORMAT_S24_LE, SND_PCM_FORMAT_S24_BE,
   101     SND_PCM_FORMAT_U24, SND_PCM_FORMAT_U24_LE, SND_PCM_FORMAT_U24_BE,
   104     SND_PCM_FORMAT_S32, SND_PCM_FORMAT_S32_LE, SND_PCM_FORMAT_S32_BE,
   105     SND_PCM_FORMAT_U32, SND_PCM_FORMAT_U32_LE, SND_PCM_FORMAT_U32_BE,
   108     SND_PCM_FORMAT_FLOAT, SND_PCM_FORMAT_FLOAT_LE, SND_PCM_FORMAT_FLOAT_BE,
   111     SND_PCM_FORMAT_FLOAT64,
   112     SND_PCM_FORMAT_FLOAT64_LE, SND_PCM_FORMAT_FLOAT64_BE,
   116     SND_PCM_FORMAT_IEC958_SUBFRAME,
   117     SND_PCM_FORMAT_IEC958_SUBFRAME_LE, SND_PCM_FORMAT_IEC958_SUBFRAME_BE,
   121     SND_PCM_FORMAT_MU_LAW,
   124     SND_PCM_FORMAT_A_LAW,
   133     SND_PCM_FORMAT_IMA_ADPCM,
   142     SND_PCM_FORMAT_SPECIAL,
   150     if (snd_pcm_format_float(fmt)) {
   151         if (snd_pcm_format_width(fmt) == 32)
   153         if (snd_pcm_format_width(fmt) == 64)
   155     } 
else if (snd_pcm_format_linear(fmt)) {
   156         if (snd_pcm_format_signed(fmt) == 1)
   158         else if (snd_pcm_format_unsigned(fmt) == 1)
   169     if (snd_pcm_format_little_endian(fmt) == 1)
   171     if (snd_pcm_format_big_endian(fmt) == 1)
   181         case SND_PCM_FORMAT_MU_LAW:
   183         case SND_PCM_FORMAT_A_LAW:
   185         case SND_PCM_FORMAT_IMA_ADPCM:
   187         case SND_PCM_FORMAT_MPEG:
   189         case SND_PCM_FORMAT_GSM:
   200      m_sw_params(Q_NULLPTR), m_open_result(0), m_tracks(0),
   202      m_bits_per_sample(0), m_bytes_per_sample(0),
   204      m_supported_formats(), m_initialized(false), m_buffer_size(0),
   234     const unsigned int count =
   236     for (
unsigned int i = 0; i < count; i++) {
   240         if (err < 0) 
continue;
   282     if (!device.length()) 
return QString::number(EINVAL); 
   286     qDebug(
"RecordALSA::open -> '%s'", 
DBG(alsa_device));
   288     if (!alsa_device.length()) 
return QString::number(EINVAL);
   292     if (alsa_device.endsWith(
_(
","))) 
return QString::number(EINVAL);
   296                                  SND_PCM_STREAM_CAPTURE,
   300         qWarning(
"RecordALSA::openDevice('%s') - failed, err=%d (%s)",
   310                 reason = QString::number(ENODEV);
   313                 reason = QString::number(EBUSY);
   316                 reason = QString::fromLocal8Bit(snd_strerror(
m_open_result));
   332     snd_output_t *output = Q_NULLPTR;
   334     snd_pcm_uframes_t buffer_size;
   335     unsigned period_time = 0; 
   336     unsigned buffer_time = 0; 
   337     snd_pcm_uframes_t period_frames = 0;
   338     snd_pcm_uframes_t buffer_frames = 0;
   339     snd_pcm_uframes_t start_threshold, stop_threshold;
   352     err = snd_output_stdio_attach(&output, stderr, 0);
   354         qWarning(
"Output failed: %s", snd_strerror(err));
   358         qWarning(
"Cannot initialize hardware parameters: %s",
   360         snd_output_close(output);
   365          SND_PCM_ACCESS_RW_INTERLEAVED);
   367         qWarning(
"Cannot set access type: %s", snd_strerror(err));
   368         snd_output_close(output);
   374     Q_ASSERT(format_index >= 0);
   375     if (format_index < 0) {
   378         qWarning(
"RecordkALSA::setFormat(): no matching format for "\
   379                  "compression '%s', %d bits/sample, format '%s'",
   384         snd_output_close(output);
   388     Q_ASSERT(format_index >= 0);
   395         qWarning(
"RecordkALSA::setFormat(): format %u is not supported",
   396             static_cast<int>(alsa_format));
   397         snd_output_close(output);
   404         qWarning(
"Cannot set sample format: %s", snd_strerror(err));
   405         snd_output_close(output);
   411         qWarning(
"Cannot set channel count: %s", snd_strerror(err));
   412         snd_output_close(output);
   420         qWarning(
"Cannot set sample rate: %s", snd_strerror(err));
   421         snd_output_close(output);
   426         qWarning(
"rate is not accurate (requested = %iHz, got = %iHz)",
   431     err = snd_pcm_hw_params_get_buffer_time_max(
m_hw_params, &buffer_time,
   434     if (buffer_time > 500000) buffer_time = 500000;
   437         period_time = buffer_time / 4;
   439         period_frames = buffer_frames / 4;
   441     if (period_time > 0) {
   443                                                      &period_time, Q_NULLPTR);
   446                                                      &period_frames, Q_NULLPTR);
   449     if (buffer_time > 0) {
   451                                                      &buffer_time, Q_NULLPTR);
   462         snd_output_close(output);
   463         qWarning(
"Cannot set parameters: %s", snd_strerror(err));
   468     snd_pcm_hw_params_get_buffer_size(
m_hw_params, &buffer_size);
   470         qWarning(
"Can't use period equal to buffer size (%lu == %lu)",
   472         snd_output_close(output);
   479         qWarning(
"Unable to determine current software parameters: %s",
   481         snd_output_close(output);
   488     start_threshold = qMax<snd_pcm_uframes_t>(1, buffer_size);
   492     stop_threshold = buffer_size;
   501         qDebug(
"   activating snd_pcm_sw_params FAILED");
   503         qWarning(
"Unable to set software parameters: %s", snd_strerror(err));
   507     if ((err = snd_pcm_prepare(
m_handle)) < 0) {
   509         qWarning(
"cannot prepare interface for use: %s",snd_strerror(err));
   512     if ((err = snd_pcm_start(
m_handle)) < 0) {
   514         qWarning(
"cannot start interface: %s",snd_strerror(err));
   522     snd_output_close(output);
   530     unsigned int length = buffer.size();
   533     if (!length)   
return 0;             
   538         if (err < 0) 
return err;
   546     Q_ASSERT(chunk_bytes);
   547     if (!chunk_bytes) 
return 0;
   550     unsigned int n = (length / chunk_bytes);
   551     if (length != (n * chunk_bytes)) {
   553         length = n * chunk_bytes;
   556         buffer.resize(length);
   559     Q_ASSERT(length >= offset);
   569     static snd_pcm_state_t last_state = SND_PCM_STATE_DISCONNECTED;
   570     snd_pcm_state_t state = snd_pcm_state(
m_handle);
   571     if (state != last_state) {
   573             case SND_PCM_STATE_OPEN:
   574                 qDebug(
"SND_PCM_STATE_OPEN");
   576             case SND_PCM_STATE_SETUP:
   577                 qDebug(
"SND_PCM_STATE_SETUP");
   579             case SND_PCM_STATE_PREPARED:
   580                 qDebug(
"ND_PCM_STATE_PREPARED");
   582             case SND_PCM_STATE_RUNNING:
   583                 qDebug(
"SND_PCM_STATE_RUNNING");
   585             case SND_PCM_STATE_XRUN:
   586                 qDebug(
"SND_PCM_STATE_XRUN");
   588             case SND_PCM_STATE_DRAINING:
   589                 qDebug(
"SND_PCM_STATE_DRAINING");
   591             case SND_PCM_STATE_PAUSED:
   592                 qDebug(
"SND_PCM_STATE_PAUSED");
   594             case SND_PCM_STATE_SUSPENDED:
   595                 qDebug(
"SND_PCM_STATE_SUSPENDED");
   597             case SND_PCM_STATE_DISCONNECTED:
   598                 qDebug(
"SND_PCM_STATE_DISCONNECTED");
   609         snd_pcm_readi(
m_handle, buffer.data() + offset, samples)
   614         unsigned int timeout = (
m_rate > 0) ?
   618     } 
else if (r == -EPIPE) {
   620         qWarning(
"RecordALSA::read(), underrun");
   622         if (r >= 0) r = snd_pcm_start(
m_handle);
   624             qWarning(
"RecordALSA::read(), "   625                      "resume after underrun failed: %s",
   629         qWarning(
"RecordALSA::read(), after underrun: resuming");
   631     } 
else if (r == -ESTRPIPE) {
   632         qWarning(
"RecordALSA::read(), suspended. "\
   633                     "trying to resume...");
   634         while ((r = snd_pcm_resume(
m_handle)) == -EAGAIN)
   637             qWarning(
"RecordALSA::read(), resume failed, "   638                     "restarting stream.");
   639             if ((r = snd_pcm_prepare(
m_handle)) < 0) {
   640                 qWarning(
"RecordALSA::read(), resume error: %s",
   645         qWarning(
"RecordALSA::read(), after suspend: resuming");
   648         qWarning(
"RecordALSA: read error: %s", snd_strerror(r));
   692         if ((err = snd_pcm_hw_params_get_channels_min(
m_hw_params, &min)) < 0)
   693             qWarning(
"RecordALSA::detectTracks: min: %s",
   695         if ((err = snd_pcm_hw_params_get_channels_max(
m_hw_params, &max)) < 0)
   696             qWarning(
"RecordALSA::detectTracks: max: %s",
   727     static const unsigned int known_rates[] = {
   766     for (
unsigned int i = 0; i < 
ELEMENTS_OF(known_rates); i++) {
   767         unsigned int rate = known_rates[i];
   770         if (err < 0) 
continue;
   773         bool is_duplicate = 
false;
   774         foreach (
const double &r, list)
   775             if (qFuzzyCompare(rate, r)) { is_duplicate = 
true; 
break; }
   776         if (is_duplicate) 
continue;
   811         if (snd_pcm_format_width(*fmt) != bits) 
continue;
   822     qWarning(
"RecordALSA::mode2format -> no match found !?");
   829     QList<Kwave::Compression::Type> list;
   838         if (list.contains(compression)) 
continue;
   843         list.append(compression);
   866     QList<unsigned int> list;
   872         const unsigned int bits = snd_pcm_format_width(*fmt);
   881         if (list.contains(bits)) 
continue;
   907     QList<Kwave::SampleFormat::Format> list;
   923         if (list.contains(sample_format)) 
continue;
   929         list.append(sample_format);
   953     return (index >= 0) ?
   969     list.append(
_(
"#TREE#"));
   976     snd_ctl_t *handle = Q_NULLPTR;
   979     snd_ctl_card_info_t *info    = Q_NULLPTR;
   980     snd_pcm_info_t      *pcminfo = Q_NULLPTR;
   985     if (snd_card_next(&card) < 0 || card < 0) {
   986         qWarning(
"no soundcards found...");
   990     snd_ctl_card_info_malloc(&info);
   991     snd_pcm_info_malloc(&pcminfo);
   997         name = name.arg(card);
   998         if ((err = snd_ctl_open(&handle, name.toLocal8Bit().data(), 0)) < 0) {
   999             qWarning(
"control open (%i): %s", card, snd_strerror(err));
  1002         if ((err = snd_ctl_card_info(handle, info)) < 0) {
  1003             qWarning(
"control hardware info (%i): %s",
  1004                      card, snd_strerror(err));
  1005             snd_ctl_close(handle);
  1011             if (snd_ctl_pcm_next_device(handle, &dev)<0)
  1012                 qWarning(
"snd_ctl_pcm_next_device");
  1015             snd_pcm_info_set_device(pcminfo, dev);
  1016             snd_pcm_info_set_subdevice(pcminfo, 0);
  1017             snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
  1018             if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
  1020                     qWarning(
"control digital audio info (%i): %s", card,
  1024             count = snd_pcm_info_get_subdevices_count(pcminfo);
  1036             hw_device = 
_(
"hw:%1,%2");
  1037             hw_device = hw_device.arg(card).arg(dev);
  1039             QString card_name   = 
_(snd_ctl_card_info_get_name(info));
  1040             QString device_name = 
_(snd_pcm_info_get_name(pcminfo));
  1046                     snd_pcm_info_set_subdevice(pcminfo, idx);
  1047                     if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
  1048                         qWarning(
"ctrl digital audio playback info (%i): %s",
  1049                                  card, snd_strerror(err));
  1051                         QString hwdev = hw_device + 
_(
",%1").arg(idx);
  1052                         QString subdevice_name = 
_(
  1053                             snd_pcm_info_get_subdevice_name(pcminfo));
  1055                             i18n(
"Card %1: ", card_name) +
  1056                             _(
"|sound_card||") +
  1057                             i18n(
"Device %1: ", device_name) +
  1058                             _(
"|sound_device||") +
  1059                             i18n(
"Subdevice %1: ", subdevice_name) +
  1060                             _(
"|sound_subdevice");
  1061                         qDebug(
"# '%s' -> '%s'", 
DBG(hwdev), 
DBG(full_name));
  1067                 QString full_name = QString(
  1068                     i18n(
"Card %1: ", card_name) +
  1069                     _(
"|sound_card||") +
  1070                     i18n(
"Device %1: ", device_name) +
  1071                     _(
"|sound_subdevice")
  1078         snd_ctl_close(handle);
  1081         if (snd_card_next(&card) < 0) {
  1082             qWarning(
"snd_card_next failed");
  1092     snd_ctl_card_info_free(info);
  1093     snd_pcm_info_free(pcminfo);
  1116             if (n == name) 
return n;
  1118         qWarning(
"RecordALSA::alsaDeviceName('%s') - NOT FOUND", 
DBG(name));
 unsigned int m_buffer_size
virtual double sampleRate() Q_DECL_OVERRIDE
#define SND_PCM_FORMAT_S20_3
static const snd_pcm_format_t _known_formats[]
virtual QList< Kwave::SampleFormat::Format > detectSampleFormats() Q_DECL_OVERRIDE
virtual int setCompression(Kwave::Compression::Type new_compression) Q_DECL_OVERRIDE
Kwave::SampleFormat::Format m_sample_format
#define SND_PCM_FORMAT_U24_3
virtual int close() Q_DECL_OVERRIDE
virtual Kwave::Compression::Type compression() Q_DECL_OVERRIDE
static Kwave::SampleFormat::Format sample_format_of(snd_pcm_format_t fmt)
static Kwave::Compression::Type compression_of(snd_pcm_format_t fmt)
QString description(IDX type, bool localized) const
int mode2format(Kwave::Compression::Type compression, int bits, Kwave::SampleFormat::Format sample_format)
virtual QStringList supportedDevices() Q_DECL_OVERRIDE
virtual QList< double > detectSampleRates() Q_DECL_OVERRIDE
virtual Kwave::SampleFormat::Format sampleFormat() Q_DECL_OVERRIDE
#define SND_PCM_FORMAT_S18_3
snd_pcm_sw_params_t * m_sw_params
virtual int tracks() Q_DECL_OVERRIDE
Kwave::Compression::Type m_compression
unsigned int m_bits_per_sample
virtual int read(QByteArray &buffer, unsigned int offset) Q_DECL_OVERRIDE
void detectSupportedFormats()
virtual QString open(const QString &dev) Q_DECL_OVERRIDE
virtual int detectTracks(unsigned int &min, unsigned int &max) Q_DECL_OVERRIDE
virtual ~RecordALSA() Q_DECL_OVERRIDE
unsigned int m_bytes_per_sample
snd_pcm_hw_params_t * m_hw_params
virtual Kwave::byte_order_t endianness() Q_DECL_OVERRIDE
#define SND_PCM_FORMAT_S24_3
#define SND_PCM_FORMAT_U18_3
virtual QList< unsigned int > supportedBits() Q_DECL_OVERRIDE
virtual int setSampleRate(double &new_rate) Q_DECL_OVERRIDE
QList< int > m_supported_formats
#define SND_PCM_FORMAT_U20_3
virtual int setSampleFormat(Kwave::SampleFormat::Format new_format) Q_DECL_OVERRIDE
virtual int bitsPerSample() Q_DECL_OVERRIDE
virtual int setTracks(unsigned int &tracks) Q_DECL_OVERRIDE
static QMap< QString, QString > m_device_list
virtual QList< Kwave::Compression::Type > detectCompressions() Q_DECL_OVERRIDE
virtual int setBitsPerSample(unsigned int new_bits) Q_DECL_OVERRIDE
snd_pcm_uframes_t m_chunk_size
#define ELEMENTS_OF(__array__)
QString alsaDeviceName(const QString &name)
IDX findFromData(const DATA &data) const
static Kwave::byte_order_t endian_of(snd_pcm_format_t fmt)