From fe0b94cd2726a678111287bf1f985211b0af36a7 Mon Sep 17 00:00:00 2001 From: Peter Salomonsen Date: Sun, 19 Mar 2023 15:18:12 +0100 Subject: [PATCH] render_128_samples, handle cors --- .gitignore | 3 +- cmd/sointu-compile/server.go | 16 +- templates/wasm/player.wat | 636 ++++++++++++++++++++++++++++++++++- 3 files changed, 648 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 39c96dc..d261e99 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,5 @@ actual_output/ node_modules *.raw -sointu-server \ No newline at end of file +sointu-server +temp_song_file.* \ No newline at end of file diff --git a/cmd/sointu-compile/server.go b/cmd/sointu-compile/server.go index b94df41..6214ea5 100644 --- a/cmd/sointu-compile/server.go +++ b/cmd/sointu-compile/server.go @@ -82,6 +82,17 @@ func process(filename string) error { } func handleRequest(w http.ResponseWriter, r *http.Request) { + // Set CORS headers + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Headers", "Content-Type") + w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS") + + // Handle pre-flight OPTIONS request + if r.Method == http.MethodOptions { + w.WriteHeader(http.StatusOK) + return + } + if r.Method != http.MethodPost { http.Error(w, "Only POST method is allowed", http.StatusMethodNotAllowed) return @@ -120,6 +131,7 @@ func handleRequest(w http.ResponseWriter, r *http.Request) { } w.Header().Set("Content-Type", "text/plain") + w.WriteHeader(http.StatusOK) w.Write(watContent) } @@ -127,10 +139,10 @@ func handleRequest(w http.ResponseWriter, r *http.Request) { func main() { // Set up router and server router := mux.NewRouter() - router.HandleFunc("/process", handleRequest).Methods("POST") + router.HandleFunc("/process", handleRequest).Methods("POST", "OPTIONS") http.Handle("/", router) - port := "8080" + port := "10000" fmt.Printf("Starting server on port %s\n", port) if err := http.ListenAndServe(":"+port, nil); err != nil { fmt.Fprintf(os.Stderr, "Error starting server: %v\n", err) diff --git a/templates/wasm/player.wat b/templates/wasm/player.wat index 42d538c..b274e50 100644 --- a/templates/wasm/player.wat +++ b/templates/wasm/player.wat @@ -120,9 +120,590 @@ ;; Import the difficult math functions from javascript ;; (seriously now, it's 2020) ;;------------------------------------------------------------------------------ -(func $pow (import "m" "pow") (param f32) (param f32) (result f32)) -(func $log2 (import "m" "log2") (param f32) (result f32)) -(func $sin (import "m" "sin") (param f32) (result f32)) + +(func $log2 (param $0 f32) (result f32) + (local $1 i32) + (local $2 f64) + (local $3 i32) + (local $4 i32) + (local $5 f64) + block $~lib/util/math/log2f_lut|inlined.0 (result f32) + local.get $0 + i32.reinterpret_f32 + local.tee $1 + i32.const 8388608 + i32.sub + i32.const 2130706432 + i32.ge_u + if + f32.const -inf + local.get $1 + i32.const 1 + i32.shl + i32.eqz + br_if $~lib/util/math/log2f_lut|inlined.0 + drop + local.get $0 + local.get $1 + i32.const 2139095040 + i32.eq + br_if $~lib/util/math/log2f_lut|inlined.0 + drop + local.get $1 + i32.const 31 + i32.shr_u + local.get $1 + i32.const 1 + i32.shl + i32.const -16777216 + i32.ge_u + i32.or + if + local.get $0 + local.get $0 + f32.sub + local.tee $0 + local.get $0 + f32.div + br $~lib/util/math/log2f_lut|inlined.0 + end + local.get $0 + f32.const 8388608 + f32.mul + i32.reinterpret_f32 + i32.const 192937984 + i32.sub + local.set $1 + end + local.get $1 + i32.const 1060306944 + i32.sub + local.tee $3 + i32.const 19 + i32.shr_u + i32.const 15 + i32.and + i32.const 4 + i32.shl + i32.const 1024 + i32.add + local.set $4 + local.get $1 + local.get $3 + i32.const -8388608 + i32.and + i32.sub + f32.reinterpret_i32 + f64.promote_f32 + local.get $4 + f64.load + f64.mul + f64.const 1 + f64.sub + local.tee $2 + local.get $2 + f64.mul + local.set $5 + local.get $2 + f64.const 0.4811247078767291 + f64.mul + f64.const -0.7213476299867769 + f64.add + local.get $5 + f64.const -0.36051725506874704 + f64.mul + f64.add + local.get $5 + f64.mul + local.get $2 + f64.const 1.4426950186867042 + f64.mul + local.get $4 + f64.load offset=8 + local.get $3 + i32.const 23 + i32.shr_s + f64.convert_i32_s + f64.add + f64.add + f64.add + f32.demote_f64 + end +) + +(data (i32.const 100024) "\be\f3\f8y\eca\f6?\190\96[\c6\fe\de\bf=\88\afJ\edq\f5?\a4\fc\d42h\0b\db\bf\b0\10\f0\f09\95\f4?{\b7\1f\n\8bA\d7\bf\85\03\b8\b0\95\c9\f3?{\cfm\1a\e9\9d\d3\bf\a5d\88\0c\19\0d\f3?1\b6\f2\f3\9b\1d\d0\bf\a0\8e\0b{\"^\f2?\f0z;\1b\1d|\c9\bf?4\1aJJ\bb\f1?\9f<\af\93\e3\f9\c2\bf\ba\e5\8a\f0X#\f1?\\\8dx\bf\cb`\b9\bf\a7\00\99A?\95\f0?\ce_G\b6\9do\aa\bf\00\00\00\00\00\00\f0?\00\00\00\00\00\00\00\00\acG\9a\fd\8c`\ee?=\f5$\9f\ca8\b3?\a0j\02\1f\b3\a4\ec?\ba\918T\a9v\c4?\e6\fcjW6 \eb?\d2\e4\c4J\0b\84\ce?-\aa\a1c\d1\c2\e9?\1ce\c6\f0E\06\d4?\edAx\03\e6\86\e8?\f8\9f\1b,\9c\8e\d8?bHS\f5\dcg\e7?\cc{\b1N\a4\e0\dc?") +(data (i32.const 100286) "\f0?t\85\15\d3\b0\d9\ef?\0f\89\f9lX\b5\ef?Q[\12\d0\01\93\ef?{Q}<\b8r\ef?\aa\b9h1\87T\ef?8bunz8\ef?\e1\de\1f\f5\9d\1e\ef?\15\b71\n\fe\06\ef?\cb\a9:7\a7\f1\ee?\"4\12L\a6\de\ee?-\89a`\08\ce\ee?\'*6\d5\da\bf\ee?\82O\9dV+\b4\ee?)TH\dd\07\ab\ee?\85U:\b0~\a4\ee?\cd;\7ff\9e\a0\ee?t_\ec\e8u\9f\ee?\87\01\ebs\14\a1\ee?\13\ceL\99\89\a5\ee?\db\a0*B\e5\ac\ee?\e5\c5\cd\b07\b7\ee?\90\f0\a3\82\91\c4\ee?]%>\b2\03\d5\ee?\ad\d3Z\99\9f\e8\ee?G^\fb\f2v\ff\ee?\9cR\85\dd\9b\19\ef?i\90\ef\dc 7\ef?\87\a4\fb\dc\18X\ef?_\9b{3\97|\ef?\da\90\a4\a2\af\a4\ef?@En[v\d0\ef?") +(func $~lib/math/NativeMathf.pow (param $0 f32) (param $1 f32) (result f32) + (local $2 i32) + (local $3 f64) + (local $4 i32) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (local $8 f64) + local.get $1 + f32.abs + f32.const 2 + f32.le + if + local.get $1 + f32.const 2 + f32.eq + if + local.get $0 + local.get $0 + f32.mul + return + end + local.get $1 + f32.const 0.5 + f32.eq + if + local.get $0 + f32.sqrt + f32.abs + f32.const inf + local.get $0 + f32.const -inf + f32.ne + select + return + end + local.get $1 + f32.const -1 + f32.eq + if + f32.const 1 + local.get $0 + f32.div + return + end + local.get $1 + f32.const 1 + f32.eq + if + local.get $0 + return + end + local.get $1 + f32.const 0 + f32.eq + if + f32.const 1 + return + end + end + block $~lib/util/math/powf_lut|inlined.0 (result f32) + local.get $1 + i32.reinterpret_f32 + local.tee $7 + i32.const 1 + i32.shl + i32.const 1 + i32.sub + i32.const -16777217 + i32.ge_u + local.tee $6 + local.get $0 + i32.reinterpret_f32 + local.tee $2 + i32.const 8388608 + i32.sub + i32.const 2130706432 + i32.ge_u + i32.or + if + local.get $6 + if + f32.const 1 + local.get $7 + i32.const 1 + i32.shl + i32.eqz + br_if $~lib/util/math/powf_lut|inlined.0 + drop + f32.const nan:0x400000 + local.get $2 + i32.const 1065353216 + i32.eq + br_if $~lib/util/math/powf_lut|inlined.0 + drop + local.get $0 + local.get $1 + f32.add + local.get $7 + i32.const 1 + i32.shl + i32.const -16777216 + i32.gt_u + local.get $2 + i32.const 1 + i32.shl + i32.const -16777216 + i32.gt_u + i32.or + br_if $~lib/util/math/powf_lut|inlined.0 + drop + f32.const nan:0x400000 + local.get $2 + i32.const 1 + i32.shl + i32.const 2130706432 + i32.eq + br_if $~lib/util/math/powf_lut|inlined.0 + drop + f32.const 0 + local.get $7 + i32.const 31 + i32.shr_u + i32.eqz + local.get $2 + i32.const 1 + i32.shl + i32.const 2130706432 + i32.lt_u + i32.eq + br_if $~lib/util/math/powf_lut|inlined.0 + drop + local.get $1 + local.get $1 + f32.mul + br $~lib/util/math/powf_lut|inlined.0 + end + local.get $2 + i32.const 1 + i32.shl + i32.const 1 + i32.sub + i32.const -16777217 + i32.ge_u + if + f32.const 1 + local.get $0 + local.get $0 + f32.mul + local.tee $0 + f32.neg + local.get $0 + local.get $2 + i32.const 31 + i32.shr_u + if (result i32) + block $~lib/util/math/checkintf|inlined.0 (result i32) + i32.const 0 + local.get $7 + i32.const 23 + i32.shr_u + i32.const 255 + i32.and + local.tee $2 + i32.const 127 + i32.lt_u + br_if $~lib/util/math/checkintf|inlined.0 + drop + i32.const 2 + local.get $2 + i32.const 150 + i32.gt_u + br_if $~lib/util/math/checkintf|inlined.0 + drop + i32.const 0 + i32.const 1 + i32.const 150 + local.get $2 + i32.sub + i32.shl + local.tee $2 + i32.const 1 + i32.sub + local.get $7 + i32.and + br_if $~lib/util/math/checkintf|inlined.0 + drop + i32.const 1 + local.get $2 + local.get $7 + i32.and + br_if $~lib/util/math/checkintf|inlined.0 + drop + i32.const 2 + end + i32.const 1 + i32.eq + else + i32.const 0 + end + select + local.tee $0 + f32.div + local.get $0 + local.get $7 + i32.const 31 + i32.shr_u + select + br $~lib/util/math/powf_lut|inlined.0 + end + local.get $2 + i32.const 31 + i32.shr_u + if + block $~lib/util/math/checkintf|inlined.1 (result i32) + i32.const 0 + local.get $7 + i32.const 23 + i32.shr_u + i32.const 255 + i32.and + local.tee $4 + i32.const 127 + i32.lt_u + br_if $~lib/util/math/checkintf|inlined.1 + drop + i32.const 2 + local.get $4 + i32.const 150 + i32.gt_u + br_if $~lib/util/math/checkintf|inlined.1 + drop + i32.const 0 + i32.const 1 + i32.const 150 + local.get $4 + i32.sub + i32.shl + local.tee $4 + i32.const 1 + i32.sub + local.get $7 + i32.and + br_if $~lib/util/math/checkintf|inlined.1 + drop + i32.const 1 + local.get $4 + local.get $7 + i32.and + br_if $~lib/util/math/checkintf|inlined.1 + drop + i32.const 2 + end + local.tee $4 + i32.eqz + if + local.get $0 + local.get $0 + f32.sub + local.tee $0 + local.get $0 + f32.div + br $~lib/util/math/powf_lut|inlined.0 + end + i32.const 65536 + i32.const 0 + local.get $4 + i32.const 1 + i32.eq + select + local.set $4 + local.get $2 + i32.const 2147483647 + i32.and + local.set $2 + end + local.get $2 + i32.const 8388608 + i32.lt_u + if (result i32) + local.get $0 + f32.const 8388608 + f32.mul + i32.reinterpret_f32 + i32.const 2147483647 + i32.and + i32.const 192937984 + i32.sub + else + local.get $2 + end + local.set $2 + end + local.get $2 + local.get $2 + i32.const 1060306944 + i32.sub + local.tee $2 + i32.const -8388608 + i32.and + local.tee $6 + i32.sub + f32.reinterpret_i32 + f64.promote_f32 + local.get $2 + i32.const 19 + i32.shr_u + i32.const 15 + i32.and + i32.const 4 + i32.shl + i32.const 100024 + i32.add + local.tee $2 + f64.load + f64.mul + f64.const 1 + f64.sub + local.tee $3 + local.get $3 + f64.mul + local.set $8 + local.get $1 + f64.promote_f32 + local.get $3 + f64.const 0.288457581109214 + f64.mul + f64.const -0.36092606229713164 + f64.add + local.get $8 + local.get $8 + f64.mul + f64.mul + local.get $3 + f64.const 1.4426950408774342 + f64.mul + local.get $2 + f64.load offset=8 + local.get $6 + i32.const 23 + i32.shr_s + f64.convert_i32_s + f64.add + f64.add + local.get $3 + f64.const 0.480898481472577 + f64.mul + f64.const -0.7213474675006291 + f64.add + local.get $8 + f64.mul + f64.add + f64.add + f64.mul + local.tee $3 + i64.reinterpret_f64 + i64.const 47 + i64.shr_u + i64.const 65535 + i64.and + i64.const 32959 + i64.ge_u + if + f32.const -1584563250285286751870879e5 + f32.const 1584563250285286751870879e5 + local.get $4 + select + f32.const 1584563250285286751870879e5 + f32.mul + local.get $3 + f64.const 127.99999995700433 + f64.gt + br_if $~lib/util/math/powf_lut|inlined.0 + drop + f32.const -2.524354896707238e-29 + f32.const 2.524354896707238e-29 + local.get $4 + select + f32.const 2.524354896707238e-29 + f32.mul + local.get $3 + f64.const -150 + f64.le + br_if $~lib/util/math/powf_lut|inlined.0 + drop + end + local.get $3 + f64.const 211106232532992 + f64.add + local.tee $8 + i64.reinterpret_f64 + local.set $5 + local.get $3 + local.get $8 + f64.const 211106232532992 + f64.sub + f64.sub + local.tee $3 + f64.const 0.6931471806916203 + f64.mul + f64.const 1 + f64.add + local.get $3 + f64.const 0.05550361559341535 + f64.mul + f64.const 0.2402284522445722 + f64.add + local.get $3 + local.get $3 + f64.mul + f64.mul + f64.add + local.get $5 + i32.wrap_i64 + i32.const 31 + i32.and + i32.const 3 + i32.shl + i32.const 100280 + i32.add + i64.load + local.get $4 + i64.extend_i32_u + local.get $5 + i64.add + i64.const 47 + i64.shl + i64.add + f64.reinterpret_i64 + f64.mul + f32.demote_f64 + end + ) + (func $pow (param $0 f32) (param $1 f32) (result f32) + local.get $0 + local.get $1 + call $~lib/math/NativeMathf.pow + ) + +(func $sin (param $0 f32) (result f32) + (local $1 f32) + local.get $0 + f32.const 0.31830987334251404 + f32.mul + local.tee $0 + f32.floor + local.set $1 + local.get $0 + local.get $1 + f32.sub + local.tee $0 + f32.const 1 + local.get $0 + f32.sub + f32.mul + local.tee $0 + local.get $0 + f32.const 3.5999999046325684 + f32.mul + f32.const 3.0999999046325684 + f32.add + f32.mul + local.tee $0 + f32.neg + local.get $0 + local.get $1 + i32.trunc_sat_f32_s + i32.const 1 + i32.and + select +) ;;------------------------------------------------------------------------------ ;; Types. Only useful to define the jump table type, which is @@ -201,7 +782,54 @@ ;;------------------------------------------------------------------------------ ;; "Entry point" for the player ;;------------------------------------------------------------------------------ -(start $render) ;; we run render automagically when the module is instantiated + +(func $render_128_samples (param) + (local $rendersamplecount i32) + (i32.const 0) + (local.set $rendersamplecount) + (loop $sample_loop + (if (i32.eq (global.get $sample) (i32.const 0)) + (then + (call $su_update_voices) + ) + ) + (global.set $COM (i32.const {{index .Labels "su_patch_code"}})) + (global.set $VAL (i32.const {{index .Labels "su_patch_parameters"}})) +{{- if .SupportsPolyphony}} + (global.set $COM_instr_start (global.get $COM)) + (global.set $VAL_instr_start (global.get $VAL)) +{{- end}} + (global.set $WRK (i32.const {{index .Labels "su_voices"}})) + (global.set $voice (i32.const {{index .Labels "su_voices"}})) + (global.set $voicesRemain (i32.const {{.Song.Patch.NumVoices | printf "%v"}})) +{{- if .HasOp "delay"}} + (global.set $delayWRK (i32.const {{index .Labels "su_delaylines"}})) +{{- end}} + (call $su_run_vm) + (i64.store (global.get $outputBufPtr) (i64.load (i32.const 1440))) ;; load the sample from left & right channels as one 64bit int and store it in the address pointed by outputBufPtr + (global.set $outputBufPtr (i32.add (global.get $outputBufPtr) (i32.const 8))) ;; advance outputbufptr + (i64.store (i32.const 1440) (i64.const 0)) ;; clear the left and right ports + (global.set $sample (i32.add (global.get $sample) (i32.const 1))) + (global.set $globaltick (i32.add (global.get $globaltick) (i32.const 1))) + (if (i32.eq (global.get $sample) (i32.const {{.Song.SamplesPerRow}})) + (then + (global.set $sample (i32.const 0)) + (global.set $row (i32.add (global.get $row) (i32.const 1))) + ) + ) + (local.set $rendersamplecount (i32.add (local.get $rendersamplecount) (i32.const 1))) + (br_if $sample_loop (i32.lt_s (local.get $rendersamplecount) (i32.const 128))) + ) + (if $row_loop (i32.eq (global.get $row) (i32.const {{.PatternLength}})) + ( then + (global.set $row (i32.const 0)) + (global.set $pattern (i32.add (global.get $pattern) (i32.const 1))) + ) + ) +) +(export "render_128_samples" (func $render_128_samples)) + +;; (start $render) ;; we run render automagically when the module is instantiated (func $render (param) {{- if .Output16Bit }} (local $channel i32) {{- end }}