kwave  18.07.70
Kwave::RecordOSS Class Reference

#include <Record-OSS.h>

Inheritance diagram for Kwave::RecordOSS:
Inheritance graph
Collaboration diagram for Kwave::RecordOSS:
Collaboration graph

Public Member Functions

 RecordOSS ()
 
virtual ~RecordOSS () Q_DECL_OVERRIDE
 
virtual QString open (const QString &dev) Q_DECL_OVERRIDE
 
virtual int read (QByteArray &buffer, unsigned int offset) Q_DECL_OVERRIDE
 
virtual int close () Q_DECL_OVERRIDE
 
virtual QStringList supportedDevices () Q_DECL_OVERRIDE
 
virtual QString fileFilter () Q_DECL_OVERRIDE
 
virtual int detectTracks (unsigned int &min, unsigned int &max) Q_DECL_OVERRIDE
 
virtual int setTracks (unsigned int &tracks) Q_DECL_OVERRIDE
 
virtual int tracks () Q_DECL_OVERRIDE
 
virtual QList< double > detectSampleRates () Q_DECL_OVERRIDE
 
virtual int setSampleRate (double &new_rate) Q_DECL_OVERRIDE
 
virtual double sampleRate () Q_DECL_OVERRIDE
 
virtual QList< Kwave::Compression::TypedetectCompressions () Q_DECL_OVERRIDE
 
virtual int setCompression (Kwave::Compression::Type new_compression) Q_DECL_OVERRIDE
 
virtual Kwave::Compression::Type compression () Q_DECL_OVERRIDE
 
virtual QList< unsigned int > supportedBits () Q_DECL_OVERRIDE
 
virtual int setBitsPerSample (unsigned int new_bits) Q_DECL_OVERRIDE
 
virtual int bitsPerSample () Q_DECL_OVERRIDE
 
virtual QList< Kwave::SampleFormat::FormatdetectSampleFormats () Q_DECL_OVERRIDE
 
virtual int setSampleFormat (Kwave::SampleFormat::Format new_format) Q_DECL_OVERRIDE
 
virtual Kwave::SampleFormat::Format sampleFormat () Q_DECL_OVERRIDE
 
virtual Kwave::byte_order_t endianness () Q_DECL_OVERRIDE
 
- Public Member Functions inherited from Kwave::RecordDevice
 RecordDevice ()
 
virtual ~RecordDevice ()
 

Private Member Functions

void format2mode (int format, Kwave::Compression::Type &compression, int &bits, Kwave::SampleFormat::Format &sample_format)
 
int mode2format (Kwave::Compression::Type compression, int bits, Kwave::SampleFormat::Format sample_format)
 

Private Attributes

int m_fd
 
int m_rate
 
int m_tracks
 
int m_oss_version
 

Detailed Description

Definition at line 31 of file Record-OSS.h.

Constructor & Destructor Documentation

◆ RecordOSS()

Kwave::RecordOSS::RecordOSS ( )

Constructor

Definition at line 77 of file Record-OSS.cpp.

◆ ~RecordOSS()

Kwave::RecordOSS::~RecordOSS ( )
virtual

Destructor

Definition at line 84 of file Record-OSS.cpp.

References close().

85 {
86  close();
87 }
virtual int close() Q_DECL_OVERRIDE
Definition: Record-OSS.cpp:220
Here is the call graph for this function:

Member Function Documentation

◆ bitsPerSample()

int Kwave::RecordOSS::bitsPerSample ( )
virtual

Returns the current resolution in bits per sample or a negative error code if failed

Implements Kwave::RecordDevice.

Definition at line 757 of file Record-OSS.cpp.

References format2mode(), m_fd, and SNDCTL_DSP_SETFMT.

Referenced by detectSampleFormats().

758 {
759  Q_ASSERT(m_fd >= 0);
760  int mask = AFMT_QUERY;
761  int err = ioctl(m_fd, SNDCTL_DSP_SETFMT, &mask);
762  if (err < 0) return err;
763 
765  int b;
767  format2mode(mask, c, b, s);
768  return b;
769 }
#define SNDCTL_DSP_SETFMT
Definition: Record-OSS.cpp:70
void format2mode(int format, Kwave::Compression::Type &compression, int &bits, Kwave::SampleFormat::Format &sample_format)
Definition: Record-OSS.cpp:483
Here is the call graph for this function:
Here is the caller graph for this function:

◆ close()

int Kwave::RecordOSS::close ( )
virtual

Close the device

Implements Kwave::RecordDevice.

Definition at line 220 of file Record-OSS.cpp.

References m_fd, and m_oss_version.

Referenced by open(), and ~RecordOSS().

221 {
222  if (m_fd < 0) return 0; // already closed
223  ::close(m_fd);
224  m_fd = -1;
225  m_oss_version = -1;
226 
227  return 0;
228 }
virtual int close() Q_DECL_OVERRIDE
Definition: Record-OSS.cpp:220
Here is the caller graph for this function:

◆ compression()

Kwave::Compression::Type Kwave::RecordOSS::compression ( )
virtual

Returns the current compression type (0==none)

Implements Kwave::RecordDevice.

Definition at line 678 of file Record-OSS.cpp.

References format2mode(), m_fd, Kwave::Compression::NONE, and SNDCTL_DSP_SETFMT.

Referenced by detectSampleFormats(), setBitsPerSample(), setCompression(), setSampleFormat(), and supportedBits().

679 {
680  Q_ASSERT(m_fd >= 0);
681  int mask = AFMT_QUERY;
682  int err = ioctl(m_fd, SNDCTL_DSP_SETFMT, &mask);
683  if (err < 0) return Kwave::Compression::NONE;
684 
686  int b;
688  format2mode(mask, c, b, s);
689  return c;
690 }
#define SNDCTL_DSP_SETFMT
Definition: Record-OSS.cpp:70
void format2mode(int format, Kwave::Compression::Type &compression, int &bits, Kwave::SampleFormat::Format &sample_format)
Definition: Record-OSS.cpp:483
Here is the call graph for this function:
Here is the caller graph for this function:

◆ detectCompressions()

QList< Kwave::Compression::Type > Kwave::RecordOSS::detectCompressions ( )
virtual

Gets a list of supported compression types. If no compression is supported, the list might be empty.

Implements Kwave::RecordDevice.

Definition at line 631 of file Record-OSS.cpp.

References AFMT_S24_BE, AFMT_S24_LE, AFMT_S32_BE, AFMT_S32_LE, Kwave::Compression::G711_ALAW, Kwave::Compression::G711_ULAW, m_fd, Kwave::Compression::MPEG_LAYER_II, Kwave::Compression::MS_ADPCM, and Kwave::Compression::NONE.

632 {
633  Q_ASSERT(m_fd >= 0);
634  QList<Kwave::Compression::Type> compressions;
635  int err = 0;
636  int mask = AFMT_QUERY;
637 
638  err = ioctl(m_fd, SNDCTL_DSP_GETFMTS, &mask);
639  if (err < 0) return compressions;
640 
641  if (mask & AFMT_MPEG) compressions += Kwave::Compression::MPEG_LAYER_II;
642  if (mask & AFMT_A_LAW) compressions += Kwave::Compression::G711_ALAW;
643  if (mask & AFMT_MU_LAW) compressions += Kwave::Compression::G711_ULAW;
644  if (mask & AFMT_IMA_ADPCM) compressions += Kwave::Compression::MS_ADPCM;
645  if (mask & (AFMT_U16_LE | AFMT_U16_BE | AFMT_S16_LE | AFMT_S16_BE |
647  AFMT_S8 | AFMT_U8))
648  compressions += Kwave::Compression::NONE;
649 
650  return compressions;
651 }
#define AFMT_S24_LE
Definition: Record-OSS.cpp:45
#define AFMT_S24_BE
Definition: Record-OSS.cpp:48
#define AFMT_S32_BE
Definition: Record-OSS.cpp:54
#define AFMT_S32_LE
Definition: Record-OSS.cpp:51

◆ detectSampleFormats()

QList< Kwave::SampleFormat::Format > Kwave::RecordOSS::detectSampleFormats ( )
virtual

Gets a list of supported sample formats.

Note
this depends on the current setting of the compression!

Implements Kwave::RecordDevice.

Definition at line 772 of file Record-OSS.cpp.

References bitsPerSample(), compression(), format2mode(), and m_fd.

773 {
774  Q_ASSERT(m_fd >= 0);
775  QList<Kwave::SampleFormat::Format> formats;
776  formats.clear();
777  int err = 0;
778  int mask = AFMT_QUERY;
779 
780  err = ioctl(m_fd, SNDCTL_DSP_GETFMTS, &mask);
781  if (err < 0) return formats;
782 
783  // mask out all modes that do not match the current compression
784  // and bits per sample
786  const int bits_per_sample = this->bitsPerSample();
787  for (unsigned int bit = 0; bit < (sizeof(mask) << 3); bit++) {
788  if (!(mask & (1 << bit))) continue;
789 
790  // format is supported, split into compression, bits, sample format
792  int b;
794  format2mode(1 << bit, c, b, s);
795  if (c < 0) continue; // unknown -> skip
796 
797  if ((c == compression) && (b == bits_per_sample)) {
798  // this mode matches -> append it if not already known
799  if (!formats.contains(s)) formats += s;
800  }
801  }
802 
803  return formats;
804 }
virtual Kwave::Compression::Type compression() Q_DECL_OVERRIDE
Definition: Record-OSS.cpp:678
void format2mode(int format, Kwave::Compression::Type &compression, int &bits, Kwave::SampleFormat::Format &sample_format)
Definition: Record-OSS.cpp:483
virtual int bitsPerSample() Q_DECL_OVERRIDE
Definition: Record-OSS.cpp:757
Here is the call graph for this function:

◆ detectSampleRates()

QList< double > Kwave::RecordOSS::detectSampleRates ( )
virtual

get a list of supported sample rates

Implements Kwave::RecordDevice.

Definition at line 387 of file Record-OSS.cpp.

References m_fd, m_rate, and SNDCTL_DSP_SPEED.

388 {
389  QList<double> list;
390  Q_ASSERT(m_fd >= 0);
391 
392  static const int known_rates[] = {
393  1000, // (just for testing)
394  2000, // (just for testing)
395  4000, // standard OSS
396  5125, // seen in Harmony driver (HP712, 715/new)
397  5510, // seen in AD1848 driver
398  5512, // seen in ES1370 driver
399  6215, // seen in ES188X driver
400  6615, // seen in Harmony driver (HP712, 715/new)
401  6620, // seen in AD1848 driver
402  7350, // seen in AWACS and Burgundy sound driver
403  8000, // standard OSS
404  8820, // seen in AWACS and Burgundy sound driver
405  9600, // seen in AD1848 driver
406  11025, // soundblaster
407  14700, // seen in AWACS and Burgundy sound driver
408  16000, // standard OSS
409  17640, // seen in AWACS and Burgundy sound driver
410  18900, // seen in Harmony driver (HP712, 715/new)
411  22050, // soundblaster
412  24000, // seen in NM256 driver
413  27428, // seen in Harmony driver (HP712, 715/new)
414  29400, // seen in AWACS and Burgundy sound driver
415  32000, // standard OSS
416  32768, // seen in CS4299 driver
417  33075, // seen in Harmony driver (HP712, 715/new)
418  37800, // seen in Harmony driver (HP712, 715/new)
419  44100, // soundblaster
420  48000, // AC97
421  64000, // AC97
422  88200, // seen in RME96XX driver
423  96000, // AC97
424  128000, // (just for testing)
425  176400, // Envy24ht
426  192000, // AC97
427  196000, // (just for testing)
428  200000, // Lynx2
429  256000 // (just for testing)
430  };
431 
432  // try all known sample rates
433  for (unsigned int i=0; i < sizeof(known_rates)/sizeof(int); i++) {
434  int rate = known_rates[i];
435  int err = ioctl(m_fd, SNDCTL_DSP_SPEED, &rate);
436  if (err < 0) {
437 // qDebug("RecordOSS::detectSampleRates(): "
438 // "sample rate %d Hz not supported", known_rates[i]);
439  continue;
440  }
441 
442  // do not produce duplicates
443  bool is_duplicate = false;
444  foreach (const double &r, list)
445  if (qFuzzyCompare(rate, r)) { is_duplicate = true; break; }
446  if (is_duplicate) continue;
447 
448  // qDebug("found rate %d Hz", rate);
449  list.append(rate);
450  m_rate = rate;
451  }
452 
453  return list;
454 }
#define SNDCTL_DSP_SPEED
Definition: Record-OSS.cpp:58

◆ detectTracks()

int Kwave::RecordOSS::detectTracks ( unsigned int &  min,
unsigned int &  max 
)
virtual

Detect the minimum and maximum number of tracks. If the detection fails, minimum and maximum are set to zero.

Parameters
minreceives the lowest supported number of tracks
maxreceives the highest supported number of tracks
Returns
zero or positive number if ok, negative error number if failed

Implements Kwave::RecordDevice.

Definition at line 319 of file Record-OSS.cpp.

References m_fd, m_tracks, MAX_CHANNELS, SNDCTL_DSP_CHANNELS, and Kwave::toInt().

320 {
321  Q_ASSERT(m_fd >= 0);
322  unsigned int t;
323  int err = -1;
324 
325  // preset
326  min = 0;
327  max = 0;
328 
329  // find the smalles number of tracks, limit to MAX_CHANNELS
330  for (t = 1; t < MAX_CHANNELS; t++) {
331  int real_tracks = t;
332  err = ioctl(m_fd, SNDCTL_DSP_CHANNELS, &real_tracks);
333  if ((err >= 0) && (real_tracks == Kwave::toInt(t))) {
334  min = real_tracks;
335  break;
336  }
337  }
338  if (t >= MAX_CHANNELS) {
339  // no minimum track number found :-o
340  qWarning("no minimum track number found, err=%d", err);
341  min = 0;
342  max = 0;
343  return err;
344  }
345 
346  // find the highest number of tracks, start from MAX_CHANNELS downwards
347  max = min;
348  for (t = MAX_CHANNELS; t >= min; t--) {
349  int real_tracks = t;
350  err = ioctl(m_fd, SNDCTL_DSP_CHANNELS, &real_tracks);
351  if ((err >= 0) && (real_tracks == Kwave::toInt(t))) {
352  max = real_tracks;
353  break;
354  }
355  }
356  m_tracks = max;
357 
358  qDebug("RecordOSS::detectTracks, min=%u, max=%u", min, max);
359 
360  return (max > 0) ? 0 : -1;
361 }
#define MAX_CHANNELS
Definition: Record-OSS.cpp:74
int toInt(T x)
Definition: Utils.h:127
#define SNDCTL_DSP_CHANNELS
Definition: Record-OSS.cpp:62
Here is the call graph for this function:

◆ endianness()

Kwave::byte_order_t Kwave::RecordOSS::endianness ( )
virtual

Returns the current endianness (big/little/cpu)

Implements Kwave::RecordDevice.

Definition at line 848 of file Record-OSS.cpp.

References AFMT_S24_BE, AFMT_S24_LE, AFMT_S32_BE, AFMT_S32_LE, Kwave::BigEndian, Kwave::CpuEndian, Kwave::LittleEndian, m_fd, SNDCTL_DSP_SETFMT, and Kwave::UnknownEndian.

849 {
850  Q_ASSERT(m_fd >= 0);
851  int mask = AFMT_QUERY;
852  int err = ioctl(m_fd, SNDCTL_DSP_SETFMT, &mask);
853  if (err < 0) return Kwave::UnknownEndian;
854 
855  if (mask & (AFMT_U16_LE | AFMT_S16_LE | AFMT_S24_LE | AFMT_S32_LE))
856  return Kwave::LittleEndian;
857 
858  if (mask & (AFMT_U16_BE | AFMT_S16_BE | AFMT_S24_BE | AFMT_S32_BE))
859  return Kwave::BigEndian;
860 
861  if (mask & (AFMT_S8 | AFMT_U8))
862  return Kwave::CpuEndian;
863 
864  return Kwave::UnknownEndian;
865 }
#define AFMT_S24_LE
Definition: Record-OSS.cpp:45
#define AFMT_S24_BE
Definition: Record-OSS.cpp:48
#define SNDCTL_DSP_SETFMT
Definition: Record-OSS.cpp:70
#define AFMT_S32_BE
Definition: Record-OSS.cpp:54
#define AFMT_S32_LE
Definition: Record-OSS.cpp:51

◆ fileFilter()

QString Kwave::RecordOSS::fileFilter ( )
virtual

return a string suitable for a "File Open..." dialog

Reimplemented from Kwave::RecordDevice.

Definition at line 301 of file Record-OSS.cpp.

References _.

302 {
303  QString filter;
304 
305  if (filter.length()) filter += _("\n");
306  filter += _("audio*|") + i18n("OSS recording device (audio*)");
307  filter += _("dsp*|") + i18n("OSS recording device (dsp*)");
308 
309  if (filter.length()) filter += _("\n");
310  filter += _("adsp*|") + i18n("ALSA recording device (adsp*)");
311 
312  if (filter.length()) filter += _("\n");
313  filter += _("*|") + i18n("Any device (*)");
314 
315  return filter;
316 }
#define _(m)
Definition: memcpy.c:66

◆ format2mode()

void Kwave::RecordOSS::format2mode ( int  format,
Kwave::Compression::Type compression,
int &  bits,
Kwave::SampleFormat::Format sample_format 
)
private

split a device format bitmask into it's parameters.

Parameters
formatthe device specific format
compressionreceives a compression type
See also
Compression
Parameters
bitsreceives the number of bits per sample, related to the decoded stream
sample_formatreceives the sample format, as defined in libaudiofile (signed or unsigned)

Definition at line 483 of file Record-OSS.cpp.

References AFMT_S24_BE, AFMT_S24_LE, AFMT_S32_BE, AFMT_S32_LE, Kwave::Compression::G711_ALAW, Kwave::Compression::G711_ULAW, Kwave::Compression::MPEG_LAYER_II, Kwave::Compression::MS_ADPCM, Kwave::Compression::NONE, Kwave::SampleFormat::Signed, Kwave::SampleFormat::Unknown, and Kwave::SampleFormat::Unsigned.

Referenced by bitsPerSample(), compression(), detectSampleFormats(), sampleFormat(), setBitsPerSample(), setCompression(), setSampleFormat(), and supportedBits().

487 {
488 
489  switch (format) {
490  case AFMT_MU_LAW:
492  sample_format = Kwave::SampleFormat::Signed;
493  bits = 16;
494  break;
495  case AFMT_A_LAW:
497  sample_format = Kwave::SampleFormat::Unsigned;
498  bits = 16;
499  break;
500  case AFMT_IMA_ADPCM:
502  sample_format = Kwave::SampleFormat::Signed;
503  bits = 16;
504  break;
505  case AFMT_U8:
507  sample_format = Kwave::SampleFormat::Unsigned;
508  bits = 8;
509  break;
510  case AFMT_S16_LE: /* FALLTHROUGH */
511  case AFMT_S16_BE:
513  sample_format = Kwave::SampleFormat::Signed;
514  bits = 16;
515  break;
516  case AFMT_S8:
518  sample_format = Kwave::SampleFormat::Signed;
519  bits = 8;
520  break;
521  case AFMT_U16_LE: /* FALLTHROUGH */
522  case AFMT_U16_BE:
524  sample_format = Kwave::SampleFormat::Unsigned;
525  bits = 16;
526  break;
527  case AFMT_MPEG:
529  sample_format = Kwave::SampleFormat::Signed;
530  bits = 16;
531  break;
532 #if 0
533  case AFMT_AC3: /* Dolby Digital AC3 */
535  sample_format = Kwave::SampleFormat::Unknown;
536  bits = 16;
537  break;
538 #endif
539  case AFMT_S24_LE: /* FALLTHROUGH */
540  case AFMT_S24_BE:
542  sample_format = Kwave::SampleFormat::Signed;
543  bits = 24;
544  break;
545  case AFMT_S32_LE: /* FALLTHROUGH */
546  case AFMT_S32_BE:
548  sample_format = Kwave::SampleFormat::Signed;
549  bits = 32;
550  break;
551  default:
553  sample_format = Kwave::SampleFormat::Unknown;
554  bits = -1;
555  }
556 
557 }
#define AFMT_S24_LE
Definition: Record-OSS.cpp:45
#define AFMT_S24_BE
Definition: Record-OSS.cpp:48
virtual Kwave::Compression::Type compression() Q_DECL_OVERRIDE
Definition: Record-OSS.cpp:678
#define AFMT_S32_BE
Definition: Record-OSS.cpp:54
#define AFMT_S32_LE
Definition: Record-OSS.cpp:51
Here is the caller graph for this function:

◆ mode2format()

int Kwave::RecordOSS::mode2format ( Kwave::Compression::Type  compression,
int  bits,
Kwave::SampleFormat::Format  sample_format 
)
private

create a device format bitmask from it's parameters.

Parameters
compressionthe compression type
See also
Compression
Parameters
bitsthe number of bits per sample, related to the decoded stream
sample_formatthe sample format, as defined in libaudiofile (signed or unsigned)
Returns
the device specific format

Definition at line 560 of file Record-OSS.cpp.

References AFMT_S24_BE, AFMT_S24_LE, AFMT_S32_BE, AFMT_S32_LE, Kwave::Compression::G711_ALAW, Kwave::Compression::G711_ULAW, m_fd, Kwave::Compression::MPEG_LAYER_II, Kwave::Compression::MS_ADPCM, Kwave::SampleFormat::Signed, and Kwave::SampleFormat::Unsigned.

Referenced by setBitsPerSample(), setCompression(), and setSampleFormat().

563 {
564  // first level: compression
565  if (compression == Kwave::Compression::G711_ULAW) return AFMT_MU_LAW;
566  if (compression == Kwave::Compression::G711_ALAW) return AFMT_A_LAW;
567  if (compression == Kwave::Compression::MS_ADPCM) return AFMT_IMA_ADPCM;
568  if (compression == static_cast<int>(Kwave::Compression::MPEG_LAYER_II))
569  return AFMT_MPEG;
570 
571  // non-compressed: switch by sample format
572  if ((sample_format == Kwave::SampleFormat::Unsigned) && (bits == 8))
573  return AFMT_U8;
574  if ((sample_format == Kwave::SampleFormat::Signed) && (bits == 8))
575  return AFMT_S8;
576 
577  // get supported modes, maybe one endianness is not supported
578  int mask = 0;
579  int err = ioctl(m_fd, SNDCTL_DSP_GETFMTS, &mask);
580  if (err < 0) return bits;
581 
582  // unsigned 16 bit mode
583  // note: we prefer the machine's native endianness if both are supported !
584  if ((sample_format == Kwave::SampleFormat::Unsigned) && (bits == 16)) {
585  mask &= (AFMT_U16_LE | AFMT_U16_BE);
586  if (mask != (AFMT_U16_LE | AFMT_U16_BE)) return mask;
587 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
588  return AFMT_U16_BE;
589 #else
590  return AFMT_U16_LE;
591 #endif
592  }
593 
594  // signed 16 bit mode
595  if ((sample_format == Kwave::SampleFormat::Signed) && (bits == 16)) {
596  mask &= (AFMT_S16_LE | AFMT_S16_BE);
597  if (mask != (AFMT_S16_LE | AFMT_S16_BE)) return mask;
598 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
599  return AFMT_S16_BE;
600 #else
601  return AFMT_S16_LE;
602 #endif
603  }
604 
605  if ((sample_format == Kwave::SampleFormat::Signed) && (bits == 24)) {
606  mask &= (AFMT_S24_LE | AFMT_S24_BE);
607  if (mask != (AFMT_S24_LE | AFMT_S24_BE)) return mask;
608 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
609  return AFMT_S24_BE;
610 #else
611  return AFMT_S24_LE;
612 #endif
613  }
614 
615  if ((sample_format == Kwave::SampleFormat::Signed) && (bits == 32)) {
616  mask &= (AFMT_S32_LE | AFMT_S32_BE);
617  if (mask != (AFMT_S32_LE | AFMT_S32_BE)) return mask;
618 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
619  return AFMT_S32_BE;
620 #else
621  return AFMT_S32_LE;
622 #endif
623  }
624 
625  qWarning("RecordOSS: unknown format: sample_format=%d, bits=%d",
626  static_cast<int>(sample_format), bits);
627  return 0;
628 }
#define AFMT_S24_LE
Definition: Record-OSS.cpp:45
#define AFMT_S24_BE
Definition: Record-OSS.cpp:48
virtual Kwave::Compression::Type compression() Q_DECL_OVERRIDE
Definition: Record-OSS.cpp:678
#define AFMT_S32_BE
Definition: Record-OSS.cpp:54
#define AFMT_S32_LE
Definition: Record-OSS.cpp:51
Here is the caller graph for this function:

◆ open()

QString Kwave::RecordOSS::open ( const QString &  dev)
virtual

Open the record device.

Parameters
devpath of the record device
Returns
zero-length string if successful, or an error message if failed

Implements Kwave::RecordDevice.

Definition at line 90 of file Record-OSS.cpp.

References close(), m_fd, and m_oss_version.

91 {
92  // close the device if it is still open
93  if (m_fd >= 0) close();
94  if (!dev.length()) return QString::number(EINVAL); // no device name
95 
96  // first of all: try to open the device itself
97  int fd = ::open(dev.toLocal8Bit(), O_RDONLY | O_NONBLOCK);
98  if (fd < 0) {
99  qWarning("open failed, fd=%d, errno=%d (%s)",
100  fd, errno, strerror(errno));
101 
102  QString reason;
103  switch (errno) {
104  case ENOENT:
105  case ENODEV:
106  case ENXIO:
107  case EIO:
108  reason = QString::number(ENODEV);
109  break;
110  case EBUSY:
111  reason = QString::number(EBUSY);
112  break;
113  default:
114  reason = QString::fromLocal8Bit(strerror(errno));
115  break;
116  }
117  return reason;
118  }
119 
120  // Query OSS driver version
121  m_oss_version = 0x030000;
122 #ifdef OSS_GETVERSION
123  ioctl(fd, OSS_GETVERSION, &m_oss_version);
124 #endif
125  m_fd = fd;
126  return QString();
127 }
virtual QString open(const QString &dev) Q_DECL_OVERRIDE
Definition: Record-OSS.cpp:90
virtual int close() Q_DECL_OVERRIDE
Definition: Record-OSS.cpp:220
Here is the call graph for this function:

◆ read()

int Kwave::RecordOSS::read ( QByteArray &  buffer,
unsigned int  offset 
)
virtual

Read the raw audio data from the record device.

Parameters
bufferarray of bytes to receive the audio data might be resized for alignment
offsetoffset in bytes within the buffer
Returns
number of bytes read, zero or negative if failed

Implements Kwave::RecordDevice.

Definition at line 130 of file Record-OSS.cpp.

References m_fd, sampleRate(), and Kwave::toInt().

131 {
132  fd_set rfds;
133  struct timeval tv;
134  int retval;
135  int read_bytes = 0;
136  unsigned int length = buffer.size();
137 
138 // qDebug("RecordOSS::read(), offset=%d, length=%d", offset, length);
139  Q_ASSERT(m_fd >= 0);
140  Q_ASSERT(buffer.size());
141  Q_ASSERT(length);
142  Q_ASSERT(offset < length);
143  if (m_fd < 0) return -EBADF; // file not opened
144  if (buffer.isEmpty()) return -EINVAL; // buffer is null pointer
145  if (!length) return -EINVAL;
146  if (offset >= length) return -EINVAL;
147 
148  length -= offset;
149 
150 #if 0
151  int blocksize = length;
152  int err = ioctl(m_fd, SNDCTL_DSP_GETBLKSIZE, &blocksize);
153  Q_ASSERT(!err);
154  qDebug("blocksize = %u", blocksize);
155  if (err) {
156  blocksize = length;
157  }
158 
159  blocksize = (127 << 16) + 6;
160  err = ioctl(m_fd, SNDCTL_DSP_SETFRAGMENT, &blocksize);
161 #endif
162 
163  // determine the timeout for reading, use safety factor 2
164  int rate = Kwave::toInt(sampleRate());
165  if (rate < 1) rate = 1;
166 
167  unsigned int timeout = (length / rate) * 2;
168  if (timeout < 2) timeout = 2;
169  quint8 *buf = reinterpret_cast<quint8 *>(buffer.data()) + offset;
170 
171  int mask = 0;
172  retval = ioctl(m_fd, SNDCTL_DSP_SETTRIGGER, &mask);
173  Q_ASSERT(!retval);
174  mask = PCM_ENABLE_INPUT;
175  retval = ioctl(m_fd, SNDCTL_DSP_SETTRIGGER, &mask);
176  Q_ASSERT(!retval);
177 
178  while (length) {
179  FD_ZERO(&rfds);
180  FD_SET(m_fd, &rfds);
181 
182  tv.tv_sec = timeout;
183  tv.tv_usec = 0;
184  retval = select(m_fd+1, &rfds, Q_NULLPTR, Q_NULLPTR, &tv);
185 
186  if (retval == -1) {
187  if (errno == EINTR)
188  return -errno; // return without warning
189 
190  qWarning("RecordOSS::read() - select() failed errno=%d (%s)",
191  errno, strerror(errno));
192  return -errno;
193  } else if (retval) {
194  ssize_t res = ::read(m_fd, buf, length);
195 
196  if ((res == -1) && (errno == EINTR))
197  return -errno; // interrupted, return without warning
198 
199  if ((res == -1) && (errno == EAGAIN))
200  continue;
201 
202  if (res < 0) {
203  qWarning("RecordOSS::read() - read error %d (%s)",
204  errno, strerror(errno));
205  return read_bytes;
206  }
207  read_bytes += res;
208  length -= res;
209  buf += res;
210  } else {
211  printf("No data within 5 seconds.\n");
212  return -EIO;
213  }
214  }
215 
216  return read_bytes;
217 }
virtual int read(QByteArray &buffer, unsigned int offset) Q_DECL_OVERRIDE
Definition: Record-OSS.cpp:130
virtual double sampleRate() Q_DECL_OVERRIDE
Definition: Record-OSS.cpp:475
int toInt(T x)
Definition: Utils.h:127
Here is the call graph for this function:

◆ sampleFormat()

Kwave::SampleFormat::Format Kwave::RecordOSS::sampleFormat ( )
virtual

Returns the current sample format (signed/unsigned)

Implements Kwave::RecordDevice.

Definition at line 833 of file Record-OSS.cpp.

References format2mode(), m_fd, SNDCTL_DSP_SETFMT, and Kwave::SampleFormat::Unknown.

834 {
835  Q_ASSERT(m_fd >= 0);
836  int mask = AFMT_QUERY;
837  int err = ioctl(m_fd, SNDCTL_DSP_SETFMT, &mask);
838  if (err < 0) return Kwave::SampleFormat::Unknown;
839 
841  int b;
843  format2mode(mask, c, b, s);
844  return s;
845 }
#define SNDCTL_DSP_SETFMT
Definition: Record-OSS.cpp:70
void format2mode(int format, Kwave::Compression::Type &compression, int &bits, Kwave::SampleFormat::Format &sample_format)
Definition: Record-OSS.cpp:483
Here is the call graph for this function:

◆ sampleRate()

double Kwave::RecordOSS::sampleRate ( )
virtual

Returns the current sample rate of the device

Implements Kwave::RecordDevice.

Definition at line 475 of file Record-OSS.cpp.

References m_fd, and m_rate.

Referenced by read().

476 {
477  Q_ASSERT(m_fd >= 0);
478 
479  return m_rate;
480 }
Here is the caller graph for this function:

◆ setBitsPerSample()

int Kwave::RecordOSS::setBitsPerSample ( unsigned int  new_bits)
virtual

Set the resolution in bits per sample

Parameters
new_bitsresolution [bits/sample]

Implements Kwave::RecordDevice.

Definition at line 731 of file Record-OSS.cpp.

References compression(), format2mode(), m_fd, mode2format(), and SNDCTL_DSP_SETFMT.

732 {
733  Q_ASSERT(m_fd >= 0);
735  int bits, format = AFMT_QUERY;
736  Kwave::SampleFormat::Format sample_format;
737 
738  // read back current format
739  int err = ioctl(m_fd, SNDCTL_DSP_SETFMT, &format);
740  if (err < 0) return err;
741  format2mode(format, compression, bits, sample_format);
742 
743  // modify the bits per sample
744  bits = new_bits;
745 
746  // activate new format
747  int oldformat = format;
748  format = mode2format(compression, bits, sample_format);
749  err = ioctl(m_fd, SNDCTL_DSP_SETFMT, &format);
750  if (err < 0) return err;
751  if (oldformat != format) return -1;
752 
753  return 0;
754 }
#define SNDCTL_DSP_SETFMT
Definition: Record-OSS.cpp:70
virtual Kwave::Compression::Type compression() Q_DECL_OVERRIDE
Definition: Record-OSS.cpp:678
void format2mode(int format, Kwave::Compression::Type &compression, int &bits, Kwave::SampleFormat::Format &sample_format)
Definition: Record-OSS.cpp:483
int mode2format(Kwave::Compression::Type compression, int bits, Kwave::SampleFormat::Format sample_format)
Definition: Record-OSS.cpp:560
Here is the call graph for this function:

◆ setCompression()

int Kwave::RecordOSS::setCompression ( Kwave::Compression::Type  new_compression)
virtual

Try to set a new compression type.

Parameters
new_compressionthe identifier of the new compression
Returns
zero on success, negative error code if failed
See also
class Compression

Implements Kwave::RecordDevice.

Definition at line 654 of file Record-OSS.cpp.

References compression(), format2mode(), m_fd, mode2format(), and SNDCTL_DSP_SETFMT.

655 {
656  Q_ASSERT(m_fd >= 0);
658  int bits, format = AFMT_QUERY;
659  Kwave::SampleFormat::Format sample_format;
660 
661  // read back current format
662  int err = ioctl(m_fd, SNDCTL_DSP_SETFMT, &format);
663  if (err < 0) return -1;
664  format2mode(format, compression, bits, sample_format);
665 
666  // modify the compression
667  compression = new_compression;
668 
669  // activate new format
670  format = mode2format(compression, bits, sample_format);
671  err = ioctl(m_fd, SNDCTL_DSP_SETFMT, &format);
672  if (err < 0) return -1;
673 
674  return 0;
675 }
#define SNDCTL_DSP_SETFMT
Definition: Record-OSS.cpp:70
virtual Kwave::Compression::Type compression() Q_DECL_OVERRIDE
Definition: Record-OSS.cpp:678
void format2mode(int format, Kwave::Compression::Type &compression, int &bits, Kwave::SampleFormat::Format &sample_format)
Definition: Record-OSS.cpp:483
int mode2format(Kwave::Compression::Type compression, int bits, Kwave::SampleFormat::Format sample_format)
Definition: Record-OSS.cpp:560
Here is the call graph for this function:

◆ setSampleFormat()

int Kwave::RecordOSS::setSampleFormat ( Kwave::SampleFormat::Format  new_format)
virtual

Try to set a new sample format (signed/unsigned)

Parameters
new_formatthe identifier for the new format
Returns
zero on success, negative error code if failed
See also
class SampleFormat

Implements Kwave::RecordDevice.

Definition at line 807 of file Record-OSS.cpp.

References compression(), format2mode(), m_fd, mode2format(), and SNDCTL_DSP_SETFMT.

808 {
809  Q_ASSERT(m_fd >= 0);
811  int bits, format = AFMT_QUERY;
812  Kwave::SampleFormat::Format sample_format;
813 
814  // read back current format
815  int err = ioctl(m_fd, SNDCTL_DSP_SETFMT, &format);
816  if (err < 0) return err;
817  format2mode(format, compression, bits, sample_format);
818 
819  // modify the sample format
820  sample_format = new_format;
821 
822  // activate new format
823  int oldformat = format;
824  format = mode2format(compression, bits, sample_format);
825  err = ioctl(m_fd, SNDCTL_DSP_SETFMT, &format);
826  if (err < 0) return err;
827  if (oldformat != format) return -1;
828 
829  return 0;
830 }
#define SNDCTL_DSP_SETFMT
Definition: Record-OSS.cpp:70
virtual Kwave::Compression::Type compression() Q_DECL_OVERRIDE
Definition: Record-OSS.cpp:678
void format2mode(int format, Kwave::Compression::Type &compression, int &bits, Kwave::SampleFormat::Format &sample_format)
Definition: Record-OSS.cpp:483
int mode2format(Kwave::Compression::Type compression, int bits, Kwave::SampleFormat::Format sample_format)
Definition: Record-OSS.cpp:560
Here is the call graph for this function:

◆ setSampleRate()

int Kwave::RecordOSS::setSampleRate ( double &  new_rate)
virtual

Try to set a new sample rate.

Parameters
new_ratethe sample rate to be set [samples/second], can be modified and rounded up/down to the nearest supported sample rate if the underlying driver supports that.
Returns
zero on success, negative error code if failed

Implements Kwave::RecordDevice.

Definition at line 457 of file Record-OSS.cpp.

References m_fd, m_rate, SNDCTL_DSP_SPEED, and Kwave::toInt().

458 {
459  Q_ASSERT(m_fd >= 0);
460  // OSS supports only integer rates
461  int rate = Kwave::toInt(rint(new_rate));
462 
463  // set the rate of the device (must already be opened)
464  int err = ioctl(m_fd, SNDCTL_DSP_SPEED, &rate);
465  if (err < 0) return err;
466 
467  m_rate = rate;
468  // return the sample rate if succeeded
469  new_rate = static_cast<double>(rate);
470 
471  return 0;
472 }
int toInt(T x)
Definition: Utils.h:127
#define SNDCTL_DSP_SPEED
Definition: Record-OSS.cpp:58
Here is the call graph for this function:

◆ setTracks()

int Kwave::RecordOSS::setTracks ( unsigned int &  tracks)
virtual

Try to set a new number of tracks.

Note
the device must be open
Parameters
tracksthe number of tracks to be set, can be modified and decreased to the next supported number of tracks if the underlying driver supports that.
Returns
zero on success, negative error code if failed

Implements Kwave::RecordDevice.

Definition at line 364 of file Record-OSS.cpp.

References m_fd, m_tracks, SNDCTL_DSP_CHANNELS, and tracks().

365 {
366  Q_ASSERT(m_fd >= 0);
367 
368  // set the number of tracks in the device (must already be opened)
369  int t = tracks;
370  int err = ioctl(m_fd, SNDCTL_DSP_CHANNELS, &t);
371  if (err < 0) return err;
372 
373  m_tracks = t;
374  // return the number of tracks if succeeded
375  tracks = t;
376 
377  return 0;
378 }
virtual int tracks() Q_DECL_OVERRIDE
Definition: Record-OSS.cpp:381
#define SNDCTL_DSP_CHANNELS
Definition: Record-OSS.cpp:62
Here is the call graph for this function:

◆ supportedBits()

QList< unsigned int > Kwave::RecordOSS::supportedBits ( )
virtual

Detect a list of supported bits per sample.

Note
this depends on the compression type
Returns
a list of bits per sample, empty if failed

Implements Kwave::RecordDevice.

Definition at line 693 of file Record-OSS.cpp.

References compression(), format2mode(), m_fd, and Kwave::Compression::NONE.

694 {
695  Q_ASSERT(m_fd >= 0);
696  QList<unsigned int> bits;
697  bits.clear();
698  int err = 0;
699  int mask = AFMT_QUERY;
700 
701  err = ioctl(m_fd, SNDCTL_DSP_GETFMTS, &mask);
702  if (err < 0) return bits;
703 
704  // mask out all modes that do not match the current compression
705  const int compression = this->compression();
706  for (unsigned int bit=0; bit < (sizeof(mask) << 3); bit++) {
707  if (!(mask & (1 << bit))) continue;
708 
709  // format is supported, split into compression, bits, sample format
711  int b;
713  format2mode(1 << bit, c, b, s);
714  if (b < 0) continue; // unknown -> skip
715 
716  // take the mode if compression matches and it is not already known
717  if ((c == compression) && !(bits.contains(b))) {
718  bits += b;
719  }
720  }
721 
722 #if 0
723  if (mask | AFMT_AC3)
724  qDebug("RecordOSS: your device supports AC3 which is not "\
725  "yet supported, sorry :-(");
726 #endif
727  return bits;
728 }
virtual Kwave::Compression::Type compression() Q_DECL_OVERRIDE
Definition: Record-OSS.cpp:678
void format2mode(int format, Kwave::Compression::Type &compression, int &bits, Kwave::SampleFormat::Format &sample_format)
Definition: Record-OSS.cpp:483
Here is the call graph for this function:

◆ supportedDevices()

QStringList Kwave::RecordOSS::supportedDevices ( )
virtual

return a string list with supported device names

Implements Kwave::RecordDevice.

Definition at line 285 of file Record-OSS.cpp.

References _, scanDirectory(), and scanFiles().

286 {
287  QStringList list, dirlist;
288 
289  scanDirectory(list, _("/dev"));
290  scanDirectory(list, _("/dev/sound"));
291  scanFiles(dirlist, _("/dev/oss"), _("[^.]*"));
292  foreach(QString dir, dirlist)
293  scanDirectory(list, dir);
294  list.append(_("#EDIT#"));
295  list.append(_("#SELECT#"));
296 
297  return list;
298 }
static void scanDirectory(QStringList &list, const QString &dir)
Definition: Record-OSS.cpp:275
static void scanFiles(QStringList &list, const QString &dirname, const QString &mask)
Definition: Record-OSS.cpp:256
#define _(m)
Definition: memcpy.c:66
Here is the call graph for this function:

◆ tracks()

int Kwave::RecordOSS::tracks ( )
virtual

Returns the current number of tracks

Implements Kwave::RecordDevice.

Definition at line 381 of file Record-OSS.cpp.

References m_tracks.

Referenced by setTracks().

382 {
383  return m_tracks;
384 }
Here is the caller graph for this function:

Member Data Documentation

◆ m_fd

◆ m_oss_version

int Kwave::RecordOSS::m_oss_version
private

OSS driver version

Definition at line 207 of file Record-OSS.h.

Referenced by close(), and open().

◆ m_rate

int Kwave::RecordOSS::m_rate
private

sample rate

Definition at line 201 of file Record-OSS.h.

Referenced by detectSampleRates(), sampleRate(), and setSampleRate().

◆ m_tracks

int Kwave::RecordOSS::m_tracks
private

number of tracks

Definition at line 204 of file Record-OSS.h.

Referenced by detectTracks(), setTracks(), and tracks().


The documentation for this class was generated from the following files: