PageRenderTime 26ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/src/QtRadio/Audio.cpp

https://github.com/8cH9azbsFifZ/ghpsdr3
C++ | 271 lines | 185 code | 56 blank | 30 comment | 29 complexity | f1e53eeaedaefd087214f82055df418d MD5 | raw file
  1. /*
  2. * File: Audio.cpp
  3. * Author: John Melton, G0ORX/N6LYT
  4. *
  5. * Created on 16 August 2010, 11:19
  6. */
  7. /* Copyright (C)
  8. * 2009 - John Melton, G0ORX/N6LYT
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version 2
  12. * of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  22. *
  23. */
  24. #include "Audio.h"
  25. Audio::Audio() {
  26. audio_output=NULL;
  27. audio_out=NULL;
  28. sampleRate=8000;
  29. audio_channels=1;
  30. audio_byte_order=QAudioFormat::LittleEndian;
  31. qDebug() << "Audio: LittleEndian=" << QAudioFormat::LittleEndian << " BigEndian=" << QAudioFormat::BigEndian;
  32. audio_format.setSampleType(QAudioFormat::SignedInt);
  33. audio_format.setFrequency(sampleRate+(sampleRate==8000?SAMPLE_RATE_FUDGE:0));
  34. audio_format.setChannels(audio_channels);
  35. audio_format.setSampleSize(16);
  36. audio_format.setCodec("audio/pcm");
  37. audio_format.setByteOrder(audio_byte_order);
  38. }
  39. Audio::~Audio() {
  40. }
  41. int Audio::get_sample_rate() {
  42. return sampleRate;
  43. }
  44. int Audio::get_channels() {
  45. return audio_channels;
  46. }
  47. void Audio::initialize_audio(int buffer_size) {
  48. qDebug() << "initialize_audio " << buffer_size;
  49. decoded_buffer.resize(buffer_size*2);
  50. init_decodetable();
  51. audio_format.setFrequency(sampleRate+(sampleRate==8000?SAMPLE_RATE_FUDGE:0));
  52. audio_format.setChannels(audio_channels);
  53. audio_format.setSampleSize(16);
  54. audio_format.setCodec("audio/pcm");
  55. audio_format.setByteOrder(audio_byte_order);
  56. }
  57. void Audio::get_audio_devices(QComboBox* comboBox) {
  58. QList<QAudioDeviceInfo> devices=QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
  59. QAudioDeviceInfo device_info;
  60. qDebug() << "Audio::get_audio_devices";
  61. for(int i=0;i<devices.length();i++) {
  62. device_info=devices.at(i);
  63. qDebug() << "Audio::get_audio_devices: " << device_info.deviceName();
  64. qDebug() << " Codecs:";
  65. QStringList codecs=device_info.supportedCodecs();
  66. for(int j=0;j<codecs.size();j++) {
  67. qDebug() << " " << codecs.at(j).toLocal8Bit().constData();
  68. }
  69. qDebug() << " Byte Orders";
  70. QList<QAudioFormat::Endian> byteOrders=device_info.supportedByteOrders();
  71. for(int j=0;j<byteOrders.size();j++) {
  72. qDebug() << " " << (byteOrders.at(j)==QAudioFormat::BigEndian?"BigEndian":"LittleEndian");
  73. }
  74. qDebug() << " Sample Type";
  75. QList<QAudioFormat::SampleType> sampleTypes=device_info.supportedSampleTypes();
  76. for(int j=0;j<sampleTypes.size();j++) {
  77. if(sampleTypes.at(j)==QAudioFormat::Unknown) {
  78. qDebug() << " Unknown";
  79. } else if(sampleTypes.at(j)==QAudioFormat::SignedInt) {
  80. qDebug() << " SignedInt";
  81. } else if(sampleTypes.at(j)==QAudioFormat::UnSignedInt) {
  82. qDebug() << " UnSignedInt";
  83. } else if(sampleTypes.at(j)==QAudioFormat::Float) {
  84. qDebug() << " Float";
  85. }
  86. }
  87. qDebug() << " Sample Rates";
  88. QList<int> sampleRates=device_info.supportedFrequencies();
  89. for(int j=0;j<sampleRates.size();j++) {
  90. qDebug() << " " << sampleRates.at(j);
  91. }
  92. qDebug() << " Sample Sizes";
  93. QList<int> sampleSizes=device_info.supportedSampleSizes();
  94. for(int j=0;j<sampleSizes.size();j++) {
  95. qDebug() << " " << sampleSizes.at(j);
  96. }
  97. qDebug() << " Channels";
  98. QList<int> channels=device_info.supportedChannels();
  99. for(int j=0;j<channels.size();j++) {
  100. qDebug() << " " << channels.at(j);
  101. }
  102. comboBox->addItem(device_info.deviceName(),qVariantFromValue(device_info));
  103. if(i==0) {
  104. audio_device=device_info;
  105. }
  106. i++;
  107. }
  108. qDebug() << "Audio::get_audio_devices: default is " << audio_device.deviceName();
  109. audio_output = new QAudioOutput(audio_device, audio_format, this);
  110. qDebug() << "QAudioOutput: error=" << audio_output->error() << " state=" << audio_output->state();
  111. audio_out = audio_output->start();
  112. if(audio_output->error()!=0) {
  113. qDebug() << "QAudioOutput: after start error=" << audio_output->error() << " state=" << audio_output->state();
  114. qDebug() << "Format:";
  115. qDebug() << " sample rate: " << audio_format.frequency();
  116. qDebug() << " codec: " << audio_format.codec();
  117. qDebug() << " byte order: " << audio_format.byteOrder();
  118. qDebug() << " sample size: " << audio_format.sampleSize();
  119. qDebug() << " sample type: " << audio_format.sampleType();
  120. qDebug() << " channels: " << audio_format.channels();
  121. audio_out=NULL;
  122. }
  123. if(audio_out==NULL) {
  124. qDebug() << "Audio::selectAudio: audio_out is NULL!";
  125. }
  126. }
  127. void Audio::select_audio(QAudioDeviceInfo info,int rate,int channels,QAudioFormat::Endian byteOrder) {
  128. qDebug() << "selected audio " << info.deviceName() << " sampleRate:" << rate << " Channels: " << channels << " Endian:" << (byteOrder==QAudioFormat::BigEndian?"BigEndian":"LittleEndian");
  129. sampleRate=rate;
  130. audio_channels=channels;
  131. audio_byte_order=byteOrder;
  132. if(audio_output!=NULL) {
  133. audio_output->stop();
  134. audio_output->disconnect(this);
  135. audio_output=NULL;
  136. audio_out=NULL;
  137. }
  138. audio_device=info;
  139. audio_format.setFrequency(sampleRate+(sampleRate==8000?SAMPLE_RATE_FUDGE:0));
  140. audio_format.setChannels(audio_channels);
  141. audio_format.setByteOrder(audio_byte_order);
  142. if (!audio_device.isFormatSupported(audio_format)) {
  143. qDebug()<<"Audio format not supported by device.";
  144. }
  145. audio_output = new QAudioOutput(audio_device, audio_format, this);
  146. qDebug() << "QAudioOutput: error=" << audio_output->error() << " state=" << audio_output->state();
  147. audio_out = audio_output->start();
  148. if(audio_output->error()!=0) {
  149. qDebug() << "QAudioOutput: after start error=" << audio_output->error() << " state=" << audio_output->state();
  150. qDebug() << "Format:";
  151. qDebug() << " sample rate: " << audio_format.frequency();
  152. qDebug() << " codec: " << audio_format.codec();
  153. qDebug() << " byte order: " << audio_format.byteOrder();
  154. qDebug() << " sample size: " << audio_format.sampleSize();
  155. qDebug() << " sample type: " << audio_format.sampleType();
  156. qDebug() << " channels: " << audio_format.channels();
  157. audio_out=NULL;
  158. }
  159. if(audio_out==NULL) {
  160. qDebug() << "Audio::selectAudio: audio_out is NULL!";
  161. }
  162. }
  163. void Audio::process_audio(char* header,char* buffer,int length) {
  164. //qDebug() << "process audio";
  165. int written=0;
  166. aLawDecode(buffer,length);
  167. if(audio_out!=NULL) {
  168. //qDebug() << "writing audio data length=: " << decoded_buffer.length();
  169. //while(written<decoded_buffer.length()) {
  170. // written+=audio_out->write(&decoded_buffer.data()[written],decoded_buffer.length()-written);
  171. //}
  172. written=audio_out->write(decoded_buffer.data(),decoded_buffer.length());
  173. if(written!=decoded_buffer.length()) {
  174. // qDebug() << "process_audio: dropped audio data: length="<<decoded_buffer.length()<<"written="<<written;
  175. }
  176. }
  177. }
  178. void Audio::aLawDecode(char* buffer,int length) {
  179. int i;
  180. short v;
  181. //qDebug() << "aLawDecode " << decoded_buffer.length();
  182. decoded_buffer.clear();
  183. for (i=0; i < length; i++) {
  184. v=decodetable[buffer[i]&0xFF];
  185. switch(audio_byte_order) {
  186. case QAudioFormat::LittleEndian:
  187. decoded_buffer.append((char)(v&0xFF));
  188. decoded_buffer.append((char)((v>>8)&0xFF));
  189. break;
  190. case QAudioFormat::BigEndian:
  191. decoded_buffer.append((char)((v>>8)&0xFF));
  192. decoded_buffer.append((char)(v&0xFF));
  193. break;
  194. }
  195. }
  196. }
  197. void Audio::init_decodetable() {
  198. qDebug() << "init_decodetable";
  199. for (int i = 0; i < 256; i++) {
  200. int input = i ^ 85;
  201. int mantissa = (input & 15) << 4;
  202. int segment = (input & 112) >> 4;
  203. int value = mantissa + 8;
  204. if (segment >= 1) {
  205. value += 256;
  206. }
  207. if (segment > 1) {
  208. value <<= (segment - 1);
  209. }
  210. if ((input & 128) == 0) {
  211. value = -value;
  212. }
  213. decodetable[i] = (short) value;
  214. }
  215. }