Durun / vst3kotlin

A VST3 SDK binding in Kotlin
GNU General Public License v3.0
7 stars 0 forks source link

Kotlinで基本的なVST3プラグインとウィンドウを作成しますか? #27

Open GavinRay97 opened 3 years ago

GavinRay97 commented 3 years ago

こんにちは、私は日本語を話せないので、Google翻訳を使用しているのでお詫びします。

VSTプラグインを構築するために必要なすべてのパーツがここにあるようです。 コードはホスティングVSTに焦点を当てているように見えますが、KotlinNativeを使用して最も単純な .dllまたは.soVST3プラグインを作成することがどれほど難しいか興味があります。

これはあなたがした非常にクールな仕事です。 上記も可能ですか?

ありがとう=)

Durun commented 3 years ago

(English ver. is below) こんにちは、興味を持って頂きありがとうございます。

現時点では、このリポジトリはVST hostを作成するためのパーツを部分的に提供するに留まり、まだ実験的なものです。 VST pluginを作成するためのAPIは実装されていないため、いくつかの追加の作業が必要です。

しかし、plugin APIを実装することは難しいです。 なぜなら、Kotlinが生成する.dllのヘッダー(例えば https://kotlinlang.org/docs/native-dynamic-libraries.html#generated-headers-file )は、VST3の規定する形式と異なるからです。

そういう理由で、私はplugin APIを実装する予定はありません、すみません。

Hello, thank you for your interest.

At this time, this repository provides only the parts for creating VST-hosts and is still experimental. The API for creating VST-plugins is not implemented and requires some additional work.

However, implementing the plugin API is difficult. This is because the header of the .dll generated by Kotlin (like https://kotlinlang.org/docs/native-dynamic-libraries.html#generated-headers-file ) is different from the format specified by VST3.

For that reason, I have no plans to implement the plugin API, I'm sorry.

GavinRay97 commented 3 years ago

Ahh I see, thank you anyways.

Your code is beautiful and brilliant. This is some of the most amazing Kotlin I have ever seen. It is very inspirational.

Even though you have targeted HOSTING only VST, the C API you wrote for Kotlin Native to interface with VST3 already has a great amount of what is required to eventually be able to write VST3 plugins in Kotlin too.

Would it be okay if I expanded your C wrappers, and potentially the Kotlin Native code, to add the VST3 interfaces for plugins?

I would of course offer to contribute any additions made, and don't intend commercial purposes (just for fun/learning).


I have been experimenting with GraalVM as well -- it lets you write C API's or call C API's directly, using annotations in JVM languages, and then compile to native binary or shared/static libary (.so/.dll/.dylib):

I thought maybe you'd find it interesting.


ああ、なるほど、とにかくありがとう。

あなたのコードは美しく素晴らしいです。 これは、私が今まで見た中で最も素晴らしいKotlinの一部です。 とても刺激的です。

HOSTINGのみのVSTをターゲットにしている場合でも、KotlinNativeがVST3とインターフェイスするために作成したCAPIには、最終的にKotlinでVST3プラグインを作成できるようにするために必要なものがすでに大量に含まれています。

プラグイン用のVST3インターフェイスを追加するために、Cラッパー、場合によってはKotlinネイティブコードを拡張しても大丈夫ですか?

もちろん、私は追加されたものを寄付することを申し出ますが、商業目的ではありません(楽しみ/学習のためだけに)。

私もGraalVMを試してきました。これにより、JVM言語のアノテーションを使用してC APIを記述したり、C APIを直接呼び出したりして、ネイティブバイナリまたは共有/静的ライブラリ(.so / .dll / .dylib)にコンパイルできます。


Example: Writing .dll which exposes C function int add(int, int)

import com.oracle.svm.core.c.function.CEntryPointOptions
import com.oracle.svm.core.c.function.CEntryPointSetup
import org.graalvm.nativeimage.c.function.CEntryPoint

object App {
    @CEntryPoint(name = "add")
    @CEntryPointOptions(prologue = CEntryPointSetup.EnterCreateIsolatePrologue::class,
                        epilogue = CEntryPointSetup.LeaveTearDownIsolateEpilogue::class)
    fun add(a: Int, b: Int): Int {
        return a + b
    }
}
$ native-image --shared -H:Name=libnativeimpl -cp ./target/classes
# Printing build artifacts to: Projects\tmp\graalvm-native-example\libnativeimpl.build_artifacts.txt 
#include <stdio.h>
#include <string.h>
#include <windows.h>

#define DLL_NAME "libnativeimpl.dll"
typedef int(*addFn)(int, int);

int main() {
  HMODULE hTargetDll = LoadLibraryA(DLL_NAME);
  if (!hTargetDll) return 0;
  printf("[+] Target DLL base address: 0x%p\n", hTargetDll);

  addFn add = (addFn)GetProcAddress(hTargetDll, "add");
  printf("add address: %x\n", add);

  int res = add(1, 5);
  printf("Result: %d\n", res);

  printf("[+] done\n");
  return 1;
}
$ clang-cl main.c && ./main.exe
[+] Target DLL base address: 0x00007FFAC1F20000
add address: c1f2dde0
Result: 6
[+] done

Example with OpenGL C API:

#define  GLUT_SINGLE  0x0000
void  glutInit( int* pargc, char** argv );
void  glutInitDisplayMode( unsigned int displayMode );
void  glutDisplayFunc( void (* callback)( void ) );
@CContext(Main.Directives::class)
class Main {
    class Directives : CContext.Directives {
        val headerFiles: List<String> = listOf("<GL/glut.h>")
        val libraries: List<String> = listOf("GL", "glut")
    }
}

@CContext(Main.Directives::class)
internal object GLUT {

    @CConstant("GLUT_SINGLE")
    external fun SINGLE(): Int

    @CFunction("glutInit")
    external fun init(argc: CIntPointer, argv: CCharPointerPointer)

    @CFunction("glutInitDisplayMode")
    external fun initDisplayMode(displayMode: Int)

    @CFunction("glutDisplayFunc")
    external fun displayFunc(callback: Callback)

    internal interface Callback : CFunctionPointer {
        @InvokeCFunctionPointer
        operator fun invoke()
    }
}
Durun commented 3 years ago

Sorry for the late contact.

It's okay to extend the code. Please fork this repository when extending.

Thank you for the interesting information and your contribution.


連絡が遅くなりすみません。

コードを拡張しても大丈夫です。 拡張の際はこのリポジトリをフォークしてもらえればと思います。

興味深い情報とご協力をありがとうございます。

GavinRay97 commented 3 years ago

Thank you!


ありがとうございました!