TTKMusicPlayer  4.3.0.0
TTKMusicPlayer imitates Kugou UI, the music player uses of qmmp core library based on Qt for windows and linux
musicaudiorecordermodule.cpp
Go to the documentation of this file.
2 
3 static constexpr int OPEN_FILE_ERROR = -1;
4 static constexpr int SAVE_FILE_ERROR = -2;
5 static constexpr int WRITE_FILE_ERROR = -3;
6 static constexpr int REWRITE_FILE_ERROR = -4;
7 
8 struct Data
9 {
10  char riffName[4];
11  ulong riffLength;
12  char wavName[4];
13  char fmtName[4];
14  ulong fmtLength;
15  ushort audioFormat;
16  ushort channleNumber;
17  ulong sampleRate;
20  ushort bitsPerSample;
21  char dataName[4];
22  ulong dataLength;
23 };
24 
25 
27  : QObject(parent),
28  m_inputVolume(0),
29  m_audioInputFile(nullptr),
30  m_audioOutputFile(nullptr)
31 {
32  m_file = new QFile(this);
33  m_file->setFileName(TTK_RECORD_FILE);
34 
35  m_formatFile.setChannelCount(1);
36  m_formatFile.setSampleRate(8000);
37 
38 #if TTK_QT_VERSION_CHECK(6,0,0)
39  m_formatFile.setSampleFormat(QAudioFormat::Int16);
40 
41  const QAudioDevice input_info(QMediaDevices::defaultAudioInput());
42  if(!input_info.isFormatSupported(m_formatFile))
43  {
44  TTK_WARN_STREAM("Input default format file not supported try to use preferred");
45  m_formatFile = input_info.preferredFormat();
46  }
47 
48  const QAudioDevice output_info(QMediaDevices::defaultAudioOutput());
49 #else
50  m_formatFile.setSampleSize(16);
51  m_formatFile.setCodec("audio/pcm");
52  m_formatFile.setSampleType(QAudioFormat::SignedInt);
53  m_formatFile.setByteOrder(QAudioFormat::LittleEndian);
54 
55  const QAudioDeviceInfo input_info(QAudioDeviceInfo::defaultInputDevice());
56  if(!input_info.isFormatSupported(m_formatFile))
57  {
58  TTK_WARN_STREAM("Input default format file not supported try to use nearest");
59  m_formatFile = input_info.nearestFormat(m_formatFile);
60  }
61 
62  const QAudioDeviceInfo output_info(QAudioDeviceInfo::defaultOutputDevice());
63 #endif
64  if(!output_info.isFormatSupported(m_formatFile))
65  {
66  TTK_WARN_STREAM("Output default format file not supported");
67  }
68 
69  int bit = 16;
70 #if TTK_QT_VERSION_CHECK(6,0,0)
71  switch(m_formatFile.sampleFormat())
72  {
73  case QAudioFormat::Unknown: bit = 0; break;
74  case QAudioFormat::UInt8: bit = 8; break;
75  case QAudioFormat::Int16: bit = 16; break;
76  case QAudioFormat::Int32: bit = 32; break;
77  case QAudioFormat::Float: bit = 32; break;
78  case QAudioFormat::NSampleFormats: bit = 0; break;
79  default: break;
80  }
81 #else
82  bit = m_formatFile.sampleSize();
83 #endif
84  if(bit != 16)
85  {
86  TTK_INFO_STREAM(QString("Audio device doesn't support 16 bit, support %1 bit samples").arg(bit));
87  }
88 }
89 
91 {
92  QFile::remove(TTK_RECORD_FILE);
93  QFile::remove(TTK_RECORD_DATA_FILE);
94 
95  delete m_file;
96  delete m_audioInputFile;
97  delete m_audioOutputFile;
98 }
99 
100 int MusicAudioRecorderModule::addWavHeader(const char *fileName) const
101 {
102  Data fileHeader;
103  fileHeader.riffName[0] = 'R';
104  fileHeader.riffName[1] = 'I';
105  fileHeader.riffName[2] = 'F';
106  fileHeader.riffName[3] = 'F';
107 
108  fileHeader.wavName[0] = 'W';
109  fileHeader.wavName[1] = 'A';
110  fileHeader.wavName[2] = 'V';
111  fileHeader.wavName[3] = 'E';
112 
113  fileHeader.fmtName[0] = 'f';
114  fileHeader.fmtName[1] = 'm';
115  fileHeader.fmtName[2] = 't';
116  fileHeader.fmtName[3] = 0x20;
117  fileHeader.fmtLength = 16;
118  fileHeader.audioFormat = 1;
119 
120  fileHeader.dataName[0] = 'd';
121  fileHeader.dataName[1] = 'a';
122  fileHeader.dataName[2] = 't';
123  fileHeader.dataName[3] = 'a';
124  fileHeader.bitsPerSample = 16;
125  fileHeader.bytesPerSample = 2;
126  fileHeader.sampleRate = 8000;
127  fileHeader.bytesPperSecond = 16000;
128  fileHeader.channleNumber = 1;
129 
130  int fileLen = 0;
131  const int headerSize = sizeof(fileHeader);
132 
133  FILE *input = nullptr;
134  FILE *output = nullptr;
135  if((input = fopen(qPrintable(m_file->fileName()), "rb")) == nullptr)
136  {
137  return OPEN_FILE_ERROR;
138  }
139 
140  if((output = fopen(qPrintable(fileName), "wb+")) == nullptr)
141  {
142  return SAVE_FILE_ERROR;
143  }
144 
145  if(fwrite(&fileHeader, 1, headerSize, output) != headerSize)
146  {
147  fclose(input);
148  fclose(output);
149  return WRITE_FILE_ERROR;
150  }
151 
152  while(!feof(input))
153  {
154  char readBuf[4096];
155  const int nRead = fread(readBuf, 1, 4096, input);
156  if(nRead > 0)
157  {
158  fwrite(readBuf, 1, nRead, output);
159  }
160 
161  fileLen += nRead;
162  }
163 
164  fseek(output, 0L, SEEK_SET);
165  fileHeader.riffLength = fileLen - 8 + headerSize;
166  fileHeader.dataLength = fileLen;
167 
168  if(fwrite(&fileHeader, 1, headerSize, output) != headerSize)
169  {
170  fclose(input);
171  fclose(output);
172  return REWRITE_FILE_ERROR;
173  }
174 
175  fclose(input);
176  fclose(output);
177  return fileLen;
178 }
179 
181 {
183 #if TTK_QT_VERSION_CHECK(5,0,0)
184  if(m_audioInputFile)
185  {
186  m_audioInputFile->setVolume(volume);
187  }
188 #endif
189 }
190 
192 {
193  return m_inputVolume;
194 }
195 
197 {
198  m_file->setFileName(name);
199 }
200 
202 {
203  return m_file->fileName();
204 }
205 
207 {
208  if(!m_audioInputFile)
209  {
210  return true;
211  }
212 
213  return m_audioInputFile->error() != QAudio::NoError;
214 }
215 
217 {
218  if(!m_file->isOpen() && m_file->open(QIODevice::WriteOnly | QIODevice::Truncate))
219  {
221  }
222 
223  if(!m_audioInputFile || m_audioInputFile->error() != QAudio::NoError)
224  {
225  TTK_ERROR_STREAM("Audio input open error");
226  return;
227  }
228 
229 #if TTK_QT_VERSION_CHECK(5,0,0)
230  m_audioInputFile->setVolume(m_inputVolume);
231 #endif
232  m_audioInputFile->start(m_file);
233 }
234 
236 {
237  if(m_audioInputFile)
238  {
239  m_audioInputFile->stop();
240  delete m_audioInputFile;
241  m_audioInputFile = nullptr;
242  }
243 
245  {
246  m_audioOutputFile->stop();
247  delete m_audioOutputFile;
248  m_audioOutputFile = nullptr;
249  }
250 
251  m_file->close();
252 }
int addWavHeader(const char *fileName) const
void setFileName(const QString &name)
static constexpr int REWRITE_FILE_ERROR
#define qPrintable(s)
Definition: ttkqtglobal.h:35
#define TTK_WARN_STREAM(msg)
Definition: ttklogger.h:75
const char * name
Definition: http_parser.c:458
#define TTK_RECORD_DATA_FILE
#define TTK_INFO_STREAM(msg)
Definition: ttklogger.h:74
The class of the music meta.
#define TTK_RECORD_FILE
static constexpr int WRITE_FILE_ERROR
#define SEEK_SET
Definition: zip.c:88
static constexpr int OPEN_FILE_ERROR
QAudioInput QtAudioInput
static constexpr int SAVE_FILE_ERROR
MusicAudioRecorderModule(QObject *parent=nullptr)
#define const
Definition: zconf.h:233
#define TTK_ERROR_STREAM(msg)
Definition: ttklogger.h:76