| 
									
										
										
										
											2015-05-24 06:55:12 +02:00
										 |  |  | // Copyright 2008 Dolphin Emulator Project
 | 
					
						
							| 
									
										
										
										
											2015-05-18 01:08:10 +02:00
										 |  |  | // Licensed under GPLv2+
 | 
					
						
							| 
									
										
										
										
											2013-04-17 23:09:55 -04:00
										 |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | #include <string>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "AudioCommon/WaveFile.h"
 | 
					
						
							| 
									
										
										
										
											2016-11-27 22:31:48 +01:00
										 |  |  | #include "Common/CommonFuncs.h"
 | 
					
						
							| 
									
										
										
										
											2014-09-07 20:06:58 -05:00
										 |  |  | #include "Common/CommonTypes.h"
 | 
					
						
							| 
									
										
										
										
											2015-09-26 17:13:07 -04:00
										 |  |  | #include "Common/Logging/Log.h"
 | 
					
						
							| 
									
										
										
										
											2016-10-07 22:55:13 +02:00
										 |  |  | #include "Common/MsgHandler.h"
 | 
					
						
							| 
									
										
										
										
											2016-11-27 22:31:48 +01:00
										 |  |  | #include "Common/StringUtil.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-08 13:51:00 -05:00
										 |  |  | #include "Core/ConfigManager.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-02 20:00:48 -05:00
										 |  |  | constexpr size_t WaveFileWriter::BUFFER_SIZE; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-02 20:00:48 -05:00
										 |  |  | WaveFileWriter::WaveFileWriter() | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | WaveFileWriter::~WaveFileWriter() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   Stop(); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | bool WaveFileWriter::Start(const std::string& filename, unsigned int HLESampleRate) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-12-17 22:35:27 -05:00
										 |  |  |   // Ask to delete file
 | 
					
						
							|  |  |  |   if (File::Exists(filename)) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-01-08 13:51:00 -05:00
										 |  |  |     if (SConfig::GetInstance().m_DumpAudioSilent || | 
					
						
							|  |  |  |         AskYesNoT("Delete the existing file '%s'?", filename.c_str())) | 
					
						
							| 
									
										
										
										
											2016-12-17 22:35:27 -05:00
										 |  |  |     { | 
					
						
							|  |  |  |       File::Delete(filename); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       // Stop and cancel dumping the audio
 | 
					
						
							|  |  |  |       return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // Check if the file is already open
 | 
					
						
							|  |  |  |   if (file) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     PanicAlertT("The file %s was already open, the file header will not be written.", | 
					
						
							|  |  |  |                 filename.c_str()); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   file.Open(filename, "wb"); | 
					
						
							|  |  |  |   if (!file) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     PanicAlertT("The file %s could not be opened for writing. Please check if it's already opened " | 
					
						
							|  |  |  |                 "by another program.", | 
					
						
							|  |  |  |                 filename.c_str()); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   audio_size = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-11 18:52:45 -04:00
										 |  |  |   if (basename.empty()) | 
					
						
							|  |  |  |     SplitPath(filename, nullptr, &basename, nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   current_sample_rate = HLESampleRate; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // -----------------
 | 
					
						
							|  |  |  |   // Write file header
 | 
					
						
							|  |  |  |   // -----------------
 | 
					
						
							|  |  |  |   Write4("RIFF"); | 
					
						
							|  |  |  |   Write(100 * 1000 * 1000);  // write big value in case the file gets truncated
 | 
					
						
							|  |  |  |   Write4("WAVE"); | 
					
						
							|  |  |  |   Write4("fmt "); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Write(16);          // size of fmt block
 | 
					
						
							|  |  |  |   Write(0x00020001);  // two channels, uncompressed
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const u32 sample_rate = HLESampleRate; | 
					
						
							|  |  |  |   Write(sample_rate); | 
					
						
							|  |  |  |   Write(sample_rate * 2 * 2);  // two channels, 16bit
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Write(0x00100004); | 
					
						
							|  |  |  |   Write4("data"); | 
					
						
							|  |  |  |   Write(100 * 1000 * 1000 - 32); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // We are now at offset 44
 | 
					
						
							|  |  |  |   if (file.Tell() != 44) | 
					
						
							|  |  |  |     PanicAlert("Wrong offset: %lld", (long long)file.Tell()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return true; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void WaveFileWriter::Stop() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // u32 file_size = (u32)ftello(file);
 | 
					
						
							|  |  |  |   file.Seek(4, SEEK_SET); | 
					
						
							|  |  |  |   Write(audio_size + 36); | 
					
						
							| 
									
										
										
										
											2009-03-28 08:57:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   file.Seek(40, SEEK_SET); | 
					
						
							|  |  |  |   Write(audio_size); | 
					
						
							| 
									
										
										
										
											2009-03-28 08:57:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   file.Close(); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void WaveFileWriter::Write(u32 value) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   file.WriteArray(&value, 1); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | void WaveFileWriter::Write4(const char* ptr) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   file.WriteBytes(ptr, 4); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-11 18:52:45 -04:00
										 |  |  | void WaveFileWriter::AddStereoSamplesBE(const short* sample_data, u32 count, int sample_rate) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (!file) | 
					
						
							|  |  |  |     PanicAlertT("WaveFileWriter - file not open."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (count > BUFFER_SIZE * 2) | 
					
						
							|  |  |  |     PanicAlert("WaveFileWriter - buffer too small (count = %u).", count); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (skip_silence) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     bool all_zero = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (u32 i = 0; i < count * 2; i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (sample_data[i]) | 
					
						
							|  |  |  |         all_zero = false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (all_zero) | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (u32 i = 0; i < count; i++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     // Flip the audio channels from RL to LR
 | 
					
						
							|  |  |  |     conv_buffer[2 * i] = Common::swap16((u16)sample_data[2 * i + 1]); | 
					
						
							|  |  |  |     conv_buffer[2 * i + 1] = Common::swap16((u16)sample_data[2 * i]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-11 18:52:45 -04:00
										 |  |  |   if (sample_rate != current_sample_rate) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     Stop(); | 
					
						
							|  |  |  |     file_index++; | 
					
						
							|  |  |  |     std::stringstream filename; | 
					
						
							|  |  |  |     filename << File::GetUserPath(D_DUMPAUDIO_IDX) << basename << file_index << ".wav"; | 
					
						
							|  |  |  |     Start(filename.str(), sample_rate); | 
					
						
							|  |  |  |     current_sample_rate = sample_rate; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-06-30 20:43:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   file.WriteBytes(conv_buffer.data(), count * 4); | 
					
						
							|  |  |  |   audio_size += count * 4; | 
					
						
							| 
									
										
										
										
											2016-06-11 18:52:45 -04:00
										 |  |  | } |