File indexing completed on 2024-04-28 16:06:20
0001 /* AUDEX CDDA EXTRACTOR 0002 * SPDX-FileCopyrightText: Copyright (C) 2007 Marco Nelles 0003 * <https://userbase.kde.org/Audex> 0004 * 0005 * SPDX-License-Identifier: GPL-3.0-or-later 0006 */ 0007 0008 #include "wavefilewriter.h" 0009 0010 #include <QDebug> 0011 0012 WaveFileWriter::WaveFileWriter() 0013 { 0014 p_data_written = 0; 0015 p_endianess = LittleEndian; 0016 } 0017 0018 WaveFileWriter::~WaveFileWriter() 0019 { 0020 close(); 0021 } 0022 0023 bool WaveFileWriter::open(const QString &filename) 0024 { 0025 close(); 0026 0027 p_data_written = 0; 0028 0029 p_output_file.setFileName(filename); 0030 if (p_output_file.open(QIODevice::WriteOnly)) { 0031 p_filename = filename; 0032 p_write_empty_header(); 0033 return true; 0034 } else { 0035 return false; 0036 } 0037 } 0038 0039 bool WaveFileWriter::isOpen() 0040 { 0041 return p_output_file.isOpen(); 0042 } 0043 0044 QString WaveFileWriter::filename() const 0045 { 0046 return p_filename; 0047 } 0048 0049 void WaveFileWriter::setEndianess(const Endianess e) 0050 { 0051 p_endianess = e; 0052 } 0053 0054 WaveFileWriter::Endianess WaveFileWriter::endianess() 0055 { 0056 return p_endianess; 0057 } 0058 0059 void WaveFileWriter::close() 0060 { 0061 if (isOpen()) { 0062 if (p_data_written) { 0063 // update wave header 0064 p_update_header(); 0065 p_output_file.close(); 0066 } else { 0067 p_output_file.close(); 0068 p_output_file.remove(); 0069 } 0070 } 0071 p_filename.clear(); 0072 } 0073 0074 void WaveFileWriter::write(const QByteArray &data) 0075 { 0076 int len = data.size(); 0077 if (isOpen()) { 0078 if (p_endianess == LittleEndian) { 0079 qint64 ret = p_output_file.write(data); 0080 if (ret == -1) { 0081 Q_EMIT error(p_output_file.errorString()); 0082 return; 0083 } 0084 } else { 0085 if (data.size() % 2 > 0) { 0086 qDebug() << "Data length is not a multiple of 2! Cannot write data."; 0087 return; 0088 } 0089 // we need to swap the bytes 0090 char *buffer = new char[len]; 0091 for (int i = 0; i < len - 1; i += 2) { 0092 buffer[i] = data.data()[i + 1]; 0093 buffer[i + 1] = data.data()[i]; 0094 } 0095 p_output_file.write(buffer, len); 0096 delete[] buffer; 0097 } 0098 p_data_written += len; 0099 } 0100 } 0101 0102 void WaveFileWriter::p_write_empty_header() 0103 { 0104 static const unsigned char riffHeader[] = { 0105 0x52, 0x49, 0x46, 0x46, // 0 "RIFF" 0106 0x00, 0x00, 0x00, 0x00, // 4 wavSize 0107 0x57, 0x41, 0x56, 0x45, // 8 "WAVE" 0108 0x66, 0x6d, 0x74, 0x20, // 12 "fmt " 0109 0x10, 0x00, 0x00, 0x00, // 16 0110 0x01, 0x00, 0x02, 0x00, // 20 0111 0x44, 0xac, 0x00, 0x00, // 24 0112 0x10, 0xb1, 0x02, 0x00, // 28 0113 0x04, 0x00, 0x10, 0x00, // 32 0114 0x64, 0x61, 0x74, 0x61, // 36 "data" 0115 0x00, 0x00, 0x00, 0x00 // 40 byteCount 0116 }; 0117 p_output_file.write((char *)riffHeader, 44); 0118 } 0119 0120 void WaveFileWriter::p_update_header() 0121 { 0122 if (isOpen()) { 0123 p_output_file.flush(); 0124 0125 char c[4]; 0126 qint32 wavSize = p_data_written + 44 - 8; 0127 0128 // jump to the wavSize position in the header 0129 0130 p_output_file.seek(4); 0131 c[0] = (wavSize >> 0) & 0xff; 0132 c[1] = (wavSize >> 8) & 0xff; 0133 c[2] = (wavSize >> 16) & 0xff; 0134 c[3] = (wavSize >> 24) & 0xff; 0135 p_output_file.write(c, 4); 0136 0137 p_output_file.seek(40); 0138 c[0] = (p_data_written >> 0) & 0xff; 0139 c[1] = (p_data_written >> 8) & 0xff; 0140 c[2] = (p_data_written >> 16) & 0xff; 0141 c[3] = (p_data_written >> 24) & 0xff; 0142 p_output_file.write(c, 4); 0143 0144 // jump back to the end 0145 p_output_file.seek(p_output_file.size()); 0146 } 0147 }