1 // Copyright (c) Charles J. Cliffe
2 // SPDX-License-Identifier: GPL-2.0+
3 
4 #include "AudioSinkFileThread.h"
5 #include <ctime>
6 
7 #define HEARTBEAT_CHECK_PERIOD_MICROS (50 * 1000)
8 
AudioSinkFileThread()9 AudioSinkFileThread::AudioSinkFileThread() : AudioSinkThread() {
10 
11 }
12 
~AudioSinkFileThread()13 AudioSinkFileThread::~AudioSinkFileThread() {
14     if (audioFileHandler != nullptr) {
15         audioFileHandler->closeFile();
16     }
17 }
18 
sink(AudioThreadInputPtr input)19 void AudioSinkFileThread::sink(AudioThreadInputPtr input) {
20     if (!audioFileHandler) {
21         return;
22     }
23 
24 	//by default, always write something
25 	bool isSomethingToWrite = true;
26 
27 	if (input->is_squelch_active) {
28 
29 		if (squelchOption == SQUELCH_RECORD_SILENCE) {
30 
31 			//patch with "silence"
32 			input->data.assign(input->data.size(), 0.0f);
33 			input->peak = 0.0f;
34 		}
35 		else if (squelchOption == SQUELCH_SKIP_SILENCE) {
36 			isSomethingToWrite = false;
37 		}
38 	}
39 
40 	//else, nothing to do record as if squelch was not enabled.
41 
42 	if (!isSomethingToWrite) {
43 		return;
44 	}
45 
46 	if (fileTimeLimit > 0) {
47 		durationMeasurement.update();
48 
49 		//duration exeeded, close this file and create another
50 		//with "now" as timestamp.
51 		if (durationMeasurement.getSeconds() > fileTimeLimit) {
52 
53 			audioFileHandler->closeFile();
54 
55 			//initialize the filename of the AudioFile with the current time
56 			time_t t = std::time(nullptr);
57 			tm ltm = *std::localtime(&t);
58 
59 			//  GCC 5+
60 			//    fileName << "_" << std::put_time(&ltm, "%d-%m-%Y_%H-%M-%S");
61 
62 			char timeStr[512];
63 			//International format: Year.Month.Day, also lexicographically sortable
64 			strftime(timeStr, sizeof(timeStr), "%Y-%m-%d_%H-%M-%S", &ltm);
65 
66 			audioFileHandler->setOutputFileName(fileNameBase + std::string("_") + timeStr);
67 
68 			//reset duration counter
69 			durationMeasurement.start();
70 			//the following writeToFile will take care of creating another file.
71 		}
72 	}
73 
74     // forward to output file handler
75     audioFileHandler->writeToFile(input);
76 }
77 
inputChanged(AudioThreadInput,AudioThreadInputPtr)78 void AudioSinkFileThread::inputChanged(AudioThreadInput /* oldProps */, AudioThreadInputPtr /* newProps */) {
79     // close, set new parameters, adjust file name sequence and re-open?
80     if (!audioFileHandler) {
81         return;
82     }
83 
84     audioFileHandler->closeFile();
85 
86 	//reset duration counter
87 	durationMeasurement.start();
88 }
89 
setAudioFileNameBase(const std::string & baseName)90 void AudioSinkFileThread::setAudioFileNameBase(const std::string& baseName) {
91 
92 	fileNameBase = baseName;
93 }
94 
setAudioFileHandler(AudioFile * output)95 void AudioSinkFileThread::setAudioFileHandler(AudioFile * output) {
96     audioFileHandler = output;
97 
98 	//initialize the filename of the AudioFile with the current time
99 	time_t t = std::time(nullptr);
100 	tm ltm = *std::localtime(&t);
101 
102 	//  GCC 5+
103 	//    fileName << "_" << std::put_time(&ltm, "%d-%m-%Y_%H-%M-%S");
104 
105 	char timeStr[512];
106 	//International format: Year.Month.Day, also lexicographically sortable
107 	strftime(timeStr, sizeof(timeStr), "%Y-%m-%d_%H-%M-%S", &ltm);
108 
109 	audioFileHandler->setOutputFileName(fileNameBase + std::string("_") + timeStr);
110 
111 	// reset Timer
112 	durationMeasurement.start();
113 }
114 
setSquelchOption(int squelchOptEnumValue)115 void AudioSinkFileThread::setSquelchOption(int squelchOptEnumValue) {
116 
117 	if (squelchOptEnumValue == AudioSinkFileThread::SQUELCH_RECORD_SILENCE) {
118 		squelchOption = AudioSinkFileThread::SQUELCH_RECORD_SILENCE;
119 	}
120 	else if (squelchOptEnumValue == AudioSinkFileThread::SQUELCH_SKIP_SILENCE) {
121 		squelchOption = AudioSinkFileThread::SQUELCH_SKIP_SILENCE;
122 	}
123 	else if (squelchOptEnumValue == AudioSinkFileThread::SQUELCH_RECORD_ALWAYS) {
124 		squelchOption = AudioSinkFileThread::SQUELCH_RECORD_ALWAYS;
125 	}
126 	else {
127 		squelchOption = AudioSinkFileThread::SQUELCH_RECORD_SILENCE;
128 	}
129 }
130 
131 // Time limit
setFileTimeLimit(int nbSeconds)132 void AudioSinkFileThread::setFileTimeLimit(int nbSeconds) {
133 
134 	if (nbSeconds > 0) {
135 		fileTimeLimit = nbSeconds;
136 	}
137 	else {
138 		fileTimeLimit = 0;
139 	}
140 }
141