Update CI version
[carla.git] / source / native-plugins / audio-file.cpp
blob822ccdb61e112219d6687a1c1f879aa53c97aeb0
1 /*
2 * Carla Native Plugins
3 * Copyright (C) 2013-2023 Filipe Coelho <falktx@falktx.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #include "CarlaNativePrograms.hpp"
19 #include "CarlaString.hpp"
21 #include "audio-base.hpp"
23 #include <cmath>
25 // --------------------------------------------------------------------------------------------------------------------
27 class VolumeFilter
29 static constexpr const float kPIf = static_cast<float>(M_PI);
31 float a0, b1, z1;
33 public:
34 VolumeFilter(const float sampleRate) noexcept
36 setSampleRate(sampleRate);
39 void reset() noexcept
41 a0 = 1.f - b1;
42 z1 = 0.f;
45 void setSampleRate(const float sampleRate) noexcept
47 const float frequency = 30.0f / sampleRate;
49 b1 = std::exp(-2.f * kPIf * frequency);
50 a0 = 1.f - b1;
51 z1 = 0.f;
54 void processStereo(const float gain, float* buffers[2], const uint32_t frames) noexcept
56 const float _a0 = a0;
57 const float _b1 = b1;
58 float _z1 = z1;
60 for (uint32_t i=0; i < frames; ++i)
62 _z1 = gain * _a0 + _z1 * _b1;
63 buffers[0][i] *= _z1;
64 buffers[1][i] *= _z1;
67 z1 = _z1;
71 // --------------------------------------------------------------------------------------------------------------------
74 #ifndef __MOD_DEVICES__
75 class AudioFilePlugin : public NativePluginWithMidiPrograms<FileAudio>
76 #else
77 class AudioFilePlugin : public NativePluginClass
78 #endif
80 public:
81 #ifndef __MOD_DEVICES__
82 static constexpr const char* const audiofilesWildcard =
83 #ifdef HAVE_SNDFILE
84 "*.aif;*.aifc;*.aiff;*.au;*.bwf;*.flac;*.htk;*.iff;*.mat4;*.mat5;*.oga;*.ogg;*.opus;"
85 "*.paf;*.pvf;*.pvf5;*.sd2;*.sf;*.snd;*.svx;*.vcc;*.w64;*.wav;*.xi;"
86 #endif
87 #ifdef HAVE_FFMPEG
88 "*.3g2;*.3gp;*.aac;*.ac3;*.amr;*.ape;*.mp2;*.mp3;*.mpc;*.wma;"
89 #ifndef HAVE_SNDFILE
90 "*.flac;*.oga;*.ogg;*.w64;*.wav;"
91 #endif
92 #else
93 "*.mp3;"
94 #endif
97 enum PendingInlineDisplay : uint8_t {
98 InlineDisplayNotPending,
99 InlineDisplayNeedRequest,
100 InlineDisplayRequesting
102 #endif
104 enum Parameters {
105 kParameterLooping,
106 kParameterHostSync,
107 kParameterVolume,
108 kParameterEnabled,
109 kParameterQuadChannels,
110 kParameterInfoChannels,
111 kParameterInfoBitRate,
112 kParameterInfoBitDepth,
113 kParameterInfoSampleRate,
114 kParameterInfoLength,
115 kParameterInfoPosition,
116 kParameterInfoPoolFill,
117 kParameterCount
120 AudioFilePlugin(const NativeHostDescriptor* const host)
121 #ifndef __MOD_DEVICES__
122 : NativePluginWithMidiPrograms<FileAudio>(host, fPrograms, 3),
123 fPrograms(hostGetFilePath("audio"), audiofilesWildcard),
124 #else
125 : NativePluginClass(host),
126 #endif
127 fVolumeFilter(getSampleRate()) {}
129 protected:
130 // ----------------------------------------------------------------------------------------------------------------
131 // Plugin parameter calls
133 uint32_t getParameterCount() const override
135 return kParameterCount;
138 const NativeParameter* getParameterInfo(const uint32_t index) const override
140 static NativeParameter param;
142 param.scalePointCount = 0;
143 param.scalePoints = nullptr;
144 param.unit = nullptr;
145 param.ranges.step = 1.0f;
146 param.ranges.stepSmall = 1.0f;
147 param.ranges.stepLarge = 1.0f;
148 param.designation = NATIVE_PARAMETER_DESIGNATION_NONE;
150 switch (index)
152 case kParameterLooping:
153 param.name = "Loop Mode";
154 param.hints = static_cast<NativeParameterHints>(NATIVE_PARAMETER_IS_AUTOMATABLE|
155 NATIVE_PARAMETER_IS_ENABLED|
156 NATIVE_PARAMETER_IS_BOOLEAN);
157 param.ranges.def = 1.0f;
158 param.ranges.min = 0.0f;
159 param.ranges.max = 1.0f;
160 break;
161 case kParameterHostSync:
162 param.name = "Host Sync";
163 param.hints = static_cast<NativeParameterHints>(NATIVE_PARAMETER_IS_AUTOMATABLE|
164 NATIVE_PARAMETER_IS_ENABLED|
165 NATIVE_PARAMETER_IS_BOOLEAN);
166 #ifdef __MOD_DEVICES__
167 param.ranges.def = 0.0f;
168 #else
169 param.ranges.def = 1.0f;
170 #endif
171 param.ranges.min = 0.0f;
172 param.ranges.max = 1.0f;
173 break;
174 case kParameterVolume:
175 param.name = "Volume";
176 param.hints = static_cast<NativeParameterHints>(NATIVE_PARAMETER_IS_AUTOMATABLE|
177 NATIVE_PARAMETER_IS_ENABLED);
178 param.ranges.def = 100.0f;
179 param.ranges.min = 0.0f;
180 param.ranges.max = 127.0f;
181 param.ranges.stepSmall = 0.5f;
182 param.ranges.stepLarge = 10.0f;
183 param.unit = "%";
184 break;
185 case kParameterEnabled:
186 param.name = "Enabled";
187 param.hints = static_cast<NativeParameterHints>(NATIVE_PARAMETER_IS_AUTOMATABLE|
188 NATIVE_PARAMETER_IS_ENABLED|
189 NATIVE_PARAMETER_IS_BOOLEAN|
190 NATIVE_PARAMETER_USES_DESIGNATION);
191 param.ranges.def = 1.0f;
192 param.ranges.min = 0.0f;
193 param.ranges.max = 1.0f;
194 param.designation = NATIVE_PARAMETER_DESIGNATION_ENABLED;
195 break;
196 case kParameterQuadChannels:
197 param.name = "Quad Channels";
198 param.hints = static_cast<NativeParameterHints>(NATIVE_PARAMETER_IS_AUTOMATABLE|
199 NATIVE_PARAMETER_IS_ENABLED|
200 NATIVE_PARAMETER_IS_INTEGER|
201 NATIVE_PARAMETER_USES_SCALEPOINTS);
202 param.ranges.def = 0.0f;
203 param.ranges.min = 0.0f;
204 param.ranges.max = 2.0f;
206 static const NativeParameterScalePoint scalePoints[3] = {
207 { "Channels 1 + 2", 0 },
208 { "Channels 3 + 4", 1 },
209 { "Channels 1&2 + 3&4", 2 }
211 param.scalePointCount = 3;
212 param.scalePoints = scalePoints;
214 break;
215 case kParameterInfoChannels:
216 param.name = "Num Channels";
217 param.hints = static_cast<NativeParameterHints>(NATIVE_PARAMETER_IS_AUTOMATABLE|
218 NATIVE_PARAMETER_IS_ENABLED|
219 NATIVE_PARAMETER_IS_INTEGER|
220 NATIVE_PARAMETER_IS_OUTPUT);
221 param.ranges.def = 0.0f;
222 param.ranges.min = 0.0f;
223 param.ranges.max = 2.0f;
224 break;
225 case kParameterInfoBitRate:
226 param.name = "Bit Rate";
227 param.hints = static_cast<NativeParameterHints>(NATIVE_PARAMETER_IS_AUTOMATABLE|
228 NATIVE_PARAMETER_IS_ENABLED|
229 NATIVE_PARAMETER_IS_INTEGER|
230 NATIVE_PARAMETER_IS_OUTPUT);
231 param.ranges.def = 0.0f;
232 param.ranges.min = -1.0f;
233 param.ranges.max = 384000.0f * 64.0f * 2.0f;
234 break;
235 case kParameterInfoBitDepth:
236 param.name = "Bit Depth";
237 param.hints = static_cast<NativeParameterHints>(NATIVE_PARAMETER_IS_AUTOMATABLE|
238 NATIVE_PARAMETER_IS_ENABLED|
239 NATIVE_PARAMETER_IS_INTEGER|
240 NATIVE_PARAMETER_IS_OUTPUT);
241 param.ranges.def = 0.0f;
242 param.ranges.min = 0.0f;
243 param.ranges.max = 64.0f;
244 break;
245 case kParameterInfoSampleRate:
246 param.name = "Sample Rate";
247 param.hints = static_cast<NativeParameterHints>(NATIVE_PARAMETER_IS_AUTOMATABLE|
248 NATIVE_PARAMETER_IS_ENABLED|
249 NATIVE_PARAMETER_IS_INTEGER|
250 NATIVE_PARAMETER_IS_OUTPUT);
251 param.ranges.def = 0.0f;
252 param.ranges.min = 0.0f;
253 param.ranges.max = 384000.0f;
254 break;
255 case kParameterInfoLength:
256 param.name = "Length";
257 param.hints = static_cast<NativeParameterHints>(NATIVE_PARAMETER_IS_AUTOMATABLE|
258 NATIVE_PARAMETER_IS_ENABLED|
259 NATIVE_PARAMETER_IS_OUTPUT);
260 param.ranges.def = 0.0f;
261 param.ranges.min = 0.0f;
262 param.ranges.max = (float)INT64_MAX;
263 param.unit = "s";
264 break;
265 case kParameterInfoPosition:
266 param.name = "Position";
267 param.hints = static_cast<NativeParameterHints>(NATIVE_PARAMETER_IS_AUTOMATABLE|
268 NATIVE_PARAMETER_IS_ENABLED|
269 NATIVE_PARAMETER_IS_OUTPUT);
270 param.ranges.def = 0.0f;
271 param.ranges.min = 0.0f;
272 param.ranges.max = 100.0f;
273 param.unit = "%";
274 break;
275 case kParameterInfoPoolFill:
276 param.name = "Pool Fill";
277 param.hints = static_cast<NativeParameterHints>(NATIVE_PARAMETER_IS_AUTOMATABLE|
278 NATIVE_PARAMETER_IS_ENABLED|
279 NATIVE_PARAMETER_IS_OUTPUT);
280 param.ranges.def = 0.0f;
281 param.ranges.min = 0.0f;
282 param.ranges.max = 100.0f;
283 param.unit = "%";
284 break;
285 default:
286 return nullptr;
289 return &param;
292 float getParameterValue(const uint32_t index) const override
294 switch (index)
296 case kParameterLooping:
297 return fLoopMode ? 1.0f : 0.0f;
298 case kParameterHostSync:
299 return fHostSync ? 1.f : 0.f;
300 case kParameterEnabled:
301 return fEnabled ? 1.f : 0.f;
302 case kParameterQuadChannels:
303 return fQuadMode;
304 case kParameterVolume:
305 return fVolume * 100.f;
306 case kParameterInfoPosition:
307 return fLastPosition;
308 case kParameterInfoPoolFill:
309 return fReadableBufferFill;
310 case kParameterInfoBitRate:
311 return static_cast<float>(fReader.getCurrentBitRate());
314 const ADInfo nfo = fReader.getFileInfo();
316 switch (index)
318 case kParameterInfoChannels:
319 return static_cast<float>(nfo.channels);
320 case kParameterInfoBitDepth:
321 return static_cast<float>(nfo.bit_depth);
322 case kParameterInfoSampleRate:
323 return static_cast<float>(nfo.sample_rate);
324 case kParameterInfoLength:
325 return static_cast<float>(nfo.length)/1000.f;
328 return 0.f;
331 void setParameterValue(const uint32_t index, const float value) override
333 if (index == kParameterVolume)
335 fVolume = value / 100.f;
336 return;
339 if (index == kParameterQuadChannels)
341 const int ivalue = static_cast<int>(value + 0.5f);
342 CARLA_SAFE_ASSERT_INT_RETURN(value >= AudioFileReader::kQuad1and2 && value <= AudioFileReader::kQuadAll,
343 value,);
345 fQuadMode = static_cast<AudioFileReader::QuadMode>(ivalue);
346 fPendingFileReload = true;
347 hostRequestIdle();
348 return;
351 const bool b = value > 0.5f;
353 switch (index)
355 case kParameterLooping:
356 if (fLoopMode != b)
357 fLoopMode = b;
358 break;
359 case kParameterHostSync:
360 if (fHostSync != b)
362 fInternalTransportFrame = 0;
363 fHostSync = b;
365 break;
366 case kParameterEnabled:
367 if (fEnabled != b)
369 fInternalTransportFrame = 0;
370 fEnabled = b;
372 break;
373 default:
374 break;
378 // ----------------------------------------------------------------------------------------------------------------
379 // Plugin state calls
381 void setCustomData(const char* const key, const char* const value) override
383 if (std::strcmp(key, "file") != 0)
384 return;
386 #ifndef __MOD_DEVICES__
387 invalidateNextFilename();
388 #endif
389 loadFilename(value);
392 #ifndef __MOD_DEVICES__
393 void setStateFromFile(const char* const filename) override
395 loadFilename(filename);
397 #endif
399 // ----------------------------------------------------------------------------------------------------------------
400 // Plugin process calls
402 #ifndef __MOD_DEVICES__
403 void process2(const float* const*, float** const outBuffer, const uint32_t frames,
404 const NativeMidiEvent*, uint32_t) override
405 #else
406 void process(const float* const*, float** const outBuffer, const uint32_t frames,
407 const NativeMidiEvent*, uint32_t) override
408 #endif
410 float* const out1 = outBuffer[0];
411 float* const out2 = outBuffer[1];
412 float* const playCV = outBuffer[2];
414 if (! fDoProcess)
416 // carla_stderr("P: no process");
417 carla_zeroFloats(out1, frames);
418 carla_zeroFloats(out2, frames);
419 carla_zeroFloats(playCV, frames);
420 fLastPosition = 0.f;
421 fReadableBufferFill = 0.f;
422 return;
425 bool playing;
426 uint64_t framePos;
428 if (fHostSync)
430 const NativeTimeInfo* const timePos = getTimeInfo();
431 playing = fEnabled && timePos->playing;
432 framePos = timePos->frame;
434 else
436 playing = fEnabled;
437 framePos = fInternalTransportFrame;
439 if (playing)
440 fInternalTransportFrame += frames;
443 // not playing
444 if (! playing)
446 carla_zeroFloats(out1, frames);
447 carla_zeroFloats(out2, frames);
448 carla_zeroFloats(playCV, frames);
449 return;
452 const bool offline = isOffline();
453 bool needsIdleRequest = false;
455 if (fReader.tickFrames(outBuffer, 0, frames, framePos, fLoopMode, offline) && ! fPendingFileRead)
457 if (offline)
459 fPendingFileRead = false;
460 fReader.readPoll();
462 else
464 fPendingFileRead = true;
465 needsIdleRequest = true;
469 fLastPosition = fReader.getLastPlayPosition() * 100.f;
470 fReadableBufferFill = fReader.getReadableBufferFill() * 100.f;
472 fVolumeFilter.processStereo(fVolume, outBuffer, frames);
474 #ifndef __MOD_DEVICES__
475 if (fInlineDisplay.writtenValues < 32)
477 fInlineDisplay.lastValuesL[fInlineDisplay.writtenValues] = carla_findMaxNormalizedFloat(out1, frames);
478 fInlineDisplay.lastValuesR[fInlineDisplay.writtenValues] = carla_findMaxNormalizedFloat(out2, frames);
479 ++fInlineDisplay.writtenValues;
481 if (fInlineDisplay.pending == InlineDisplayNotPending)
483 needsIdleRequest = true;
484 fInlineDisplay.pending = InlineDisplayNeedRequest;
486 #endif
488 if (needsIdleRequest)
489 hostRequestIdle();
492 // ----------------------------------------------------------------------------------------------------------------
493 // Plugin UI calls
495 void uiShow(const bool show) override
497 if (! show)
498 return;
500 if (const char* const filename = uiOpenFile(false, "Open Audio File", ""))
501 uiCustomDataChanged("file", filename);
503 uiClosed();
506 // ----------------------------------------------------------------------------------------------------------------
507 // Plugin dispatcher calls
509 void idle() override
511 #ifndef __MOD_DEVICES__
512 NativePluginWithMidiPrograms<FileAudio>::idle();
514 if (fInlineDisplay.pending == InlineDisplayNeedRequest)
516 fInlineDisplay.pending = InlineDisplayRequesting;
517 hostQueueDrawInlineDisplay();
519 #endif
521 if (fPendingFileReload)
523 fPendingFileReload = fPendingFileRead = false;
525 if (char* const filename = fFilename.releaseBufferPointer())
527 loadFilename(filename);
528 std::free(filename);
531 else if (fPendingFileRead)
533 fPendingFileRead = false;
534 fReader.readPoll();
538 void sampleRateChanged(const double sampleRate) override
540 fVolumeFilter.setSampleRate(sampleRate);
542 if (char* const filename = fFilename.releaseBufferPointer())
544 loadFilename(filename);
545 std::free(filename);
549 #ifndef __MOD_DEVICES__
550 const NativeInlineDisplayImageSurface* renderInlineDisplay(const uint32_t rwidth, const uint32_t height) override
552 CARLA_SAFE_ASSERT_RETURN(height > 4, nullptr);
554 const uint32_t width = rwidth == height ? height * 4 : rwidth;
556 /* NOTE the code is this function is not optimized, still learning my way through pixels...
558 const size_t stride = width * 4;
559 const size_t dataSize = stride * height;
560 const uint pxToMove = fDoProcess ? fInlineDisplay.writtenValues : 0;
562 uchar* data = fInlineDisplay.data;
564 if (fInlineDisplay.dataSize != dataSize || data == nullptr)
566 delete[] data;
567 data = new uchar[dataSize];
568 std::memset(data, 0, dataSize);
569 fInlineDisplay.data = data;
570 fInlineDisplay.dataSize = dataSize;
572 else if (pxToMove != 0)
574 // shift all previous values to the left
575 for (uint w=0; w < width - pxToMove; ++w)
576 for (uint h=0; h < height; ++h)
577 std::memmove(&data[h * stride + w * 4], &data[h * stride + (w+pxToMove) * 4], 4);
580 fInlineDisplay.width = static_cast<int>(width);
581 fInlineDisplay.height = static_cast<int>(height);
582 fInlineDisplay.stride = static_cast<int>(stride);
584 if (pxToMove != 0)
586 const uint h2 = height / 2;
588 // clear current line
589 for (uint w=width-pxToMove; w < width; ++w)
590 for (uint h=0; h < height; ++h)
591 memset(&data[h * stride + w * 4], 0, 4);
593 // draw upper/left
594 for (uint i=0; i < pxToMove && i < 32; ++i)
596 const float valueL = fInlineDisplay.lastValuesL[i];
597 const float valueR = fInlineDisplay.lastValuesR[i];
599 const uint h2L = static_cast<uint>(valueL * (float)h2);
600 const uint h2R = static_cast<uint>(valueR * (float)h2);
601 const uint w = width - pxToMove + i;
603 for (uint h=0; h < h2L; ++h)
605 // -30dB
606 //if (valueL < 0.032f)
607 // continue;
609 data[(h2 - h) * stride + w * 4 + 3] = 160;
611 // -12dB
612 if (valueL < 0.25f)
614 data[(h2 - h) * stride + w * 4 + 1] = 255;
616 // -3dB
617 else if (valueL < 0.70f)
619 data[(h2 - h) * stride + w * 4 + 2] = 255;
620 data[(h2 - h) * stride + w * 4 + 1] = 255;
622 else
624 data[(h2 - h) * stride + w * 4 + 2] = 255;
628 for (uint h=0; h < h2R; ++h)
630 // -30dB
631 //if (valueR < 0.032f)
632 // continue;
634 data[(h2 + h) * stride + w * 4 + 3] = 160;
636 // -12dB
637 if (valueR < 0.25f)
639 data[(h2 + h) * stride + w * 4 + 1] = 255;
641 // -3dB
642 else if (valueR < 0.70f)
644 data[(h2 + h) * stride + w * 4 + 2] = 255;
645 data[(h2 + h) * stride + w * 4 + 1] = 255;
647 else
649 data[(h2 + h) * stride + w * 4 + 2] = 255;
655 fInlineDisplay.writtenValues = 0;
656 fInlineDisplay.pending = InlineDisplayNotPending;
657 return (NativeInlineDisplayImageSurface*)(NativeInlineDisplayImageSurfaceCompat*)&fInlineDisplay;
659 #endif
661 // ----------------------------------------------------------------------------------------------------------------
663 private:
664 bool fLoopMode = true;
665 #ifdef __MOD_DEVICES__
666 bool fHostSync = false;
667 #else
668 bool fHostSync = true;
669 #endif
670 bool fEnabled = true;
671 bool fDoProcess = false;
672 bool fPendingFileRead = false;
673 bool fPendingFileReload = false;
674 AudioFileReader::QuadMode fQuadMode = AudioFileReader::kQuad1and2;
676 uint32_t fInternalTransportFrame = 0;
677 float fLastPosition = 0.f;
678 float fReadableBufferFill = 0.f;
679 float fVolume = 1.f;
681 AudioFileReader fReader;
682 CarlaString fFilename;
684 float fPreviewData[108] = {};
686 #ifndef __MOD_DEVICES__
687 NativeMidiPrograms fPrograms;
689 struct InlineDisplay : NativeInlineDisplayImageSurfaceCompat {
690 float lastValuesL[32] = {};
691 float lastValuesR[32] = {};
692 volatile PendingInlineDisplay pending = InlineDisplayNotPending;
693 volatile uint8_t writtenValues = 0;
695 InlineDisplay()
696 : NativeInlineDisplayImageSurfaceCompat() {}
698 ~InlineDisplay()
700 if (data != nullptr)
702 delete[] data;
703 data = nullptr;
707 CARLA_DECLARE_NON_COPYABLE(InlineDisplay)
708 CARLA_PREVENT_HEAP_ALLOCATION
709 } fInlineDisplay;
710 #endif
712 VolumeFilter fVolumeFilter;
714 void loadFilename(const char* const filename)
716 CARLA_ASSERT(filename != nullptr);
717 carla_stdout("AudioFilePlugin::loadFilename(\"%s\")", filename);
719 fDoProcess = false;
720 fReader.destroy();
721 fFilename.clear();
723 if (filename == nullptr || *filename == '\0')
724 return;
726 constexpr uint32_t kPreviewDataLen = sizeof(fPreviewData)/sizeof(float);
728 if (fReader.loadFilename(filename, static_cast<uint32_t>(getSampleRate()), fQuadMode,
729 kPreviewDataLen, fPreviewData))
731 fInternalTransportFrame = 0;
732 fDoProcess = true;
733 fFilename = filename;
734 hostSendPreviewBufferData('f', kPreviewDataLen, fPreviewData);
738 PluginClassEND(AudioFilePlugin)
740 static const char* _get_buffer_port_name(NativePluginHandle, const uint32_t index, const bool isOutput)
742 if (!isOutput)
743 return nullptr;
745 switch (index)
747 case 0:
748 return "output_1";
749 case 1:
750 return "output_2";
751 case 2:
752 return "Play status";
755 return nullptr;
758 static const NativePortRange* _get_buffer_port_range(NativePluginHandle, const uint32_t index, const bool isOutput)
760 if (!isOutput || index != 2)
761 return nullptr;
763 static NativePortRange npr = { 0.f, 10.f };
764 return &npr;
767 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AudioFilePlugin)
770 // --------------------------------------------------------------------------------------------------------------------
772 CARLA_API_EXPORT
773 void carla_register_native_plugin_audiofile();
775 CARLA_API_EXPORT
776 void carla_register_native_plugin_audiofile()
778 static const NativePluginDescriptor audiofileDesc = {
779 /* category */ NATIVE_PLUGIN_CATEGORY_UTILITY,
780 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_RTSAFE
781 #ifndef __MOD_DEVICES__
782 |NATIVE_PLUGIN_HAS_INLINE_DISPLAY
783 #endif
784 |NATIVE_PLUGIN_HAS_UI
785 |NATIVE_PLUGIN_NEEDS_UI_OPEN_SAVE
786 |NATIVE_PLUGIN_REQUESTS_IDLE
787 |NATIVE_PLUGIN_USES_CONTROL_VOLTAGE
788 |NATIVE_PLUGIN_USES_TIME),
789 /* supports */ NATIVE_PLUGIN_SUPPORTS_NOTHING,
790 /* audioIns */ 0,
791 /* audioOuts */ 2,
792 /* midiIns */ 0,
793 /* midiOuts */ 0,
794 /* paramIns */ 1,
795 /* paramOuts */ 0,
796 /* name */ "Audio File",
797 /* label */ "audiofile",
798 /* maker */ "falkTX",
799 /* copyright */ "GNU GPL v2+",
800 AudioFilePlugin::_instantiate,
801 AudioFilePlugin::_cleanup,
802 AudioFilePlugin::_get_parameter_count,
803 AudioFilePlugin::_get_parameter_info,
804 AudioFilePlugin::_get_parameter_value,
805 AudioFilePlugin::_get_midi_program_count,
806 AudioFilePlugin::_get_midi_program_info,
807 AudioFilePlugin::_set_parameter_value,
808 AudioFilePlugin::_set_midi_program,
809 AudioFilePlugin::_set_custom_data,
810 AudioFilePlugin::_ui_show,
811 AudioFilePlugin::_ui_idle,
812 AudioFilePlugin::_ui_set_parameter_value,
813 AudioFilePlugin::_ui_set_midi_program,
814 AudioFilePlugin::_ui_set_custom_data,
815 AudioFilePlugin::_activate,
816 AudioFilePlugin::_deactivate,
817 AudioFilePlugin::_process,
818 AudioFilePlugin::_get_state,
819 AudioFilePlugin::_set_state,
820 AudioFilePlugin::_dispatcher,
821 AudioFilePlugin::_render_inline_display,
822 /* cvIns */ 0,
823 /* cvOuts */ 1,
824 AudioFilePlugin::_get_buffer_port_name,
825 AudioFilePlugin::_get_buffer_port_range,
826 /* ui_width */ 0,
827 /* ui_height */ 0
830 carla_register_native_plugin(&audiofileDesc);
833 // --------------------------------------------------------------------------------------------------------------------