SDDSlib
Loading...
Searching...
No Matches
sdds2agilentArb.c File Reference

Converts SDDS files to Agilent Arbitrary Waveform files. More...

#include "SDDS.h"
#include "mdb.h"
#include "scan.h"

Go to the source code of this file.

Enumerations

enum  option_type { SET_PIPE , N_OPTIONS }
 

Functions

int main (int argc, char *argv[])
 

Variables

char * option [N_OPTIONS]
 
char * usage
 

Detailed Description

Converts SDDS files to Agilent Arbitrary Waveform files.

This program reads an SDDS file, extracts the "I" and "Q" floating-point columns, scales the data, and writes the results to an output file in a binary format compatible with Agilent arbitrary waveform generators.

Features:

  • Supports input and output via pipes.
  • Automatically scales the waveform data to fit the [-32767, 32767] range.
  • Handles little-endian to big-endian conversion if needed.

Usage:

sdds2agilentArb [<inputFile>] [<outputFile>] [-pipe[=in][,out]]

Example:

sdds2agilentArb input.sdds output.wfm

Options:

  • -pipe: Use pipes for input/output.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
R. Soliday

Definition in file sdds2agilentArb.c.

Enumeration Type Documentation

◆ option_type

enum option_type

Definition at line 43 of file sdds2agilentArb.c.

43 {
44 SET_PIPE,
45 N_OPTIONS
46};

Function Documentation

◆ main()

int main ( int argc,
char * argv[] )

Definition at line 58 of file sdds2agilentArb.c.

58 {
59 SCANNED_ARG *scanned;
60 long i_arg;
61 unsigned long pipe_flags = 0;
62 char *input = NULL, *output = NULL;
63 FILE *fd;
64 SDDS_DATASET sdds_dataset;
65
66 long points;
67 double *i_wave;
68 double *q_wave;
69 double max_amp = 0;
70 double min_amp = 0;
71 int i;
72 double scale;
73 short *waveform = NULL;
74 char buf;
75 char *p_char;
76
78 argc = scanargs(&scanned, argc, argv);
79 if (argc < 2) {
80 fprintf(stderr, "%s", usage);
81 return 1;
82 }
83 for (i_arg = 1; i_arg < argc; i_arg++) {
84 if (scanned[i_arg].arg_type == OPTION) {
85 switch (match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
86 case SET_PIPE:
87 if (!processPipeOption(scanned[i_arg].list + 1,
88 scanned[i_arg].n_items - 1, &pipe_flags)) {
89 fprintf(stderr, "invalid -pipe syntax\n");
90 return 1;
91 }
92 break;
93 default:
94 fprintf(stderr, "invalid option seen\n");
95 fprintf(stderr, "%s", usage);
96 return 1;
97 }
98 } else {
99 if (!input)
100 input = scanned[i_arg].list[0];
101 else if (!output)
102 output = scanned[i_arg].list[0];
103 else {
104 fprintf(stderr, "too many filenames\n");
105 fprintf(stderr, "%s", usage);
106 return 1;
107 }
108 }
109 }
110 processFilenames("sdds2agilentArb", &input, &output, pipe_flags, 0, NULL);
111
112 if (!SDDS_InitializeInput(&sdds_dataset, input)) {
113 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
114 }
115 if ((SDDS_CheckColumn(&sdds_dataset, "I", NULL, SDDS_ANY_FLOATING_TYPE,
116 NULL)) != SDDS_CHECK_OKAY) {
117 fprintf(stderr, "error: Floating type column named I does not exist\n");
118 return 1;
119 }
120 if ((SDDS_CheckColumn(&sdds_dataset, "Q", NULL, SDDS_ANY_FLOATING_TYPE,
121 NULL)) != SDDS_CHECK_OKAY) {
122 fprintf(stderr, "error: Floating type column named Q does not exist\n");
123 return 1;
124 }
125
126 if (SDDS_ReadTable(&sdds_dataset) != 1) {
127 fprintf(stderr, "error: No data found in SDDS file\n");
128 return 1;
129 }
130 points = SDDS_RowCount(&sdds_dataset);
131
132 i_wave = SDDS_GetColumnInDoubles(&sdds_dataset, "I");
133 q_wave = SDDS_GetColumnInDoubles(&sdds_dataset, "Q");
134 if (!SDDS_Terminate(&sdds_dataset)) {
135 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
136 exit(1);
137 }
138
139 max_amp = i_wave[0];
140 min_amp = i_wave[0];
141 for (i = 0; i < points; i++) {
142 if (max_amp < i_wave[i])
143 max_amp = i_wave[i];
144 else if (min_amp > i_wave[i])
145 min_amp = i_wave[i];
146 if (max_amp < q_wave[i])
147 max_amp = q_wave[i];
148 else if (min_amp > q_wave[i])
149 min_amp = q_wave[i];
150 }
151 max_amp = fabs(max_amp);
152 min_amp = fabs(min_amp);
153 if (min_amp > max_amp)
154 max_amp = min_amp;
155
156 scale = 32767 / max_amp;
157 waveform = malloc(sizeof(short) * points * 2);
158 for (i = 0; i < points; i++) {
159 waveform[2 * i] = (short)floor(i_wave[i] * scale + 0.5);
160 waveform[2 * i + 1] = (short)floor(q_wave[i] * scale + 0.5);
161 }
162 free(i_wave);
163 free(q_wave);
164
166 p_char = (char *)&waveform[0];
167 for (i = 0; i < 2 * points; i++) {
168 buf = *p_char;
169 *p_char = *(p_char + 1);
170 *(p_char + 1) = buf;
171 p_char += 2;
172 }
173 }
174
175 if (!output) {
176#if defined(_WIN32)
177 if (_setmode(_fileno(stdout), _O_BINARY) == -1) {
178 fprintf(stderr, "error: unable to set stdout to binary mode\n");
179 exit(1);
180 }
181#endif
182 fd = stdout;
183 } else {
184 fd = fopen(output, "wb");
185 }
186 if (fd == NULL) {
187 fprintf(stderr, "unable to open output file for writing\n");
188 exit(1);
189 }
190 fwrite((void *)waveform, sizeof(short), points * 2, fd);
191 fclose(fd);
192 if (waveform)
193 free(waveform);
194 free_scanargs(&scanned, argc);
195
196 return 0;
197}
double * SDDS_GetColumnInDoubles(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of doubles, considering only rows mark...
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_CheckColumn(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a column exists in the SDDS dataset with the specified name, units, and type.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
int32_t SDDS_IsBigEndianMachine()
Determines whether the current machine uses big-endian byte ordering.
#define SDDS_ANY_FLOATING_TYPE
Special identifier used by SDDS_Check*() routines to accept any floating-point type.
Definition SDDStypes.h:165
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:584

Variable Documentation

◆ option

char* option[N_OPTIONS]
Initial value:
=
{
"pipe"
}

Definition at line 48 of file sdds2agilentArb.c.

49 {
50 "pipe"
51 };

◆ usage

void usage
Initial value:
=
"sdds2agilentArb [<inputFile>] [<outputFile>] [-pipe[=in][,out]]\n\n"
"Converts SDDS to Agilent Arbitrary Waveform files.\n"
"Program by Robert Soliday. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n"

Definition at line 53 of file sdds2agilentArb.c.