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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>VST SDK 2.4: VST Offline Processing</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="tabs.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.4.7 -->
<div class="tabs">
<ul>
<li><a href="main.html"><span>Main Page</span></a></li>
<li><a href="namespaces.html"><span>Namespaces</span></a></li>
<li><a href="annotated.html"><span>Classes</span></a></li>
<li><a href="files.html"><span>Files</span></a></li>
<li><a href="dirs.html"><span>Directories</span></a></li>
<li><a href="pages.html"><span>Related Pages</span></a></li>
</ul></div>
<h1><a class="anchor" name="vstoffline">VST Offline Processing</a></h1> <h2>Introduction</h2>
<p>The VST offline interface is a powerful API that allows a Plug-In to freely read
audio files open in the host, to transform them or to generate new audio files.
The main features are:</p>
<ul>
<li>
The Plug-In controls reading/writing of audio samples
by sending commands to the host (this approach is the reverse of the mechanism
used in the real-time interface).
<li>
A Plug-In can read, simultaneously and with
random-access, any number of files open in the host.
<li>
A Plug-In can overwrite part or all of any open file
in the host, with random access.
<li>
A Plug-In can create one or more files (temporary
ones or not).
<li>
Any file created by the Plug-In can be freely re-read
and overwritten, with random access, during the process.
<li>
Thanks to "delayed overwriting", original samples in
source files are preserved in all cases and can be read again, at will and at
any time during a process.
<li>
Not only audio can be read/written in files: markers
can be created; sample selection can be set; edit cursor can be moved.
Moreover, custom parameters can be written along a file, with a time stamp,
and read again later, by the same Plug-In or another one.
<li>
No stereo assumption: could be used for multi-channel
files, if the host supports it.
<li>
An offline Plug-In can be used as a file transformer,
as a file analyzer or as a file generator.
<li>
An offline Plug-In does not deal directly with file
i/o and file formats: it just sends read and write commands with float
buffers, resulting in great simplification.
<li>
An offline-capable Plug-In is notified by the host anytime a change occurs in
the set of files available for editing (new open file, transformed file, new
marker created in a file, etc.). This allows the Plug-In, if necessary, to
update its user interface according to the context (e.g. new file with the
focus; or to show a list of files to pick from; etc.).</li>
</ul>
<p> </p>
<h2>Declaring an offline Plug-In</h2>
<p>The host knows if a given Plug-In supports the offline interface through the
canDo function, as follows:
</p>
<ul>
<li>
If canDo ("offline") is true, the Plug-In supports
the offline interface
<li>
If canDo ("noRealTime") is true, the Plug-In only supports the offline
interface</li>
</ul>
<h2>Overview of the interface</h2>
<p>Three structures are dedicated to the offline interface:</p>
<ul>
<li>
<code>VstOfflineTask </code>
<li>
<code>VstAudioFile</code>
<li>
<code>VstAudioFileMarker</code></li>
</ul>
<p> There are also three enums:
</p>
<ul>
<li>
<code>VstOfflineTaskFlags</code>
<li>
<code>VstAudioFileFlags</code>
<li>
<code>VstOfflineOption</code></li>
</ul>
<p>Three host opcodes are defined:</p>
<ul>
<li>
<code>audioMasterOfflineStart</code>
<li>
<code>audioMasterOfflineRead</code>
<li>
<code>audioMasterOfflineWrite</code></li>
</ul>
<p>with the corresponding functions in AudioEffectX:</p>
<ul>
<li>
<code>bool offlineStart(VstAudioFile* ptr, VstInt32 numAudioFiles, VstInt32
numNewAudioFiles);</code>
<li>
<code>bool offlineRead(VstOfflineTask* offline, VstOfflineOption option, bool
readSource = true);</code>
<li>
<code>bool offlineWrite(VstOfflineTask* offline, VstOfflineOption option);</code></li>
</ul>
<p>Three Plug-In opcodes are defined:</p>
<ul>
<li>
<code>effOfflineNotify,</code>
<li>
<code>effOfflinePrepare,</code>
<li>
<code>effOfflineRun,</code></li>
</ul>
<p>with the corresponding functions in AudioEffectX:</p>
<ul>
<li>
<code>void offlineNotify(VstAudioFile* ptr, VstInt32 numAudioFiles, bool start);</code>
<li>
<code>bool offlinePrepare(VstOfflineTask* offline, VstInt32 count);</code>
<li>
<code>bool offlineRun(VstOfflineTask* offline, VstInt32 count);</code></li>
</ul>
<p>An offline process results from a nested sequence of calls, as follows:</p>
<ol>
<li>
The host calls offlineNotify, passing an array of
VstAudioFile structures that describe all files that can be read and written.
There is also a "start" argument that indicates to the Plug-In whether the
process should begin or not. The "start" argument is true e.g. after the user
presses the "Process" button (which should be under the host control). The
"start" argument is false if the call results from any change in the file
environment of the host.
<li>
In its implementation of offlineNotify, the Plug-In
states which file(s) it wants to read and write, by setting flags in the
VstAudioFile structures. Then the Plug-In calls the function offlineStart. The
last argument of offlineStart allows the Plug-In to create one or more new
files.
<li>
In its implementation of offlineStart, the host
initializes an array of VstOfflineTask structures, one for each file to read
or/and write. Then the host calls: offlinePrepare.
<li>
In its implementation of offlinePrepare, the Plug-In
continues the initialization of the VstOfflineTask structures (eg. set the
sample rate and number of channels in new files).
<li>
If offlinePrepare returns true, the host finalizes
the preparation of the VstOfflineTask structures (eg. allocate i/o audio
buffers), then calls offlineRun.
<li>
In its implementation of offlineRun, the Plug-In can call the host functions
offlineRead and offlineWrite at will, until its audio processing is completed.
The approach is therefore opposite to the realtime interface: the Plug-In here
instructs the host about which files to read and write, in which order, at
which rate. A small diagram can illustrate the nested sequence of calls.
Functions in red are called by the host and implemented by the Plug-In.
Functions in blue are called by the Plug-In and implemented by the host.
</li>
</ol>
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
<p><font color="#ff0000">offlineNotify</font></p>
<p> {
</p>
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
<p><font color="#3333ff">offlineStart</font>
</p>
<p>{</p>
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
<p><font color="#ff0000">offlinePrepare</font></p>
<p><font color="#ff0000">offlineRun</font></p>
<p> {
</p>
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
<p>. ..</p>
<p><font color="#3333ff">offlineRead</font></p>
<p><font color="#3333ff">offlineWrite</font></p>
<p> . ..
</p>
</blockquote>
<p dir="ltr">}</p>
</blockquote>
<p dir="ltr">}</p>
</blockquote>
<p dir="ltr">}
</p>
</blockquote>
<p> </p>
<h2>Details of the interface</h2>
<h3><a name="VstAudioFile"></a>struct VstAudioFile</h3>
<p>This structure describes an audio file already open in the host. This
description is systemindependent: no file path is specified. A Plug-In does not
query the host about available files; instead, it gets informed about the
available files when the host calls the function offlineNotify.
<br>
Note: there is an option, however, to force the host to send a notification
(see <a href="#kVstOfflineQueryFiles">kVstOfflineQueryFiles</a>).
<br>
The host sets all the members of this structure, unless notified otherwise.<br>
</p>
<blockquote>
<h4>VstInt32 flags</h4>
<p>See enum VstAudioFileFlags. Both host and Plug-In can set flags.</p>
<h4>void* hostOwned</h4>
<p>Any data private to host.</p>
<h4>void* plugOwned</h4>
<p>Any data private to Plug-In. This value is (optionally) set by the Plug-In in
its implementation of offlineNotify. This value is then copied by the host into
the VstOfflineTask structure (plugOwned member), when offlineStart is called
(this allows the Plug-In, if necessary, to make a link between the
offlineNotify call and the offlinePrepare/offlineRun calls).</p>
<h4>char name[100]
</h4>
<p>Name of the file (no path, just name without any file extension). This can be
used by the Plug-In to display in its user interface the list of all files
available for processing. This is useful if the Plug-In requires the user to
select more than one file to perform its job (eg. mixer, file comparer,
etc...).</p>
<h4>VstInt32 uniqueId</h4>
<p>This value identifies a file instance in the host, during a session. Not two
file instances must ever get the same ID during a session. If a file gets
closed and is reopen later, it must be attributed an ID that was never
attributed so far during the session. From the host side, this can be easily
implemented with a simple global counter. This ID can be a useful reference for
a Plug-In, if its user interface maintains a list of files that the user can
select.</p>
<h4>double sampleRate</h4>
<p>sample rate of the file</p>
<h4>VstInt32 numChannels</h4>
<p>number of channels: 1 for mono, 2 for stereo, etc...</p>
<h4>double numFrames</h4>
<p>number of frames in the audio file </p>
<h4>VstInt32 format</h4>
<p>reserved for future. Currently 0.</p>
<h4>double editCursorPosition</h4>
<p>frame index of the edit cursor, or -1 if no such cursor exists. This member
represents the "edit-cursor" position, if any, but never the "playback-cursor"
position.</p>
<h4>double selectionStart</h4>
<p>frame index of first selected frame, or -1 if there is no selection</p>
<h4>double selectionSize</h4>
<p>number of frames in selection. Zero if no selection.</p>
<h4>VstInt32 selectedChannelsMask</h4>
<p>Bit mask describing which channels are selected. One bit per channel. Eg. value
3 means that both channels of a stereo file are selected.
</p>
<h4>VstInt32 numMarkers</h4>
<p>number of markers in the file. The Plug-In can use offlineRead to get details
about the markers.
</p>
<h4>VstInt32 timeRulerUnit</h4>
<p>If the Plug-In needs to display time values, it might be nice to match the unit
system selected by the user for the file in the host. This is the reason why
this member, and the following ones, are provided. Possible values: 0:
undefined 1: samples units 2: hours/minutes/seconds/milliseconds 3: smpte 4:
measures and beats
</p>
<h4>double timeRulerOffset</h4>
<p>frame offset of the time ruler for the window that displays the audio file.
Usually 0 but could be negative or positive.
</p>
<h4>double tempo</h4>
<p>-1 if not used by the file's time ruler, else BPM units.
</p>
<h4>VstInt32 timeSigNumerator</h4>
<p>-1 if not used by the file's time ruler, else number of beats per measure
</p>
<h4>VstInt32 timeSigDenominator</h4>
<p>-1 if not used by the file's time ruler, else number of beats per whole note
</p>
<h4>VstInt32 ticksPerBlackNote</h4>
<p> -1 if not used by the file's time ruler, else sequencer resolution
</p>
<h4>VstInt32 smpteFrameRate</h4>
<p> -1 if not used by the file's time ruler, else refers to VstTimeInfo for
the meaning.<br>
</p>
</blockquote>
<h3><br>
</h3>
<h3><a name="VstAudioFileFlags"></a>enum VstAudioFileFlags</h3>
<p>This refers to the possible flags for the member flag of the structure <a href="#VstAudioFile">
VstAudioFile</a>:</p>
<p>The host sets its flags before calling offlineNotify. The Plug-In sets its flags
in its implementation of offlineNotify, before calling offlineStart.
</p>
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
<h4>
</h4>
</blockquote><blockquote>
<h4><a name="kVstOfflineReadOnly"></a>kVstOfflineReadOnly
</h4>
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px"> </blockquote>
<p>Set by host. Means that the file can't be modified, it can only be read. If the
Plug-In tries to write it later, the host should return false from
offlineWrite.
</p>
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px"> </blockquote>
<h4><a name="kVstOfflineNoRateConversion"></a>kVstOfflineNoRateConversion
</h4>
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px"> </blockquote>
<p>Set by host. Means that the file can't have its sample rate modified.</p>
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px"> </blockquote>
<h4><a name="kVstOfflineNoChannelChange"></a>kVstOfflineNoChannelChange
</h4>
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px"> </blockquote>
<p>Set by host. Means that the number of channels can't be changed (eg. the host
might not allow an in-place mono to stereo conversion).
</p>
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px"> </blockquote>
<h4><a name="kVstOfflineCanProcessSelection"></a>kVstOfflineCanProcessSelection
</h4>
<p>Set by the Plug-In if its process can be applied to a limited part of a file. If
no selection exists, the entire file range is used. The host checks this flag
and, accordingly, initializes the members positionToProcessFrom and
numFramesToProcess in the structure VstOfflineTask. Setting this flag is a
common case, but a counter example is e.g. a sample rate converter (the sample
rate is global to a file and can't be applied to a limited part of a file).</p>
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px"> </blockquote>
<h4><a name="kVstOfflineNoCrossfade"></a>kVstOfflineNoCrossfade
</h4>
<p>Consider the case of a Plug-In transforming only a part of a file. To avoid a
click at the edges (between the processed part and the non-processed part) the
host might perform a short crossfade with the old samples, according to user
preferences. However, a Plug-In might want to reject this option for some
reasons (eg. the Plug-In performs a local glitch restoration and wants to
perform the crossfade itself). In that case, the Plug-In should set this flag
to instruct the host not to perform any crossfade.
</p>
<h4><a name="kVstOfflineWantRead"></a>kVstOfflineWantRead
</h4>
<p>If the Plug-In wants to read the file, it should set this flag. E.g. a
signal-generator Plug-In would never set that flag. If this flag is not set and
the Plug-In tries to read the file later, the host should return false from
offlineRead.</p>
<h4><a name="kVstOfflineWantWrite"></a>kVstOfflineWantWrite</h4>
<p>If the Plug-In wants to overwrite part or the entire file, it should set this
flag. E.g. an analyzer plugin would never set that flag. Note: as an
alternative, the Plug-In can choose to create a new file, rather than
overwriting the source file (see offlineStart). If this flag is not set and the
Plug-In tries to write the file later, the host should return false from
offlineWrite.</p>
<h4><a name="kVstOfflineWantWriteMarker"></a>kVstOfflineWantWriteMarker
</h4>
<p>If the Plug-In wants to modify or create markers in the file, it should set this
flag. If this flag is not set and the Plug-In tries to move or create a marker
later, the host should return false from offlineWrite.
</p>
<h4><a name="kVstOfflineWantMoveCursor"></a>kVstOfflineWantMoveCursor</h4>
<p>If the Plug-In wants to move the edit-cursor of the file, it should set this
flag. If this flag is not set and the Plug-In tries to move the edit-cursor
later, the host should return false from offlineWrite.</p>
<h4><a name="kVstOfflineWantSelect"></a>kVstOfflineWantSelect
</h4>
<p>If the Plug-In wants to select samples in the file, it should set this flag. If
this flag is not set and the Plug-In tries to select samples later, the host
should return false from offlineWrite.<br>
</p>
</blockquote><blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
<p><br>
</p>
</blockquote>
<h3><a name="VstOfflineTask"></a>struct VstOfflineTask</h3>
<p dir="ltr">This structure is used in offlinePrepare, offlineRun, offlineRead and
offlineWrite functions. Its main purpose is to be a parameter-holder to
instruct the host to read/write an existing file, or to write a new file.
However, it can also be used as a parameter-holder for other purposes, as we
shall see later (see VstOfflineOption). Thus, certain members of this structure
have a different meaning according to the option selected when calling
offlineRead and offlineWrite. For the sake of simplicity, we now mainly cover
the common case of reading/writing audio samples.
<br>
An important principle to understand from the beginning, is that each file
which is read or/and written is associated with a single VstOfflineTask
structure.<br>
<br>
</p>
<blockquote>
<h4>char processName[96]
</h4>
<p dir="ltr">Set by Plug-In in offlinePrepare. The host to label the process can
use this name. E.g. the host might display that name in a menu entry called
"Undo ....".
<br>
If the process uses multiple VstOfflineTask structures, only the first one
needs to have this field set (or all other VstOfflineTask structures should
have the same label).
<br>
This field might be erased later during the process, therefore the host should
make a copy of it.
<br>
</p>
<h4>double readPosition
</h4>
<p dir="ltr">Position, as frames, of the read "head" in the audio file. Set both by
Plug-In and host:
<br>
This value should be set by the Plug-In, before calling offlineRead, to
instruct the host.
<br>
On the other hand, the host updates the value to reflect the read position
after the call to offlineRead.
<br>
</p>
<h4>double writePosition
</h4>
<p dir="ltr">Position, as frames, of the write "head" in the audio file. Set both
by Plug-In and host:
<br>
This value should be set by the Plug-In, before calling offlineWrite, to
instruct the host.
<br>
On the other hand, the host updates the value to reflect the write position
after the call to offlineWrite.
<br>
</p>
<h4>VstInt32 readCount</h4>
<p dir="ltr">Number of audio frames to read.
<br>
Set by Plug-In, before calling offlineRead.
<br>
When returning from offlineRead, readCount contains the number of actually read
frames. If the Plug-In tries to read beyond the end of the file (not considered
as an error), the float buffers are completed with blank frames by the host. In
that case, the number of blank frames is returned in the member value. In other
words, the sum (readCount + value) after the call is equal to the value of
readCount before the call.
<br>
</p>
<h4>VstInt32 writeCount
</h4>
<p dir="ltr">Number of audio frames to write.
<br>
Set by Plug-In, before calling offlineWrite.
<br>
Never set by the host. If the host can't write the samples because of a
disk-full situation, the host should return false from offlineWrite.
<br>
</p>
<h4>VstInt32 sizeInputBuffer
</h4>
<p dir="ltr">Size, as frames, of the audio input buffer.
<br>
Set by host before calling offlineRun.
<br>
This value remains unchanged during the whole process. A Plug-In can't read
more than this number of samples in a single call to offlineRead.
<br>
</p>
<h4>VstInt32 sizeOutputBuffer
</h4>
<p dir="ltr">Size, as frames, of the audio output buffer.
<br>
Set by host before calling offlineRun.
<br>
This value remains unchanged during the whole process. A Plug-In can't write
more than this number of samples in a single call to offlineWrite.
<br>
</p>
<h4>void* inputBuffer
</h4>
<h4>void* outputBuffer
</h4>
<p dir="ltr">Both set by host, before calling offlineRun. The actual type of the
pointer depends on the channel mode: if the Plug-In has set the flag
kVstOfflineInterleavedAudio, then the type is float* (array of interleaved
samples). In the other case, the type is float** (array of array of samples).
The latter is the standard case.
<br>
</p>
<h4>double positionToProcessFrom
</h4>
<h4>double numFramesToProcess
</h4>
<p>Set by host, according to the flags set in enum VstAudioFileFlags. This defines
the frame range that the Plug-In should read for its process.
<br>
If required for its algorithm, the Plug-In is allowed to read before and after
this range (if the range is a subset of the file), but only that range of
samples should be transformed.
<br>
</p>
<h4>double maxFramesToWrite
</h4>
<p>Set by Plug-In in offlinePrepare. This value could be used by the host for
optimization purposes (to select a proper write algorithm), and also to check
if the disk space is sufficient before starting the process.<br>
If the Plug-In writes no audio, this value should be 0.
<br>
If the number of written samples is the same as the number of read samples,
this value should be equal to numFramesToProcess.
<br>
If the Plug-Ins does not know exactly the number of frames, this value should
be an approximate value, large enough for sure, but as small as possible (if
the Plug-In later tries to write more frames than this number, an error would
be issued by the host).
<br>
If the Plug-Ins does not know at all, this value should be -1 (this is the
default value of this member).
<br>
</p>
<h4>void* extraBuffer
</h4>
<p>This is set by the Plug-In. This is a buffer which is used to read/write other
data than audio. Meaning depends on the offlineRead/offlineWrite option (see <a href="#VstOfflineOption">
VstOfflineOption</a>).
<br>
</p>
<h4>VstInt32 value
</h4>
<p>Set by Plug-In or host. Meaning depends on the offlineRead/offlineWrite option
(see <a href="#VstOfflineOption">VstOfflineOption</a>).
<br>
</p>
<h4>VstInt32 index
</h4>
<p>Set by Plug-In or host. Meaning depends on the offlineRead/offlineWrite option
(see <a href="#VstOfflineOption">VstOfflineOption</a>).
<br>
This value is also optionally set by the Plug-In during offlinePrepare, as
follows:
<br>
If the Plug-In generates a new file out of an existing file, then it should
initialize this value with the index of the VstOfflineTask structure
corresponding to the source file. This is not mandatory, but this info could be
of interest for the host. Be default, index is -1 when offlinePrepare is
called.
<br>
</p>
<h4>double numFramesInSourceFile
</h4>
<p>Number of frames in source file. This is set by the host in offlineStart.
<br>
This value is only set for existing source files.
<br>
If the VstOfflineTask structure refers to a file created by the host on behalf
of the Plug-In, this value is 0.
<br>
</p>
<h4>double sourceSampleRate
</h4>
<p>Sample rate of the source file. Set by host.
<br>
If the VstOfflineTask structure refers to a file created by the host on behalf
of the Plug-In, this value is 0. In that case, the Plug-In must initialize this
value when offlinePrepare is called (in that case, same value as
destinationSampleRate).
<br>
</p>
<h4>double destinationSampleRate
</h4>
<p>Sample rate of the destination file. Set by Plug-In in offlinePrepare (but
previously initialized by host as sourceSampleRate).
<br>
If the VstOfflineTask structure refers to a file created by the host on behalf
of the Plug-In, this value is 0. In that case, the Plug-In must initialize this
value when offlinePrepare is called (in that case, same value as
sourceSampleRate).
</p>
<h4>VstInt32 numSourceChannels
</h4>
<p>Number of channels in the source file. Set by host.
<br>
Note: if the mode kVstOfflineCanProcessSelection is active, and if only one
channel of a stereo file is selected, then numSourceChannels should be set to
1. In that case, the file appears as a mono file from the Plug-In point of
view.
<br>
If the VstOfflineTask structure refers to a file created by the host on behalf
of the Plug-In, this value is 0. In that case, the Plug-In must initialize this
value when offlinePrepare is called (in that case, same value as
numDestinationChannels).
<br>
</p>
<h4>VstInt32 numDestinationChannels
</h4>
<p>Number of channels in the destination file. Set by Plug-In in offlinePrepare
(but previously initialized by host as numSourceChannels). This value is
required for the host to allocate the proper outputBuffer. If the
VstOfflineTask structure refers to a file created by the host on behalf of the
Plug-In, this value is 0. In that case, the Plug-In must initialize this value
when offlinePrepare is called (in that case, same value as numSourceChannels).
<br>
</p>
<h4>VstInt32 sourceFormat
</h4>
<p>Reserved for future.
<br>
Set by host.
<br>
</p>
<h4>VstInt32 destinationFormat
</h4>
<p>Reserved for future.
<br>
Set by Plug-In.
<br>
</p>
<h4>char outputText [512]
</h4>
<p>There are three uses for this member:
<br>
If the Plug-In has instructed the host to create a new file (see offlineStart),
then the Plug-In can optionally provide its name in this member, with a fully
qualified path (this file name must be selected by the user from the Plug-In
user interface). In that case, the file is saved by the host in the default
audio file format for the platform (this could also be a host specific option).
This name has to be initialized when offlinePrepare is called.
<br>
Note: the host, if a demo version, might reject this option!
<br>
If outputText is empty (common case), then the host creates the file in a
folder dedicated to temporary files. Later, it's up to the user to save the
file from the host.
<br>
Before returning from a function with false, the Plug-In can set the flag
kVstOfflinePlugError and then (over)write the outputText member. In that case,
the host should display the message to the user. If the host sets the flag
kVstOfflineUnvalidParameter, then the host might as well fill up the outputText
member, to give a hint to the Plug-In, for pure debugging purposes.
<br>
</p>
<h4>double progress
</h4>
<p>Set by Plug-In to inform the host about the current progress of the whole
operation. The value must be in the range 0 to 1. If the value is not in this
range (e.g. -1), the host must ignore it.
<br>
The Plug-In should, if possible, update this value each time before calling
offlineRead and offlineWrite (this would give the host enough occasions to
update a progress indicator to give feedback to the user). </p>
<p> If the process has to perform several "passes", the progress value is
allowed to go from 0 to 1 several times. However, ideally, a single 0 to 1 pass
is better for the user's feedback.
<br>
The progress value is meant to be global: if there are several VstOfflineTask
involved, the progress value should be "independent" from each task (yet, this
global progress should be set in each VstOfflineTask structure passed to
VstOfflineTask and offlineWrite calls).
<br>
</p>
<h4>VstInt32 progressMode
</h4>
<p>Reserved for the future.
<br>
</p>
<h4>char progressText[100]
</h4>
<p>Set by Plug-In, to describe what's going on. Can be updated any time. Optional.
<br>
</p>
<h4>VstInt32 flags
</h4>
<p>Set by host and Plug-In. See enum <a href="#VstOfflineTaskFlags">VstOfflineTaskFlags</a>.
<br>
</p>
<h4>VstInt32 returnValue
</h4>
<p>Reserved for the future.
<br>
</p>
<h4>void* hostOwned</h4>
Any data private to host void* plugOwned Any data private to Plug-In. This
value is firstly initialized by the host, in offlineStart, with the value of
the member plugOwned from the structure VstAudioFile (if the VstOfflineTask
corresponds to an existing file).<br>
</blockquote>
<p><br>
</p>
<h3><a name="VstOfflineTaskFlags"></a> enum VstOfflineTaskFlags<br>
</h3>
<blockquote>
<h4><a name="kVstOfflineUnvalidParameter"></a> kVstOfflineUnvalidParameter
</h4>
<p>Sets by host if the Plug-In passes an unvalid parameter. In that case, the host
might fill up the member outputText, to give a hint to the Plug-In, for
debugging purposes.
<br>
</p>
<h4><a name="kVstOfflineNewFile"></a>kVstOfflineNewFile
</h4>
<p>Set by the host to indicate that this VstOfflineTask represents a task that
creates/reads/writes a new file.
<br>
</p>
<h4><a name="kVstOfflinePlugError"></a>kVstOfflinePlugError
</h4>
<p>If an error happens in the Plug-In itself (not an error notified by the host),
then the Plug-In could optionally set this flag before returning false from its
function to indicate to the host that the member outputText (now) contains a
description of the error. The host is then in charge of displaying the message
to the user. The Plug-In should never try to display itself an error message
from the offlineRun function, since offlineRun could happen in a background
task.
</p>
<h4><a name="kVstOfflineInterleavedAudio"></a>kVstOfflineInterleavedAudio
</h4>
<p>The Plug-In should set this flag if it wants to get data in interleaved format.
By default, this is not the case.
<br>
</p>
<h4><a name="kVstOfflineTempOutputFile"></a>kVstOfflineTempOutputFile
</h4>
<p>The Plug-In should set this flag in offlinePrepare, if the file to create must
be a temporary one. In that case, the file is deleted at the end of the process
(else, the file is usually open by the host at the end of the process).
<br>
This flag can obviously be set only for a new file, not for an existing file.
<br>
</p>
<h4><a name="kVstOfflineFloatOutputFile"></a>kVstOfflineFloatOutputFile
</h4>
<p>If the Plug-In needs creating a file made of float samples, this flag should be
set. Else, the default file format is dependant on the host (could be 16 bit,
24 bit, float...). This can be useful if the Plug-In needs to store temporary
results to disk, without fear of clipping.<br>
</p>
<h4>
<a name="kVstOfflineRandomWrite"></a>kVstOfflineRandomWrite
</h4>
<p>If the Plug-In needs to write randomly (not sequentially) a file, it should set
this flag. This flag should also be set if the file is to be written
sequentially more than once. This is a hint for the host to select a proper
writing procedure. If this flag is not set, the host could return false from
offlineWrite, if the Plug-In attempts a non-sequential writing.
<br>
</p>
<h4><a name="kVstOfflineStretch"></a>kVstOfflineStretch
</h4>
<p>If the Plug-In time-stretches part or all of a file (eg. resampling), it should
set this flag. This instructs the host to move and stretch the relative file
markers, if any, to match the change. This also is of great importance in mode
"process-selection" (see kVstOfflineCanProcessSelection), as it instructs the
host to replace only the selection, whatever the number of written samples.
Let's take an example: if there are 10000 selected input samples (from 0 to
9999) and 20000 samples are output by the Plug-In, then: 1) if the flag
kVstOfflineStretch is set: the host simply replaces the samples 0-9999 with the
new 20000 samples, and also moves/stretches the file markers as required. Note
that this requires the host to "push" the samples above position 20000 (to
insert the 10000 new samples). 2) if the flag kVstOfflineStretch is not set:
the host replaces the samples 0-19999 with the new 20000 samples (eg. echo
Plug-In that reads samples beyond the end of the selection, to merge the tail
of the echo).
<br>
</p>
<h4><a name="kVstOfflineNoThread"></a>kVstOfflineNoThread
</h4>
<p>The host might either create a background thread to run the process, or run it
inside the main application thread. The Plug-In does not decide about this.
However, it can happen that a process is so short that creating a thread would
be a waste of time. In that case, the Plug-In can set this flag as a hint to
the host. </p>
</blockquote>
<h3><a name="VstAudioFileMarker"></a>struct VstAudioFileMarker
</h3>
<blockquote>
<h4>double position
</h4>
<p>Position of the marker
<br>
</p>
<h4>char name[32]
</h4>
<p>Name of the marker
<br>
</p>
<h4>VstInt32 type
</h4>
<p>The host might not support all types. We currently define:
<br>
0: undefined
<br>
1: generic marker
<br>
2: temporary marker (not saved with the file)
<br>
3: loop start marker
<br>
4: loop end marker
<br>
5: section start (whatever "section" might mean for the host)<br>
6: section end
<br>
</p>
<h4>VstInt32 id
</h4>
<p>This value is set by the host to identify a marker in a file. It can be any
value but 0, which is reserved to indicate a new marker (see option
kVstOfflineMarker). Not two markers can ever get the same ID for a given file.
<br>
</p>
</blockquote>
<h3><a name="VstOfflineOption"></a>enum VstOfflineOption
</h3>
<p>The functions offlineRead and offlineWrite have an argument (VstOfflineOption)
that allows to read/write different types of data. Let's see what these options
are:
<br>
</p>
<h4><a name="kVstOfflineAudio"></a>kVstOfflineAudio
</h4>
<p>Use this option to read/write audio samples. See also description of <a href="#VstOfflineTask">
VstOfflineTask</a>.
<br>
Reading can happen randomly. This means that any time during the process, a
Plug-In is allowed to jump at any frame position and read from that point.
<br>
Random reading can occur either in a read-only file or in a file currently
being written.
<br>
If a Plug-In tries to read beyond the end of the file (not to be considered as
an error by the host), the buffers are completed with blank samples by the
host. See comments about readCount on that subject.
<br>
Writing can happen randomly. This means that a file can be (over)written any
number of times and in any order. See <a href="#kVstOfflineRandomWrite">kVstOfflineRandomWrite</a>.
<br>
If writing is to happen at a position beyond the end of the file, the host must
extend the file as required and fill the gap with zeroes.
<br>
Delayed overwriting. When a Plug-In tries to overwrite part of an existing
source file, the host should in fact write the samples in a separate file. When
the process is finished, it's up to the host to actually replace the source
samples. This feature is required to let to the Plug-In have the possibility to
read the original samples at any time during a process.<br>
One important consequence of the above feature is that any writing, whatever
the situation, always occur in a new - possibly temporary - file. This is why
all write positions that a Plug-In ever specifies, should always relate to the
origin Zero.
<br>
E.g. if a Plug-In wants to overwrite samples [10000-19999], it should specify
write position in the range [0-9999]. It's up to the host to do the rest,
later, to achieve the desired effect.
<br>
A Plug-In can never "overwrite" before the position given by the member
positionToProcessFrom; it is only possible to overwrite a continuous block
starting from positionToProcessFrom. If the Plug-In starts overwriting after
positionToProcessFrom, the gap if filled up with blank samples.
<br>
To ease the undo/redo handling of the host (usually based on audio blocks),
there is a rule to obey when "overwriting" a source file:
<br>
Only one continuous segment of a source file can be overwritten during a single
task. E.g. it is not allowed to overwrite samples 0 to 10000 then samples 50000
to 60000, hoping that intermediary samples are preserved. If a Plug-In does so,
the result is undefined. However, if a Plug-In really needs to do so, it must
simply transfer itself the intermediary samples. </p>
<h4><a name="kVstOfflinePeaks"></a>kVstOfflinePeaks
</h4>
<p>The Plug-In UI might need to display part or all of a file. Reading a whole file
(for display purposes) is a time consuming operation; this is why most hosts
maintain a "peak file" that stores a "summary" of the audio file. With the <a href="#kVstOfflinePeaks">
kVstOfflinePeaks</a> option, a Plug-In can benefit from this host
functionality. This option is only to be used with offlineRead, not
offlineWrite. The required parameters of VstOfflineTask are the following ones:
<br>
</p>
<ul>
<li>
positionToProcessFrom: set by Plug-In. The frame
index to display from.
<li>
numFramesToProcess: set by Plug-In. The number of
frames to display.
<li>
writeCount: set by host. This represents how many
elements of pixel information have been stored by the host in the
buffer.
<li>
value: set by Plug-In. This is the zoom factor: it
represents the desired number of frames to display per screen pixel.
<li>
index: set by host, see further.
<li>
inputBuffer: set by host. The elements of the array are not 32 bit float
values, but pairs of 16 bit integers. </li>
</ul>
An element of the array could be represented as follows:
<br>
struct { int16 y1; int16 y2; }
<br>
There are two ways to interpret the data written by the host into the buffer:
<br>
If the member index is set to 0 by the host, then the sound view is much
"compressed". In that case, a peak at a given position is represented by a
vertical line below and above the horizontal axis of the display. The value y1
represents the positive coordinate, above the axis, and the y2 coordinate, the
negative value below the axis.
<br>
y1 is always in the range 0 to 32767. It has to be scaled by the Plug-In,
according to its display's height.
<br>
y2 is always in the range -32767 to 0. It has to be scaled by the Plug-In,
according to its display's height. If the member index is set to 1 by the host,
then the sound view is less "compressed" and should be displayed as a
continuous curve.<br>
In this case, y1 is always in the range -32767 to 32767. It has to be scaled by
the Plug-In, according to its display's height.
<br>
y2 is always 0 and should be ignored.
<br>
Note: since the buffer that is used with this option is the buffer normally
used for audio samples, the pixel data is interleaved or not, according to the
mode kVstOfflineInterleavedAudio, as selected for that VstOfflineTask
structure.
<br>
It is only possible to call this function on a source file, not on a file being
written during a process. If the host does not implement this function,
offlineRead returns false. The Plug-In could then read itself the audio
(kVstOfflineAudio option) to display the wave.<br>
<br>
<h4><a name="kVstOfflineParameter"></a>kVstOfflineParameter
</h4>
If the host supports this option, the Plug-In can read and write parameters
along the audio-file. A "parameter" is a float value or byte array. Each
parameter is attributed an index (e.g. if there are 3 float values and 2
arrays, the indexes go from 0 to 4).
<br>
Examples of use: parameter automation; storage of meta-information (e.g. pitch)
usable by the same plugin, later during the same process, or in another process
by another Plug-In, etc.
<br>
The host is free to implement the underlying parameter storage, as it likes.
However, it is easy to understand that parameters should be stored in a sorted
vector, each one attached to a frame index.
<br>
The parameters are usually maintained in RAM by the host, therefore the Plug-In
should not over-use this feature and for instance write one parameter per
sample!
<br>
The host might choose to save the parameters into a project-file, or to embed
them into the audio file header, or not to save them at all (ie. all parameters
get erased when the audio file closes).
<br>
<br>
<h5>Writing parameters with offlineWrite:
</h5>
<i>processName</i>: name of the parameter family.
<br>
<br>
If a Plug-In X writes parameters to a file, then a Plug-In Y can retrieve the
parameters only if it provides the right family name.
<br>
The name must be made unique enough, to prevent any clash.
<br>
This member only needs to be set for the first parameter to record during the
process.
<br>
If this first parameter belongs to a new family, the host destroys all
previously stored parameters.
<br>
<i>
<br>
value</i>: version of the parameter family.
<br>
<br>
Freely under the control of the Plug-In. This member only needs to be set for
the first parameter to record during the process.
<br>
<i>
<br>
index</i>: index of parameter to write.
<br>
<i>
<br>
writeCount</i>: 0 if writing a float parameter, else byte size of the
parameter array.
<br>
<i>
<br>
extraBuffer</i>: buffer allocated by the Plug-In to pass the parameter.
<br>
<br>
For writing a float, this pointer is actually a float* pointer, else this is a
pointer to the array.
<br>
If this pointer is NULL, then the parameter at that position, if any, is
deleted. If this pointer is NULL and the writePosition is negative, all
parameters are erased.
<br>
<i>
<br>
writePosition</i>: position where to write the parameter.
<br>
<br>
Since parameters are not stored "inside" the audio samples, it does not matter
if the write position is temporarily beyond the end of the audio file.<br>
For the sake of simplicity (when reading back later), it is not possible to
write more than one parameter at a given position. If this happens, the old
parameter gets erased. If this parameter is negative and extraBuffer is NULL,
all parameters get erased.
<br>
<br>
<h5>Reading parameters with offlineRead:
</h5>
At the beginning, the Plug-In is usually ignorant about what parameters are
stored, and where. The first call to offlineRead is therefore a special one, as
follows:
<br>
The Plug-In initializes the member extraBuffer to 0 and the member readPosition
to the position it wants to get informed about (usually, 0). When returning
from offlineRead, the host has initialized the following parameters:
<br>
<i>
<br>
processName</i>: name of the parameter family, or nothing if no recorded
parameter.
<br>
<br>
If the name of this parameter family is not supported by the Plug-In, the
Plug-In should not try to read the parameters.
<br>
<i>
<br>
value</i>: version of the recorded parameter family. Might be useful for
the Plug-In.
<br>
<i>
<br>
readPosition</i>: the frame index at which the next parameter is found
(this value was unchanged by the host if there was already a parameter there).
<br>
<i>
<br>
readCount</i>: if the parameter is an array, this is its size (as bytes),
else the value is 0.
<br>
<i>
<br>
index</i>: the index of the parameter, or -1 if no parameter was found.
<br>
<br>
In order to retrieve the parameters one by one, the Plug-In can then use
offlineRead in the following way:
<br>
<ul>
<li>
Input parameters, as set by the Plug-In before
calling offlineRead.
<li>
readCount: should be 0 when retrieving a float
parameter, else indicates the size of the buffer, as bytes, to receive the
array.
<li>
extraBuffer: buffer allocated by the Plug-In to
receive the parameter. If the parameter is a float, this pointer is actually a
float* pointer, else this is a pointer to an array.
<li>
readPosition: position where to read the parameter.
If there is no parameter at this position, the host returns false.
<li>
index: index of the parameter to retrieve.
<li>
Output parameters, as set by the host after calling
offlineRead:
<li>
index: index of the next parameter, else -1.
<li>
readPosition: position of next recorded parameter, or
-1 if no more parameter. This is an useful hint for the Plug-In, to make it
easy and fast to retrieve sequentially all recorded parameters.
<li>
readCount: if the next parameter is a float, this value is 0. If it is an
array, this value is the byte-size of this array. </li>
</ul>
<br>
<h4><a name="kVstOfflineMarker"></a>kVstOfflineMarker
</h4>
With this option, the Plug-In can create one or more markers in the file, or
move existing ones.
<br>
To know which markers currently exist in a given file, the Plug-In can use
offlineRead, with the following parameters:
<br>
<ul>
<li>
extraBuffer: buffer allocated by the Plug-In, to
receive a copy of the markers. If this value is NULL, then offlineRead sets
the number of markers into the member readCount. This is a way for the Plug-In
to know how many markers exist in the file, and therefore to allocate a proper
buffer size (and call again offlineRead).
<li>
readCount: the size of the buffer (number of VstAudioFileMarker elements). If
this size is not equal to the current number of markers, the offlineRead
function should return false. </li>
</ul>
To write new markers:
<br>
<ul>
<li>
extraBuffer: a buffer allocated by the Plug-In that
holds the markers to create, and only them.
<li>
writeCount: the number of markers in the buffer. Important: the member id of a
marker to create must be 0. When returning from the offlineWrite function, the
id of the marker has been initialized by the host (it could be reused by the
Plug-In to move the marker later). </li>
</ul>
To move existing markers:
<br>
<ul>
<li>
extraBuffer: a buffer allocated by the Plug-In that
holds the markers to move. These markers must have been previously retrieved
through offlineRead. The host identifies the markers to move by checking the
id member of the markers. The position member of a marker structure represents
the new position that a marker should adopt. If position is -1, then the host
deletes the markers.
<li>
writeCount: the number of markers in the buffer. </li>
</ul>
To copy markers from one file to another:
<br>
If the Plug-In creates a new file out of a source file, it might be convenient
to copy the source file markers into the new file. In this case, the Plug-In
can call the offlineWrite function with the following parameters:
<br>
<ul>
<li>
extraBuffer: NULL
<li>
index: index of the VstOfflineTask structure that corresponds to the source
file. </li>
</ul>
<h4><br>
</h4>
<h4><a name="kVstOfflineCursor"></a>kVstOfflineCursor
</h4>
By calling offlineRead with this option, the Plug-In retrieves the file's
edit-cursor position:
<br>
<ul>
<li>
readPosition: position of the cursor, or -1 if no
edit-cursor
<li>
index: bit mask describing on which channel(s) lies the edit-cursor. </li>
</ul>
To move the edit cursor to a certain location, the Plug-In should initialize
the following members:
<br>
<ul>
<li>
writePosition: position of the cursor
<li>
index: bit mask describing on which channel(s) should lie the edit-cursor. -1
means all channels. If the host does not support the placement of the
edit-cursor on individual channels, it should ignore this parameter. It's worth
noting that "edit-cursor" position does not mean "playback-cursor"
position. </li>
</ul>
<br>
<h4><a name="kVstOfflineSelection"></a>kVstOfflineSelection
</h4>
By calling offlineRead with this option, the Plug-In retrieves the current
sample selection in the file:
<br>
<ul>
<li>
positionToProcessFrom: the first selected frame, or
-1
<li>
numFramesToProcess: the size of the selection, or
0
<li>
index: bit mask describing which channel(s) are selected </li>
</ul>
To set a selection in the file, the Plug-In should initialize the above
members.
<br>
If the host does not support the selection of individual channels, it should
ignore index and select all channels.
<br>
If the host does not support sample selections, offlineWrite should return
false.
<h4><a name="kVstOfflineQueryFiles"></a>kVstOfflineQueryFiles
</h4>
<p>If the Plug-In desires to get notified about which files are available in the
host, it should call offlineRead with this option.
<br>
The first parameter of offlineRead (VstOfflineTask*) should be NULL. On
receiving this call, the host should call, immedialty or later, offlineNotify,
with the start parameter set to false. In other words, the
kVstOfflineQueryFiles option is a way to force the host to call offlineNotify,
in order to get informed about open files (normally, the host only calls
offlineNotify if a change happens in the set of open files). It is important to
insist on the fact that the host is free to call kVstOfflineQueryFiles
asynchronously, ie. not immediatly when kVstOfflineQueryFiles is called.
<br>
Normally, this option is only used if the Plug-In needs to be notified about
the file information, in order to update its user interface. </p>
<h2>Functions
</h2>
<div class="cpp"><a name="offlineNotify"></a>bool offlineNotify(VstAudioFile* ptr, VstInt32 numAudioFiles, bool start)</div>
<p>The host calls this Plug-In function in two cases:
<br>
</p>
<ul>
<li>
When the Plug-In's process is to be executed. E.g.
the user has pressed the "Process" button. In that case, the "start" parameter
is true.
<li>
Anytime a change happens in the set of files open in the host. In that case,
the "start" parameter is false. </li>
</ul>
<p>
The purpose of this notification is to give the Plug-In a chance to update its
user interface according to the host environment.
<br>
For example:
<br>
The Plug-In might display the list of all files available for processing; this
list needs to be updated if a new file is open or closed in the host.<br>
The Plug-In might display some information about the file with the focus: this
needs to change if a new file gains the focus.
<br>
Etc...
<br>
Tip: since the <a href="#VstAudioFile">VstAudioFile</a> structure contains
parameters that are likely to often change, such as cursor position or sample
selection, the offlineNotify function might be called often. Therefore, a good
design for a Plug-In that needs to update its user interface would be to cache
the VstAudioFile settings, so as to actually update its user interface only
when really required (eg. if the Plug-In does not care about the editcursor
position in a file. It should not update its user-interface only if the
edit-cursor position happens to move in a file).
<br>
<br>
The host as aparameter passes an array of VstAudioFile structures.
<br>
The number of elements in this array is given by the parameter numAudioFiles.
<br>
numAudioFiles is 0 if there is no open file in the host, and in that case, the
parameter "ptr" is NULL.
<br>
The first element of the array always represents the file with the focus.
<br>
If the "start" argument is true, the Plug-In should start the process by
calling offlineStart. Else, the Plug-In might, or might not, starts a read-only
process, to update its user-interface. See <a href="#offlineStart">offlineStart</a>.
</p>
<p>Whatever the state of the start argument, the Plug-In should return false from
the function if it can't process the file(s) open in the host. E.g. if the
Plug-In only works with stereo files, and the file with the focus is mono, the
Plug-In should return false from this function. This allows the host, for
instance, to disable the process button of the user interface.
<br>
<b>Important</b>: the Plug-In should not initialize anything internally at this
stage. All internal initialization and cleanup required for the process should
happen inside <a href="#offlineRun">offlineRun</a>, and only there. </p>
<div class="cpp"><a name="offlinePrepare"></a>bool offlinePrepare(VstOfflineTask* offline, VstInt32 count)</div>
<p>The host calls this function so that the Plug-In complements the <a href="#VstOfflineTask">
VstOfflineTask</a> structure(s). If everything is fine, the function should
return true. <b>Important</b>: the Plug-In should not initialize anything
internally at this stage. All internal initialization and cleanup required for
the process should happen inside <a href="#offlineRun">offlineRun</a>, and only
there.<br>
<br>
</p>
<div class="cpp"><a name="offlineRun"></a>bool offlineRun(VstOfflineTask* offline, VstInt32 count)</div>
<p>This function is called by the host once the VstOfflineTask structure(s) is(are)
ready. Within this function, the Plug-In does its audio processing and calls <a href="#offlineRead">
offlineRead</a> and <a href="#offlineWrite">offlineWrite</a> at will. If
any error is detected during this procedure, the function should return false.
<br>
<b>Important</b>: all internal initialization and cleanup required for the
process should happen inside <a href="#offlineRun">offlineRun</a>, and only
there. E.g. if the Plug-In should allocate some memory, this should be done
inside this function (as well as the deallocation).<br>
<br>
</p>
<div class="cpp"><a name="offlineStart"></a>bool offlineStart(VstAudioFile* ptr, VstInt32 numAudioFiles, VstInt32 numNewAudioFiles)</div>
<p>When the function <a href="#offlineNotify">offlineNotify</a> is called, the
Plug-In might decide to start a process. For this purpose, the Plug-In has to
decide which file(s) to process, and also if some new file(s) should be
created.
<br>
By setting the member flag of each <a href="#VstAudioFile">VstAudioFile</a> structure,
the Plug-In instructs the host about which file(s) should be processed. In many
cases, only the first VstAudioFile element (the focused file) is concerned.
<br>
The parameter numAudioFiles is simply the one passed from <a href="#offlineNotify">offlineNotify</a>.
<br>
The parameter numNewAudioFiles is the number of files that the Plug-In want to
create.
<br>
E.g. if the Plug-In selects one file from the VstAudioFile array and sets the
value of numNewAudioFiles to 1, the host will create two VstOfflineTask
structures. By convention, all VstOfflineTask structures corresponding to new
files are placed by the host at the end of the array passed to offlineRun (ie,
the front of the array corresponds to already existing files).
<br>
It is not allowed for a Plug-In to call offlineStart if the Plug-In is not
itself called with offlineNotify. This is to ensure a synchronous protocol with
the host. If the Plug-In would call offlineStart asynchronously, maybe the
VstAudioFile structures would not be valid anymore at that time, resulting in
an undefined behaviour.<br>
<br>
</p>
<div class="cpp"><a name="offlineRead"></a>bool offlineRead(VstOfflineTask* offline, VstOfflineOption option, bool readSource = true)</div>
<p>This function is called by the Plug-In to read data. See enum VstOfflineOption
to see what kind of data can be read, apart audio samples.</p>
<p>About the parameter readSource:</p>
<p>As already seen, a single VstOfflineTask structure can be used both to read an
existing file, and to overwrite it. Moreover, the offline specification states
that it is possible, at any time, to read both the original samples and the new
ones (the "overwritten" samples). This is the reason for the readSource
parameter: set it to true to read the original samples and to false to read the
recently written samples.<br>
<br>
</p>
<div class="cpp"><a name="offlineWrite"></a>bool offlineWrite(VstOfflineTask* offline, VstOfflineOption option)</div>
<p>This function is called by the Plug-In to write data.
<br>
See enum <a href="#VstOfflineOption">VstOfflineOption</a> to see what kind of
data can be written, apart audio samples.
<br>
<br>
<br>
</p>
</div>
<html>
<head>
<title>Empty</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="mario">
</head>
<body>
<br/>
<hr width="100%" size="2" align="left" />
<div align=left>
Copyright �2006 <a href="http://www.steinberg.net" target="_blank"><u>Steinberg Media Technologies</u></a>.
All Rights Reserved.
</div>
</body>
</html>
|