add time command parameters to rtl_raw2wav

Signed-off-by: hayati ayguen <h_ayguen@web.de>
development
hayati ayguen 2019-09-15 09:12:17 +00:00
parent 5abec7f328
commit f0b84e010c
6 changed files with 261 additions and 24 deletions

View File

@ -183,6 +183,7 @@ if(UNIX)
target_link_libraries(rtl_ir m)
target_link_libraries(rtl_adsb m)
target_link_libraries(rtl_power m)
target_link_libraries(rtl_raw2wav m)
if(APPLE)
target_link_libraries(rtl_test m)
else()
@ -200,7 +201,7 @@ if(WIN32)
target_link_libraries(rtl_eeprom libgetopt_static)
target_link_libraries(rtl_adsb libgetopt_static)
target_link_libraries(rtl_power libgetopt_static)
target_link_libraries(rtl_raw2wav libgetopt_static)
target_link_libraries(rtl_raw2wav libgetopt_static m)
set_property(TARGET rtl_sdr APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" )
set_property(TARGET rtl_tcp APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" )
set_property(TARGET rtl_udp APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" )

View File

@ -119,6 +119,122 @@ double atofp(char *s)
return atof(s);
}
static struct tm * str_to_tm( const char * str, struct tm * t, double * fraction ) {
char b[16];
int k, v;
/* 0 1 2 */
/* 01234567890123456789012 */
/* 2019-09-15T01:53:20.234 - mostly ISO 8601 */
*fraction = 0.0;
t->tm_sec = 0;
t->tm_min = 0;
t->tm_hour = 0;
t->tm_mday = 1;
t->tm_mon = 0;
t->tm_year = 0;
t->tm_wday = 0;
t->tm_yday = 0;
t->tm_isdst = -1;
/* date */
if ( (str[4] == '-' || str[4] == '/') && str[4] == str[7] ) {
/* year */
b[4] = 0; for ( k = 0; k < 4; ++k ) b[k] = str[k];
v = atoi(b);
t->tm_year = v - 1900;
/* month */
b[2] = 0; for ( k = 0; k < 2; ++k ) b[k] = str[5+k];
v = atoi(b);
if (v < 1 || v > 12)
return NULL;
t->tm_mon = v - 1;
/* day */
b[2] = 0; for ( k = 0; k < 2; ++k ) b[k] = str[8+k];
v = atoi(b);
if (v < 1 || v > 31)
return NULL;
t->tm_mday = v;
} else
return NULL;
if (str[10] == 0 )
return t;
/* time */
if ( str[10] != 'T' && str[10] != ' ' && str[10] != '_' )
return NULL;
if ( (str[13] == ':' || str[13] == '/') && str[13] == str[16] ) {
/* hour */
b[2] = 0; for ( k = 0; k < 2; ++k ) b[k] = str[11+k];
v = atoi(b);
if (v < 0 || v > 23)
return NULL;
t->tm_hour = v;
/* minute */
b[2] = 0; for ( k = 0; k < 2; ++k ) b[k] = str[14+k];
v = atoi(b);
if (v < 0 || v > 59)
return NULL;
t->tm_min = v;
/* second */
b[2] = 0; for ( k = 0; k < 2; ++k ) b[k] = str[17+k];
v = atoi(b);
if (v < 0 || v > 61)
return NULL;
t->tm_sec = v;
} else
return NULL;
if (str[19] == 0 )
return t;
/* fraction */
if ( str[19] == '.' && str[19] == ',' ) {
for ( k = 0; k < 16; ++k ) b[k] = 0;
strcpy(b, "0.");
strncpy(&b[2], &str[20], 12);
*fraction = atof(b);
return t;
}
/* return t anyway .. without fraction */
return t;
}
time_t utctimestr_to_time(const char * str, double * fraction) {
struct tm t;
struct tm *p;
p = str_to_tm( str, &t, fraction );
if (!p)
return 0;
#ifndef _WIN32
return timegm(p);
#else
return _mkgmtime(p);
#endif
}
time_t localtimestr_to_time(const char * str, double * fraction) {
struct tm t;
struct tm *p;
p = str_to_tm( str, &t, fraction );
if (!p)
return 0;
#ifndef _WIN32
return timelocal(p);
#else
return mktime(p);
#endif
}
#ifndef _WIN32
void executeInBackground( char * file, char * args, char * searchStr[], char * replaceStr[] )

View File

@ -19,6 +19,7 @@
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#ifdef __cplusplus
extern "C" {
@ -54,6 +55,10 @@ double atoft(char *s);
double atofp(char *s);
time_t utctimestr_to_time(const char * str, double * fraction);
time_t localtimestr_to_time(const char * str, double * fraction);
void executeInBackground( char * file, char * args, char * searchStr[], char * replaceStr[] );

View File

@ -96,7 +96,8 @@ static waveFileHeader waveHdr;
static uint32_t waveDataSize = 0;
int waveHdrStarted = 0;
void waveSetTime(Wind_SystemTime *p)
static void waveSetCurrTime(Wind_SystemTime *p)
{
struct timeval tv;
struct tm t;
@ -119,6 +120,28 @@ void waveSetTime(Wind_SystemTime *p)
p->wSecond = t.tm_sec; /* 0 .. 59 */
}
static void waveSetStartTimeInt(time_t tim, double fraction, Wind_SystemTime *p)
{
struct tm t = *gmtime( &tim );
p->wYear = t.tm_year + 1900; /* 1601 through 30827 */
p->wMonth = t.tm_mon + 1; /* 1..12 */
p->wDayOfWeek = t.tm_wday; /* 0 .. 6: 0 == Sunday, .., 6 == Saturday */
p->wDay = t.tm_mday; /* 1 .. 31 */
p->wHour = t.tm_hour; /* 0 .. 23 */
p->wMinute = t.tm_min; /* 0 .. 59 */
p->wSecond = t.tm_sec; /* 0 .. 59 */
p->wMilliseconds = (int)( fraction * 1000.0 );
if (p->wMilliseconds >= 1000)
p->wMilliseconds = 999;
}
void waveSetStartTime(time_t tim, double fraction)
{
waveSetStartTimeInt(tim, fraction, &waveHdr.StartTime );
waveHdr.StopTime = waveHdr.StartTime; /* to fix */
}
void wavePrepareHeader(unsigned samplerate, unsigned freq, int bitsPerSample, int numChannels)
{
int bytesPerSample = bitsPerSample / 8;
@ -139,7 +162,7 @@ void wavePrepareHeader(unsigned samplerate, unsigned freq, int bitsPerSample, in
strncpy( waveHdr.auxiID, "auxi", 4 );
waveHdr.auxiSize = 2 * sizeof(Wind_SystemTime) + 9 * sizeof(int32_t); /* = 2 * 16 + 9 * 4 = 68 */
waveSetTime( &waveHdr.StartTime );
waveSetCurrTime( &waveHdr.StartTime );
waveHdr.StopTime = waveHdr.StartTime; /* to fix */
waveHdr.centerFreq = freq;
waveHdr.ADsamplerate = samplerate;
@ -221,7 +244,7 @@ int waveFinalizeHeader(FILE * f)
{
if (f != stdout) {
assert( waveHdrStarted );
waveSetTime( &waveHdr.StopTime );
waveSetCurrTime( &waveHdr.StopTime );
waveHdr.dataSize = waveDataSize;
waveHdr.riffSize += waveDataSize;

View File

@ -19,6 +19,7 @@
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#ifdef __cplusplus
extern "C" {
@ -44,6 +45,7 @@ void waveWriteHeader(unsigned samplerate, unsigned freq, int bitsPerSample, int
*/
int waveWriteFrames(FILE* f, void * vpData, size_t numFrames, int needCleanData);
int waveWriteSamples(FILE* f, void * vpData, size_t numSamples, int needCleanData); /* returns 0, when no errors occured */
void waveSetStartTime(time_t t, double fraction);
int waveFinalizeHeader(FILE * f); /* returns 0, when no errors occured */
#ifdef __cplusplus

View File

@ -21,18 +21,25 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#ifndef _WIN32
#include <unistd.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#else
#include <windows.h>
#include <fcntl.h>
#include <io.h>
#include "getopt/getopt.h"
#if defined(_MSC_VER) && (_MSC_VER < 1900)
#define snprintf _snprintf
#endif
#include <windows.h>
#include <fcntl.h>
#include <io.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "getopt/getopt.h"
#if defined(_MSC_VER) && (_MSC_VER < 1900)
#define snprintf _snprintf
#endif
#endif
#include "convenience/convenience.h"
@ -58,6 +65,8 @@ void usage(void)
"\t-s samplerate samplerate, of raw input\n"
"\t-c #channels number of channels, default: 2 - for I and Q\n"
"\t-b #bits number of bits per sample, default: 8 - 8 or 16 allowed\n"
"\t-u time set start time in UTC: 'yyy-mm-ddThh:mm:dd.zzz'\n"
"\t-t time set start time in localtime: 'yyy-mm-ddThh:mm:dd.zzz'\n"
"\t-v verbose output\n"
"\t-r filename input filename for raw samples, default: - for stdin\n\n" );
}
@ -100,8 +109,11 @@ int main(int argc, char **argv)
char acBuf[ 65536 * sizeof(int16_t) * 2 ]; /* 64 K frames with 2 channels and 16 Bit */
size_t smpSize;
size_t nRead;
time_t tim = 0;
double fraction = 0.0;
int haveTime = 0;
while ((opt = getopt(argc, argv, "f:s:c:b:r:w:vh")) != -1) {
while ((opt = getopt(argc, argv, "f:s:c:b:r:u:t:w:vh")) != -1) {
switch (opt) {
case 'f': freq = (uint32_t)atofs(optarg); break;
case 's': srate = (uint32_t)atofs(optarg); break;
@ -109,6 +121,12 @@ int main(int argc, char **argv)
case 'b': nBits = 8 * atoi(optarg); break;
case 'v': ++verbosity; break;
case 'r': rawfilename = optarg; break;
case 'u': tim = utctimestr_to_time(optarg, &fraction);
if (tim) haveTime = 1;
break;
case 't': tim = localtimestr_to_time(optarg, &fraction);
if (tim) haveTime = 1;
break;
case 'w': wavfilename = optarg; break;
case 'h':
case '?':
@ -128,18 +146,18 @@ int main(int argc, char **argv)
if (!wavfilename) {
usage();
fprintf(stderr, "error: missing output wave filename!\n");
fprintf(stderr, "Error: missing output wave filename!\n");
exit(1);
}
if (nChan < 1 || nChan > 2) {
usage();
fprintf(stderr, "error: number of channels must be 1 or 2!\n");
fprintf(stderr, "Error: number of channels must be 1 or 2!\n");
exit(1);
}
if (nBits != 8 && nBits != 16) {
usage();
fprintf(stderr, "error: number of bits per sample must be 8 or 16!\n");
fprintf(stderr, "Error: number of bits per sample must be 8 or 16!\n");
exit(1);
}
@ -155,52 +173,124 @@ int main(int argc, char **argv)
SetConsoleCtrlHandler( (PHANDLER_ROUTINE) sighandler, TRUE );
#endif
smpSize = nChan * ( nBits == 16 ? sizeof(int16_t) : sizeof(uint8_t) );
if (verbosity >= 2)
fprintf(stderr, "Frame size = %d channels * %d bits = %d bytes\n", nChan, nBits, smpSize);
if (!rawfilename || !strcmp(rawfilename, "-")) {
#ifdef _WIN32
_setmode(_fileno(stdin), _O_BINARY);
#endif
inpfile = stdin;
if (verbosity)
fprintf(stderr, "Using stdin as input\n");
} else {
if (verbosity >= 2)
fprintf(stderr, "Opening input '%s'\n", rawfilename);
inpfile = fopen(rawfilename, "rb");
if (!inpfile) {
fprintf(stderr, "error: Failed to open input %s\n", rawfilename);
fprintf(stderr, "Error: Failed to open input %s\n", rawfilename);
exit(1);
}
if (verbosity)
fprintf(stderr, "Opened '%s' for input\n", rawfilename);
if (!haveTime) {
int gotmodtim = 0;
#ifdef _WIN32
struct _stat attr;
if (!_stat(rawfilename, &attr)) {
tim = attr.st_mtime;
fraction = 0.0;
gotmodtim = 1;
}
#else
struct stat attr;
if (!stat(rawfilename, &attr)) {
tim = attr.st_mtime;
fraction = attr.st_mtim.tv_nsec / 1E9;
gotmodtim = 1;
}
#endif
if (gotmodtim) {
long fs = 0;
if (verbosity >= 2)
fprintf(stderr, "Got 'last modified' from input file '%s'\n", rawfilename);
if (!fseek(inpfile, 0, SEEK_END)) {
fs = ftell(inpfile);
if (fs > 0) {
double dur = (double)(fs) / ( (double)srate * smpSize );
double di = floor(dur);
double df = dur - di;
tim -= (time_t)di;
fraction -= df;
if (fraction < 0.0) {
fraction += 1.0;
tim -= 1;
}
if (verbosity)
fprintf(stderr, "Set output's timestamp from input files 'last modified' minus duration of %f seconds\n", dur);
haveTime = 1;
}
}
fseek(inpfile, 0, SEEK_SET);
}
}
}
tempfilename = malloc( strlen(wavfilename)+8 );
strcpy(tempfilename, wavfilename);
strcat(tempfilename, ".tmp");
if (verbosity >= 2)
fprintf(stderr, "Opening output '%s'\n", tempfilename);
outfile = fopen(tempfilename, "wb");
if (!outfile) {
fprintf(stderr, "Error: Failed to open output %s\n", tempfilename);
fprintf(stderr, "Error: Failed to open output '%s'\n", tempfilename);
exit(1);
} else {
if (verbosity)
fprintf(stderr, "Open %s for write\n", tempfilename);
fprintf(stderr, "Opened '%s' for output\n", tempfilename);
waveWriteHeader(srate, freq, nBits, nChan, outfile);
if (haveTime) {
if (verbosity >= 2)
fprintf(stderr, "Setting start time of output file\n");
waveSetStartTime(tim, fraction);
}
}
smpSize = nChan * ( nBits == 16 ? sizeof(int16_t) : sizeof(uint8_t) );
while ( !feof(inpfile) ) {
if (do_exit) {
fprintf(stderr, "\nUser cancel, exiting...\n");
break;
}
nRead = fread(acBuf, smpSize, 65536, inpfile);
if (nRead)
if (nRead > 0)
fwrite(acBuf, smpSize, nRead, outfile);
if (verbosity >= 2)
fprintf(stderr, ".");
}
if (verbosity >= 2)
fprintf(stderr, "\nWriting output header\n");
waveFinalizeHeader(outfile);
fclose(outfile);
if (verbosity)
fprintf(stderr, "Closed output file.\n");
if (verbosity >= 2)
fprintf(stderr, "Deleting '%s' - in case it exists\n", wavfilename);
remove(wavfilename); /* delete, in case file already exists */
if (verbosity >= 2)
fprintf(stderr, "Renaming '%s' into '%s'\n", tempfilename, wavfilename);
r = rename( tempfilename, wavfilename ); /* #include <stdio.h> */
if ( r )
fprintf( stderr, "%s: error %d '%s' renaming'%s' to '%s'\n"
fprintf( stderr, "%s: Error %d '%s' renaming'%s' to '%s'\n"
, argv[0], errno, strerror(errno), tempfilename, wavfilename );
else if (verbosity)
fprintf( stderr, "Renamed output file into '%s'\n", wavfilename );
if (inpfile != stdin)
fclose(inpfile);
return 0;
}