File: sample_list_test.c

package info (click to toggle)
libinstpatch 1.0.0-4
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 8,148 kB
  • ctags: 7,030
  • sloc: ansic: 37,958; sh: 10,747; makefile: 361; python: 27
file content (194 lines) | stat: -rw-r--r-- 6,673 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/*
 * sample_list_test.c - Tests sample edit lists and virtual sample store
 *
 * - Creates double stereo format test waveform with triangle wave in left
 *   channel and sine wave in right channel
 * - Re-constructs both channels using 2 sample lists using various list
 *   operations
 * - Creates virtual sample store using double stereo format with left
 *   and right sample lists
 * - Duplicates virtual sample store to a double stereo format store
 * - Compares final duplicated store to original waveform and makes sure its
 *   the same
 *
 * libInstPatch
 * Copyright (C) 1999-2010 Joshua "Element" Green <jgreen@users.sourceforge.net>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; version 2.1
 * of the License only.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA or point your web browser to http://www.gnu.org.
 */
#include <libinstpatch/libinstpatch.h>
#include <math.h>

#define DEFAULT_AUDIO_SIZE	(32 * 1024)	/* default test waveform size in samples */
#define WAVEFORM_PERIOD		1684		/* something to exercise LSB bytes too */
#define MAX_DIFF_ALLOWED	0.0		/* maximum difference allowed */

#define WAVEFORM_QUARTER	(WAVEFORM_PERIOD / 4)


static int test_size = DEFAULT_AUDIO_SIZE;
static gboolean verbose = FALSE;

static GOptionEntry entries[] =
{
  { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Be verbose", NULL },
  { NULL }
};

int main (int argc, char *argv[])
{
  IpatchSampleStore *store, *vstore, *finstore;
  IpatchSampleList *rlist, *llist;
  IpatchSampleData *data, *vdata;
  double *dwave, *findata;
  guint periodpos;
  double d, maxdiff;
  int i, maxindex;
  GError *error = NULL;
  GOptionContext *context;
  int test_size_q;

  context = g_option_context_new ("- test libInstPatch sample edit list functions");
  g_option_context_add_main_entries (context, entries, "sample_list_test");

  if (!g_option_context_parse (context, &argc, &argv, &error))
  {
    printf ("Failed to parse command line arguments: %s\n",
	    ipatch_gerror_message (error));
    return 1;
  }

  g_option_context_free (context);

  test_size_q = test_size / 4;	/* test size quarter */

  ipatch_init ();

  /* allocate audio buffer (double format stereo) */
  dwave = g_new (double, test_size * 2);	/* ++ alloc */

  /* generate triangle waveform for left channel and sine wave for right */
  for (i = 0; i < test_size * 2; i += 2)
  {
    periodpos = i % WAVEFORM_PERIOD;

    if (periodpos <= WAVEFORM_QUARTER)
      dwave[i] = periodpos / (double)WAVEFORM_QUARTER;
    else if (periodpos <= WAVEFORM_QUARTER * 3)
      dwave[i] = -((periodpos - WAVEFORM_QUARTER) / (double)WAVEFORM_QUARTER - 1.0);
    else dwave[i] = (periodpos - WAVEFORM_QUARTER * 3) / (double)WAVEFORM_QUARTER - 1.0;

    dwave[i + 1] = sin ((periodpos / (double)WAVEFORM_PERIOD) * G_PI * 2.0);
  }

  data = ipatch_sample_data_new (test_size);	/* ++ ref */

  /* ++ ref - create sample store object for original waveform */
  store = ipatch_sample_store_new (IPATCH_TYPE_SAMPLE_STORE_RAM, data,
				   "format", IPATCH_SAMPLE_DOUBLE
				   | IPATCH_SAMPLE_STEREO
				   | IPATCH_SAMPLE_ENDIAN_HOST,
				   "location", dwave,
				   "active", TRUE,
				   NULL);

  rlist = ipatch_sample_list_new ();

  /* re-construct right channel in a very inefficient way ;) */
  ipatch_sample_list_prepend (rlist, store, test_size_q * 2, test_size_q,
			      IPATCH_SAMPLE_LIST_CHAN_RIGHT);
  ipatch_sample_list_prepend (rlist, store, 0, test_size_q,
			      IPATCH_SAMPLE_LIST_CHAN_RIGHT);
  ipatch_sample_list_insert_index (rlist, 1, store, test_size_q, test_size_q,
				   IPATCH_SAMPLE_LIST_CHAN_RIGHT);
  ipatch_sample_list_append (rlist, store, test_size_q * 3, test_size_q,
			     IPATCH_SAMPLE_LIST_CHAN_RIGHT);
  /* cut a segment out which overlaps segments and then re-insert the cut seg */
  ipatch_sample_list_cut (rlist, test_size_q + test_size_q / 2, test_size_q);
  ipatch_sample_list_insert (rlist, test_size_q + test_size_q / 2,
			     store, test_size_q + test_size_q / 2,
			     test_size_q, IPATCH_SAMPLE_LIST_CHAN_RIGHT);

  llist = ipatch_sample_list_new ();

  /* have fun with left channel too */
  ipatch_sample_list_append (llist, store, 0, test_size,
			     IPATCH_SAMPLE_LIST_CHAN_LEFT);
  ipatch_sample_list_cut (llist, test_size_q, test_size_q);
  ipatch_sample_list_insert (llist, test_size_q, store, test_size_q,
			     test_size_q, IPATCH_SAMPLE_LIST_CHAN_LEFT);

  vdata = ipatch_sample_data_new (test_size);	/* ++ ref */

  /* ++ ref - create virtual store from left and right sample lists */
  vstore = ipatch_sample_store_new (IPATCH_TYPE_SAMPLE_STORE_VIRTUAL, vdata,
				    "format", IPATCH_SAMPLE_DOUBLE
				    | IPATCH_SAMPLE_STEREO
				    | IPATCH_SAMPLE_ENDIAN_HOST,
				    NULL);
  ipatch_sample_store_virtual_set_list (vstore, 0, llist);
  ipatch_sample_store_virtual_set_list (vstore, 1, rlist);
  ipatch_sample_store_activate (vstore);

  /* ++ ref - Duplicate store to render final waveform */
  finstore = ipatch_sample_store_duplicate (vstore, IPATCH_TYPE_SAMPLE_STORE_RAM,
					    IPATCH_SAMPLE_DOUBLE
					    | IPATCH_SAMPLE_STEREO
					    | IPATCH_SAMPLE_ENDIAN_HOST, &error);
  if (!finstore)
  {
    printf ("Failed to create new duplicate sample store: %s",
	    ipatch_gerror_message (error));
    return 1;
  }

  findata = ipatch_sample_store_RAM_get_location (finstore);

  /* compare final waveform against original */
  for (i = 0, maxdiff = 0.0, maxindex = 0; i < test_size * 2; i++)
  {
    d = dwave[i] - findata[i];
    if (d < 0.0) d = -d;

    if (d > maxdiff)
    {
      maxdiff = d;
      maxindex = i;
    }
  }

  /* free up objects and data (for memcheck) */
  g_object_unref (data);
  g_object_unref (vdata);
  g_object_unref (store);
  g_object_unref (vstore);
  g_object_unref (finstore);
  g_free (dwave);

  if (maxdiff > MAX_DIFF_ALLOWED)
  {
    printf ("Sample list test failed: maxdiff=%0.16f index=%d\n",
	    maxdiff, maxindex);
    return 1;
  }

  if (verbose)
    printf ("Sample list test passed: maxdiff=%0.16f index=%d\n",
	    maxdiff, maxindex);
  else printf ("Sample list and virtual sample store test passed\n");

  return 0;
}