diff --git a/firmware/application/capture_thread.hpp b/firmware/application/capture_thread.hpp index e6e489322..792af1957 100644 --- a/firmware/application/capture_thread.hpp +++ b/firmware/application/capture_thread.hpp @@ -24,8 +24,6 @@ #include "ch.h" -#include "file.hpp" - #include "event_m0.hpp" #include "portapack_shared_memory.hpp" @@ -33,7 +31,9 @@ #include "hackrf_gpio.hpp" using namespace hackrf::one; -#include <cstring> +#include <cstdint> +#include <cstddef> +#include <utility> class Writer { public: @@ -41,107 +41,6 @@ public: virtual ~Writer() = default; }; -class RawFileWriter : public Writer { -public: - RawFileWriter( - const std::string& filename - ) : file { filename, File::openmode::out | File::openmode::binary | File::openmode::trunc } - { - } - - bool write(const void* const buffer, const size_t bytes) override { - return file.write(buffer, bytes); - } - -private: - File file; -}; - -class WAVFileWriter : public Writer { -public: - WAVFileWriter( - const std::string& filename, - size_t sampling_rate - ) : file { filename, File::openmode::out | File::openmode::binary | File::openmode::trunc }, - header { sampling_rate } - { - update_header(); - } - - ~WAVFileWriter() { - update_header(); - } - - bool write(const void* const buffer, const size_t bytes) override { - const auto success = file.write(buffer, bytes) ; - if( success ) { - bytes_written += bytes; - } - return success; - } - -private: - struct fmt_pcm_t { - constexpr fmt_pcm_t( - const uint32_t sampling_rate - ) : nSamplesPerSec { sampling_rate }, - nAvgBytesPerSec { nSamplesPerSec * nBlockAlign } - { - } - - private: - const uint8_t ckID[4] { 'f', 'm', 't', ' ' }; - const uint32_t cksize { 16 }; - const uint16_t wFormatTag { 0x0001 }; - const uint16_t nChannels { 1 }; - const uint32_t nSamplesPerSec; - const uint32_t nAvgBytesPerSec; - const uint16_t nBlockAlign { 2 }; - const uint16_t wBitsPerSample { 16 }; - }; - - struct data_t { - void set_size(const uint32_t value) { - cksize = value; - } - - private: - const uint8_t ckID[4] { 'd', 'a', 't', 'a' }; - uint32_t cksize { 0 }; - }; - - struct header_t { - constexpr header_t( - const uint32_t sampling_rate - ) : fmt { sampling_rate } - { - } - - void set_data_size(const uint32_t value) { - data.set_size(value); - cksize = sizeof(header_t) + value - 8; - } - - private: - const uint8_t riff_id[4] { 'R', 'I', 'F', 'F' }; - uint32_t cksize { 0 }; - const uint8_t wave_id[4] { 'W', 'A', 'V', 'E' }; - fmt_pcm_t fmt; - data_t data; - }; - - File file; - header_t header; - uint64_t bytes_written { 0 }; - - void update_header() { - header.set_data_size(bytes_written); - const auto old_position = file.seek(0); - file.write(&header, sizeof(header)); - file.seek(old_position); - } -}; - class StreamOutput { public: StreamOutput( diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index d92a0fa66..3f905f063 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -30,6 +30,109 @@ using namespace portapack; #include "string_format.hpp" #include "utility.hpp" +#include <cstdint> + +class RawFileWriter : public Writer { +public: + RawFileWriter( + const std::string& filename + ) : file { filename, File::openmode::out | File::openmode::binary | File::openmode::trunc } + { + } + + bool write(const void* const buffer, const size_t bytes) override { + return file.write(buffer, bytes); + } + +private: + File file; +}; + +class WAVFileWriter : public Writer { +public: + WAVFileWriter( + const std::string& filename, + size_t sampling_rate + ) : file { filename, File::openmode::out | File::openmode::binary | File::openmode::trunc }, + header { sampling_rate } + { + update_header(); + } + + ~WAVFileWriter() { + update_header(); + } + + bool write(const void* const buffer, const size_t bytes) override { + const auto success = file.write(buffer, bytes) ; + if( success ) { + bytes_written += bytes; + } + return success; + } + +private: + struct fmt_pcm_t { + constexpr fmt_pcm_t( + const uint32_t sampling_rate + ) : nSamplesPerSec { sampling_rate }, + nAvgBytesPerSec { nSamplesPerSec * nBlockAlign } + { + } + + private: + const uint8_t ckID[4] { 'f', 'm', 't', ' ' }; + const uint32_t cksize { 16 }; + const uint16_t wFormatTag { 0x0001 }; + const uint16_t nChannels { 1 }; + const uint32_t nSamplesPerSec; + const uint32_t nAvgBytesPerSec; + const uint16_t nBlockAlign { 2 }; + const uint16_t wBitsPerSample { 16 }; + }; + + struct data_t { + void set_size(const uint32_t value) { + cksize = value; + } + + private: + const uint8_t ckID[4] { 'd', 'a', 't', 'a' }; + uint32_t cksize { 0 }; + }; + + struct header_t { + constexpr header_t( + const uint32_t sampling_rate + ) : fmt { sampling_rate } + { + } + + void set_data_size(const uint32_t value) { + data.set_size(value); + cksize = sizeof(header_t) + value - 8; + } + + private: + const uint8_t riff_id[4] { 'R', 'I', 'F', 'F' }; + uint32_t cksize { 0 }; + const uint8_t wave_id[4] { 'W', 'A', 'V', 'E' }; + fmt_pcm_t fmt; + data_t data; + }; + + File file; + header_t header; + uint64_t bytes_written { 0 }; + + void update_header() { + header.set_data_size(bytes_written); + const auto old_position = file.seek(0); + file.write(&header, sizeof(header)); + file.seek(old_position); + } +}; + namespace ui { RecordView::RecordView(