File indexing completed on 2024-04-28 04:49:54
0001 /* 0002 SPDX-FileCopyrightText: 1998-2009 Sebastian Trueg <trueg@k3b.org> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "k3bwavefilewriter.h" 0007 #include <QDebug> 0008 0009 K3b::WaveFileWriter::WaveFileWriter() 0010 : m_outputStream( &m_outputFile ) 0011 { 0012 } 0013 0014 0015 K3b::WaveFileWriter::~WaveFileWriter() 0016 { 0017 close(); 0018 } 0019 0020 0021 bool K3b::WaveFileWriter::open( const QString& filename ) 0022 { 0023 close(); 0024 0025 m_outputFile.setFileName( filename ); 0026 0027 if( m_outputFile.open( QIODevice::ReadWrite ) ) { 0028 m_filename = filename; 0029 0030 writeEmptyHeader(); 0031 0032 return true; 0033 } 0034 else { 0035 return false; 0036 } 0037 } 0038 0039 0040 void K3b::WaveFileWriter::close() 0041 { 0042 if( isOpen() ) { 0043 if( m_outputFile.pos() > 0 ) { 0044 padTo2352(); 0045 0046 // update wave header 0047 updateHeader(); 0048 0049 m_outputFile.close(); 0050 } 0051 else { 0052 m_outputFile.close(); 0053 m_outputFile.remove(); 0054 } 0055 } 0056 0057 m_filename = QString(); 0058 } 0059 0060 0061 bool K3b::WaveFileWriter::isOpen() 0062 { 0063 return m_outputFile.isOpen(); 0064 } 0065 0066 0067 const QString& K3b::WaveFileWriter::filename() const 0068 { 0069 return m_filename; 0070 } 0071 0072 0073 void K3b::WaveFileWriter::write( const char* data, int len, Endianess e ) 0074 { 0075 if( isOpen() ) { 0076 if( e == LittleEndian ) { 0077 m_outputStream.writeRawData( data, len ); 0078 } 0079 else { 0080 if( len % 2 > 0 ) { 0081 qDebug() << "(K3b::WaveFileWriter) data length (" 0082 << len << ") is not a multiple of 2! Cannot swap bytes." << Qt::endl; 0083 return; 0084 } 0085 0086 // we need to swap the bytes 0087 char* buffer = new char[len]; 0088 for( int i = 0; i < len-1; i+=2 ) { 0089 buffer[i] = data[i+1]; 0090 buffer[i+1] = data[i]; 0091 } 0092 m_outputStream.writeRawData( buffer, len ); 0093 0094 delete [] buffer; 0095 } 0096 } 0097 } 0098 0099 0100 void K3b::WaveFileWriter::writeEmptyHeader() 0101 { 0102 static const unsigned char riffHeader[] = 0103 { 0104 0x52, 0x49, 0x46, 0x46, // 0 "RIFF" 0105 0x00, 0x00, 0x00, 0x00, // 4 wavSize 0106 0x57, 0x41, 0x56, 0x45, // 8 "WAVE" 0107 0x66, 0x6d, 0x74, 0x20, // 12 "fmt " 0108 0x10, 0x00, 0x00, 0x00, // 16 0109 0x01, 0x00, 0x02, 0x00, // 20 0110 0x44, 0xac, 0x00, 0x00, // 24 0111 0x10, 0xb1, 0x02, 0x00, // 28 0112 0x04, 0x00, 0x10, 0x00, // 32 0113 0x64, 0x61, 0x74, 0x61, // 36 "data" 0114 0x00, 0x00, 0x00, 0x00 // 40 byteCount 0115 }; 0116 0117 m_outputStream.writeRawData( (const char*) riffHeader, 44 ); 0118 } 0119 0120 0121 void K3b::WaveFileWriter::updateHeader() 0122 { 0123 if( isOpen() ) { 0124 0125 m_outputFile.flush(); 0126 0127 qint32 dataSize( m_outputFile.pos() - 44 ); 0128 qint32 wavSize(dataSize + 44 - 8); 0129 char c[4]; 0130 0131 // jump to the wavSize position in the header 0132 if( m_outputFile.seek( 4 ) ) { 0133 c[0] = (wavSize >> 0 ) & 0xff; 0134 c[1] = (wavSize >> 8 ) & 0xff; 0135 c[2] = (wavSize >> 16) & 0xff; 0136 c[3] = (wavSize >> 24) & 0xff; 0137 m_outputStream.writeRawData( c, 4 ); 0138 } 0139 else 0140 qDebug() << "(K3b::WaveFileWriter) unable to seek in file: " << m_outputFile.fileName(); 0141 0142 if( m_outputFile.seek( 40 ) ) { 0143 c[0] = (dataSize >> 0 ) & 0xff; 0144 c[1] = (dataSize >> 8 ) & 0xff; 0145 c[2] = (dataSize >> 16) & 0xff; 0146 c[3] = (dataSize >> 24) & 0xff; 0147 m_outputStream.writeRawData( c, 4 ); 0148 } 0149 else 0150 qDebug() << "(K3b::WaveFileWriter) unable to seek in file: " << m_outputFile.fileName(); 0151 0152 // jump back to the end 0153 m_outputFile.seek( m_outputFile.size() ); 0154 } 0155 } 0156 0157 0158 void K3b::WaveFileWriter::padTo2352() 0159 { 0160 int bytesToPad = ( m_outputFile.pos() - 44 ) % 2352; 0161 if( bytesToPad > 0 ) { 0162 qDebug() << "(K3b::WaveFileWriter) padding wave file with " << bytesToPad << " bytes."; 0163 0164 char* c = new char[bytesToPad]; 0165 memset( c, 0, bytesToPad ); 0166 m_outputStream.writeRawData( c, bytesToPad ); 0167 delete [] c; 0168 } 0169 } 0170 0171 0172 int K3b::WaveFileWriter::fd() const 0173 { 0174 return m_outputFile.handle(); 0175 }