AudioSndio.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. #ifndef SINGLE_SOURCE_COMPILE
  2. /* license */
  3. #include "AudioSndio.h"
  4. #ifdef LMMS_HAVE_SNDIO
  5. #include <QtCore/QFileInfo>
  6. #include <QtGui/QLabel>
  7. #include <QtGui/QLineEdit>
  8. #include "endian_handling.h"
  9. #include "lcd_spinbox.h"
  10. #include "engine.h"
  11. #include "gui_templates.h"
  12. #include "templates.h"
  13. #ifdef LMMS_HAVE_UNISTD_H
  14. #include <unistd.h>
  15. #endif
  16. #ifdef LMMS_HAVE_STDLIB_H
  17. #include <stdlib.h>
  18. #endif
  19. #include "config_mgr.h"
  20. AudioSndio::AudioSndio(bool & _success_ful, mixer * _mixer) :
  21. AudioDevice( tLimit<ch_cnt_t>(
  22. configManager::inst()->value( "audiosndio", "channels" ).toInt(),
  23. DEFAULT_CHANNELS, SURROUND_CHANNELS ), _mixer )
  24. {
  25. _success_ful = FALSE;
  26. QString dev = configManager::inst()->value( "audiosndio", "device" );
  27. if (dev == "")
  28. {
  29. m_hdl = sio_open( NULL, SIO_PLAY, 0 );
  30. }
  31. else
  32. {
  33. m_hdl = sio_open( dev.toAscii().data(), SIO_PLAY, 0 );
  34. }
  35. if( m_hdl == NULL )
  36. {
  37. printf( "sndio: failed opening audio-device\n" );
  38. return;
  39. }
  40. sio_initpar(&m_par);
  41. m_par.pchan = channels();
  42. m_par.bits = 16;
  43. m_par.le = SIO_LE_NATIVE;
  44. m_par.rate = sampleRate();
  45. m_par.round = getMixer()->framesPerPeriod();
  46. m_par.appbufsz = m_par.round * 2;
  47. struct sio_par reqpar = m_par;
  48. if (!sio_setpar(m_hdl, &m_par))
  49. {
  50. printf( "sndio: sio_setpar failed\n" );
  51. return;
  52. }
  53. if (!sio_getpar(m_hdl, &m_par))
  54. {
  55. printf( "sndio: sio_getpar failed\n" );
  56. return;
  57. }
  58. if (reqpar.pchan != m_par.pchan ||
  59. reqpar.bits != m_par.bits ||
  60. reqpar.le != m_par.le ||
  61. (abs(int(reqpar.rate) - int(m_par.rate)) * 100)/reqpar.rate > 2)
  62. {
  63. printf( "sndio: returned params not as requested\n" );
  64. return;
  65. }
  66. if (!sio_start(m_hdl))
  67. {
  68. printf( "sndio: sio_start failed\n" );
  69. return;
  70. }
  71. _success_ful = TRUE;
  72. }
  73. AudioSndio::~AudioSndio()
  74. {
  75. stopProcessing();
  76. if (m_hdl != NULL)
  77. {
  78. sio_close( m_hdl );
  79. m_hdl = NULL;
  80. }
  81. }
  82. void AudioSndio::startProcessing( void )
  83. {
  84. if( !isRunning() )
  85. {
  86. start( QThread::HighPriority );
  87. }
  88. }
  89. void AudioSndio::stopProcessing( void )
  90. {
  91. if( isRunning() )
  92. {
  93. wait( 1000 );
  94. terminate();
  95. }
  96. }
  97. void AudioSndio::applyQualitySettings( void )
  98. {
  99. if( hqAudio() )
  100. {
  101. setSampleRate( engine::getMixer()->processingSampleRate() );
  102. /* change sample rate to sampleRate() */
  103. }
  104. AudioDevice::applyQualitySettings();
  105. }
  106. void AudioSndio::run( void )
  107. {
  108. surroundSampleFrame * temp =
  109. new surroundSampleFrame[getMixer()->framesPerPeriod()];
  110. int_sample_t * outbuf =
  111. new int_sample_t[getMixer()->framesPerPeriod() * channels()];
  112. while( TRUE )
  113. {
  114. const fpp_t frames = getNextBuffer( temp );
  115. if( !frames )
  116. {
  117. break;
  118. }
  119. uint bytes = convertToS16( temp, frames,
  120. getMixer()->masterGain(), outbuf, FALSE );
  121. if( sio_write( m_hdl, outbuf, bytes ) != bytes )
  122. {
  123. break;
  124. }
  125. }
  126. delete[] temp;
  127. delete[] outbuf;
  128. }
  129. AudioSndio::setupWidget::setupWidget( QWidget * _parent ) :
  130. AudioDevice::setupWidget( AudioSndio::name(), _parent )
  131. {
  132. m_device = new QLineEdit( "", this );
  133. m_device->setGeometry( 10, 20, 160, 20 );
  134. QLabel * dev_lbl = new QLabel( tr( "DEVICE" ), this );
  135. dev_lbl->setFont( pointSize<6>( dev_lbl->font() ) );
  136. dev_lbl->setGeometry( 10, 40, 160, 10 );
  137. lcdSpinBoxModel * m = new lcdSpinBoxModel( /* this */ );
  138. m->setRange( DEFAULT_CHANNELS, SURROUND_CHANNELS );
  139. m->setStep( 2 );
  140. m->setValue( configManager::inst()->value( "audiosndio",
  141. "channels" ).toInt() );
  142. m_channels = new lcdSpinBox( 1, this );
  143. m_channels->setModel( m );
  144. m_channels->setLabel( tr( "CHANNELS" ) );
  145. m_channels->move( 180, 20 );
  146. }
  147. AudioSndio::setupWidget::~setupWidget()
  148. {
  149. }
  150. void AudioSndio::setupWidget::saveSettings( void )
  151. {
  152. configManager::inst()->setValue( "audiosndio", "device",
  153. m_device->text() );
  154. configManager::inst()->setValue( "audiosndio", "channels",
  155. QString::number( m_channels->value<int>() ) );
  156. }
  157. #endif /* LMMS_HAVE_SNDIO */
  158. #endif /* SINGLE_SOURCE_COMPILE */