A simple and dumb lv2 plugin to test host state support
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

203 lines
5.0KB

  1. /*
  2. Copyright (C) 2020 falkTX
  3. This work is free. You can redistribute it and/or modify it under the
  4. terms of the Do What The Fuck You Want To Public License, Version 2,
  5. as published by Sam Hocevar. See the COPYING file for more details.
  6. */
  7. #include <lv2.h>
  8. #include <lv2/atom/atom.h>
  9. #include <lv2/state/state.h>
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #ifndef HAVE_LV2_STATE_FREE_PATH
  14. // forwards compatibility with old lv2 headers
  15. #define LV2_STATE__freePath LV2_STATE_PREFIX "freePath"
  16. typedef void* LV2_State_Free_Path_Handle;
  17. typedef struct {
  18. LV2_State_Free_Path_Handle handle;
  19. void (*free_path)(LV2_State_Free_Path_Handle handle, char* path);
  20. } LV2_State_Free_Path;
  21. #endif
  22. typedef struct {
  23. bool activated, deactivated, saved, restored;
  24. const LV2_Atom_Sequence* seqIn;
  25. LV2_Atom_Sequence* seqOut;
  26. const LV2_State_Free_Path* freePath;
  27. const LV2_State_Make_Path* makePath;
  28. const LV2_State_Map_Path* mapPath;
  29. } StateTest;
  30. static LV2_Handle instantiate(const LV2_Descriptor* const descriptor,
  31. const double sample_rate,
  32. const char* const bundle_path,
  33. const LV2_Feature* const* const features)
  34. {
  35. const LV2_State_Free_Path* freePath = NULL;
  36. const LV2_State_Make_Path* makePath = NULL;
  37. const LV2_State_Map_Path* mapPath = NULL;
  38. for (int i=0; features[i] != NULL; ++i)
  39. {
  40. /**/ if (strcmp(features[i]->URI, LV2_STATE__freePath) == 0)
  41. freePath = features[i]->data;
  42. else if (strcmp(features[i]->URI, LV2_STATE__makePath) == 0)
  43. makePath = features[i]->data;
  44. else if (strcmp(features[i]->URI, LV2_STATE__mapPath) == 0)
  45. mapPath = features[i]->data;
  46. }
  47. if (freePath == NULL || makePath == NULL || mapPath == NULL)
  48. return NULL;
  49. StateTest* instance = calloc(1, sizeof(StateTest));
  50. instance->freePath = freePath;
  51. instance->makePath = makePath;
  52. instance->mapPath = mapPath;
  53. {
  54. char* const projectPath = makePath->path(makePath->handle, ".");
  55. if (projectPath != NULL)
  56. {
  57. printf("state-test init ok, initial path is: '%s'\n", projectPath);
  58. freePath->free_path(freePath->handle, projectPath);
  59. }
  60. else
  61. {
  62. printf("state-test init ok, but failed to get initial path\n");
  63. }
  64. }
  65. return instance;
  66. // unused
  67. (void)descriptor;
  68. (void)sample_rate;
  69. (void)bundle_path;
  70. }
  71. #define instancePtr ((StateTest*)instance)
  72. static void connect_port(LV2_Handle instance, uint32_t port, void* data_location)
  73. {
  74. switch (port)
  75. {
  76. case 0:
  77. instancePtr->seqIn = data_location;
  78. break;
  79. case 1:
  80. instancePtr->seqOut = data_location;
  81. break;
  82. }
  83. }
  84. static void activate(LV2_Handle instance)
  85. {
  86. instancePtr->activated = true;
  87. }
  88. static void run(LV2_Handle instance, uint32_t sample_count)
  89. {
  90. if (instancePtr->deactivated)
  91. {
  92. // TODO something
  93. instancePtr->deactivated = false;
  94. }
  95. if (instancePtr->activated)
  96. {
  97. // TODO something
  98. instancePtr->activated = false;
  99. }
  100. if (instancePtr->restored)
  101. {
  102. // TODO something
  103. instancePtr->restored = false;
  104. }
  105. if (instancePtr->saved)
  106. {
  107. // TODO something
  108. instancePtr->saved = false;
  109. }
  110. }
  111. static void deactivate(LV2_Handle instance)
  112. {
  113. instancePtr->deactivated = true;
  114. }
  115. static void cleanup(LV2_Handle instance)
  116. {
  117. free(instance);
  118. }
  119. static LV2_State_Status save(LV2_Handle instance,
  120. LV2_State_Store_Function store,
  121. LV2_State_Handle handle,
  122. uint32_t flags,
  123. const LV2_Feature* const* features)
  124. {
  125. instancePtr->saved = true;
  126. return LV2_STATE_SUCCESS;
  127. // TODO
  128. (void)store;
  129. (void)handle;
  130. (void)flags;
  131. (void)features;
  132. }
  133. static LV2_State_Status restore(LV2_Handle instance,
  134. LV2_State_Retrieve_Function retrieve,
  135. LV2_State_Handle handle,
  136. uint32_t flags,
  137. const LV2_Feature* const* features)
  138. {
  139. instancePtr->restored = true;
  140. return LV2_STATE_SUCCESS;
  141. // TODO
  142. (void)retrieve;
  143. (void)handle;
  144. (void)flags;
  145. (void)features;
  146. }
  147. static const void* extension_data(const char* const uri)
  148. {
  149. static const LV2_State_Interface iface = {
  150. .save = save,
  151. .restore = restore
  152. };
  153. if (strcmp(uri, LV2_STATE__interface) == 0)
  154. return &iface;
  155. return NULL;
  156. }
  157. LV2_SYMBOL_EXPORT
  158. const LV2_Descriptor* lv2_descriptor(const uint32_t index)
  159. {
  160. static const LV2_Descriptor desc = {
  161. .URI = "https://git.kx.studio/falkTX/lv2-state-test",
  162. .instantiate = instantiate,
  163. .connect_port = connect_port,
  164. .activate = activate,
  165. .run = run,
  166. .deactivate = deactivate,
  167. .cleanup = cleanup,
  168. .extension_data = extension_data
  169. };
  170. return index == 0 ? &desc : NULL;
  171. }