mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-13 16:25:25 +00:00
Merge branch 'master' into windows-llvm-11.1.0
This commit is contained in:
@@ -607,9 +607,9 @@ floor_mod :: proc "contextless" (x, y: $T) -> T
|
||||
}
|
||||
|
||||
modf_f16 :: proc "contextless" (x: f16) -> (int: f16, frac: f16) {
|
||||
shift :: 16 - 5 - 1
|
||||
mask :: 0x1f
|
||||
bias :: 15
|
||||
shift :: F16_SHIFT
|
||||
mask :: F16_MASK
|
||||
bias :: F16_BIAS
|
||||
|
||||
if x < 1 {
|
||||
switch {
|
||||
@@ -641,9 +641,9 @@ modf_f16be :: proc "contextless" (x: f16be) -> (int: f16be, frac: f16be) {
|
||||
return f16be(i), f16be(f)
|
||||
}
|
||||
modf_f32 :: proc "contextless" (x: f32) -> (int: f32, frac: f32) {
|
||||
shift :: 32 - 8 - 1
|
||||
mask :: 0xff
|
||||
bias :: 127
|
||||
shift :: F32_SHIFT
|
||||
mask :: F32_MASK
|
||||
bias :: F32_BIAS
|
||||
|
||||
if x < 1 {
|
||||
switch {
|
||||
@@ -674,10 +674,10 @@ modf_f32be :: proc "contextless" (x: f32be) -> (int: f32be, frac: f32be) {
|
||||
i, f := #force_inline modf_f32(f32(x))
|
||||
return f32be(i), f32be(f)
|
||||
}
|
||||
modf_f64 :: proc "contextless" (x: f64) -> (int: f64, frac: f64) {
|
||||
shift :: 64 - 11 - 1
|
||||
mask :: 0x7ff
|
||||
bias :: 1023
|
||||
modf_f64 :: proc "contextless" (x: f64) -> (int: f64, frac: f64) {
|
||||
shift :: F64_SHIFT
|
||||
mask :: F64_MASK
|
||||
bias :: F64_BIAS
|
||||
|
||||
if x < 1 {
|
||||
switch {
|
||||
@@ -708,7 +708,7 @@ modf_f64be :: proc "contextless" (x: f64be) -> (int: f64be, frac: f64be) {
|
||||
i, f := #force_inline modf_f64(f64(x))
|
||||
return f64be(i), f64be(f)
|
||||
}
|
||||
modf :: proc{
|
||||
modf :: proc{
|
||||
modf_f16, modf_f16le, modf_f16be,
|
||||
modf_f32, modf_f32le, modf_f32be,
|
||||
modf_f64, modf_f64le, modf_f64be,
|
||||
@@ -1127,13 +1127,11 @@ inf_f32be :: proc "contextless" (sign: int) -> f32be {
|
||||
return f32be(inf_f64(sign))
|
||||
}
|
||||
inf_f64 :: proc "contextless" (sign: int) -> f64 {
|
||||
v: u64
|
||||
if sign >= 0 {
|
||||
v = 0x7ff00000_00000000
|
||||
return 0h7ff00000_00000000
|
||||
} else {
|
||||
v = 0xfff00000_00000000
|
||||
return 0hfff00000_00000000
|
||||
}
|
||||
return transmute(f64)v
|
||||
}
|
||||
inf_f64le :: proc "contextless" (sign: int) -> f64le {
|
||||
return f64le(inf_f64(sign))
|
||||
@@ -1161,8 +1159,7 @@ nan_f32be :: proc "contextless" () -> f32be {
|
||||
return f32be(nan_f64())
|
||||
}
|
||||
nan_f64 :: proc "contextless" () -> f64 {
|
||||
v: u64 = 0x7ff80000_00000001
|
||||
return transmute(f64)v
|
||||
return 0h7ff80000_00000001
|
||||
}
|
||||
nan_f64le :: proc "contextless" () -> f64le {
|
||||
return f64le(nan_f64())
|
||||
|
||||
@@ -39,4 +39,16 @@ cos_f32 :: proc "c" (θ: f32) -> f32 { return f32(cos_f64(f64(θ
|
||||
pow_f32 :: proc "c" (x, power: f32) -> f32 { return f32(pow_f64(f64(x), f64(power))) }
|
||||
fmuladd_f32 :: proc "c" (a, b, c: f32) -> f32 { return f32(fmuladd_f64(f64(a), f64(a), f64(c))) }
|
||||
ln_f32 :: proc "c" (x: f32) -> f32 { return f32(ln_f64(f64(x))) }
|
||||
exp_f32 :: proc "c" (x: f32) -> f32 { return f32(exp_f64(f64(x))) }
|
||||
exp_f32 :: proc "c" (x: f32) -> f32 { return f32(exp_f64(f64(x))) }
|
||||
|
||||
ln_f16le :: proc "contextless" (x: f16le) -> f16le { return #force_inline f16le(ln_f64(f64(x))) }
|
||||
ln_f16be :: proc "contextless" (x: f16be) -> f16be { return #force_inline f16be(ln_f64(f64(x))) }
|
||||
ln_f32le :: proc "contextless" (x: f32le) -> f32le { return #force_inline f32le(ln_f64(f64(x))) }
|
||||
ln_f32be :: proc "contextless" (x: f32be) -> f32be { return #force_inline f32be(ln_f64(f64(x))) }
|
||||
ln_f64le :: proc "contextless" (x: f64le) -> f64le { return #force_inline f64le(ln_f64(f64(x))) }
|
||||
ln_f64be :: proc "contextless" (x: f64be) -> f64be { return #force_inline f64be(ln_f64(f64(x))) }
|
||||
ln :: proc{
|
||||
ln_f16, ln_f16le, ln_f16be,
|
||||
ln_f32, ln_f32le, ln_f32be,
|
||||
ln_f64, ln_f64le, ln_f64be,
|
||||
}
|
||||
|
||||
@@ -68,17 +68,17 @@ package math
|
||||
@(private="file")
|
||||
stirling :: proc "contextless" (x: f64) -> (f64, f64) {
|
||||
@(static) gamS := [?]f64{
|
||||
7.87311395793093628397e-04,
|
||||
+7.87311395793093628397e-04,
|
||||
-2.29549961613378126380e-04,
|
||||
-2.68132617805781232825e-03,
|
||||
3.47222221605458667310e-03,
|
||||
8.33333333333482257126e-02,
|
||||
+3.47222221605458667310e-03,
|
||||
+8.33333333333482257126e-02,
|
||||
}
|
||||
|
||||
if x > 200 {
|
||||
return inf_f64(1), 1
|
||||
}
|
||||
SQRT_TWO_PI :: 2.506628274631000502417
|
||||
SQRT_TWO_PI :: 0h40040d931ff62706 // 2.506628274631000502417
|
||||
MAX_STIRLING :: 143.01608
|
||||
w := 1 / x
|
||||
w = 1 + w*((((gamS[0]*w+gamS[1])*w+gamS[2])*w+gamS[3])*w+gamS[4])
|
||||
@@ -113,13 +113,13 @@ gamma_f64 :: proc "contextless" (x: f64) -> f64 {
|
||||
}
|
||||
@(static) gamQ := [?]f64{
|
||||
-2.31581873324120129819e-05,
|
||||
5.39605580493303397842e-04,
|
||||
+5.39605580493303397842e-04,
|
||||
-4.45641913851797240494e-03,
|
||||
1.18139785222060435552e-02,
|
||||
3.58236398605498653373e-02,
|
||||
+1.18139785222060435552e-02,
|
||||
+3.58236398605498653373e-02,
|
||||
-2.34591795718243348568e-01,
|
||||
7.14304917030273074085e-02,
|
||||
1.00000000000000000320e+00,
|
||||
+7.14304917030273074085e-02,
|
||||
+1.00000000000000000320e+00,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -197,9 +197,9 @@ lgamma_f64 :: proc "contextless" (x: f64) -> (lgamma: f64, sign: int) {
|
||||
}
|
||||
|
||||
|
||||
Y_MIN :: 1.461632144968362245
|
||||
Y_MIN :: 0h3ff762d86356be3f // 1.461632144968362245
|
||||
TWO_52 :: 0h4330000000000000 // ~4.5036e+15
|
||||
TWO_53 :: 0h4340000000000000 // ~9.0072e+15
|
||||
TWO_53 :: 0h4340000000000000 // ~9.0072e+15
|
||||
TWO_58 :: 0h4390000000000000 // ~2.8823e+17
|
||||
TINY :: 0h3b90000000000000 // ~8.47033e-22
|
||||
Tc :: 0h3FF762D86356BE3F
|
||||
@@ -345,8 +345,8 @@ lgamma_f64 :: proc "contextless" (x: f64) -> (lgamma: f64, sign: int) {
|
||||
}
|
||||
|
||||
|
||||
lgamma_f16 :: proc "contextless" (x: f16) -> (lgamma: f16, sign: int) { r, s := lgamma_f64(f64(x)); return f16(r), s }
|
||||
lgamma_f32 :: proc "contextless" (x: f32) -> (lgamma: f32, sign: int) { r, s := lgamma_f64(f64(x)); return f32(r), s }
|
||||
lgamma_f16 :: proc "contextless" (x: f16) -> (lgamma: f16, sign: int) { r, s := lgamma_f64(f64(x)); return f16(r), s }
|
||||
lgamma_f32 :: proc "contextless" (x: f32) -> (lgamma: f32, sign: int) { r, s := lgamma_f64(f64(x)); return f32(r), s }
|
||||
lgamma_f16le :: proc "contextless" (x: f16le) -> (lgamma: f16le, sign: int) { r, s := lgamma_f64(f64(x)); return f16le(r), s }
|
||||
lgamma_f16be :: proc "contextless" (x: f16be) -> (lgamma: f16be, sign: int) { r, s := lgamma_f64(f64(x)); return f16be(r), s }
|
||||
lgamma_f32le :: proc "contextless" (x: f32le) -> (lgamma: f32le, sign: int) { r, s := lgamma_f64(f64(x)); return f32le(r), s }
|
||||
|
||||
@@ -100,11 +100,11 @@ log1p_f64le :: proc "contextless" (x: f64le) -> f64le { return f64le(log1p_f64(f
|
||||
log1p_f64be :: proc "contextless" (x: f64be) -> f64be { return f64be(log1p_f64(f64(x))) }
|
||||
|
||||
log1p_f64 :: proc "contextless" (x: f64) -> f64 {
|
||||
SQRT2_M1 :: 0h3fda827999fcef34 // Sqrt(2)-1
|
||||
SQRT2_HALF_M1 :: 0hbfd2bec333018866 // Sqrt(2)/2-1
|
||||
SQRT2_M1 :: 0h3fda827999fcef34 // sqrt(2)-1
|
||||
SQRT2_HALF_M1 :: 0hbfd2bec333018866 // sqrt(2)/2-1
|
||||
SMALL :: 0h3e20000000000000 // 2**-29
|
||||
TINY :: 1.0 / (1 << 54) // 2**-54
|
||||
TWO53 :: 1 << 53 // 2**53
|
||||
TINY :: 0h3c90000000000000 // 2**-54
|
||||
TWO53 :: 0h4340000000000000 // 2**53
|
||||
LN2HI :: 0h3fe62e42fee00000
|
||||
LN2LO :: 0h3dea39ef35793c76
|
||||
LP1 :: 0h3FE5555555555593
|
||||
@@ -128,15 +128,15 @@ log1p_f64 :: proc "contextless" (x: f64) -> f64 {
|
||||
f: f64
|
||||
iu: u64
|
||||
k := 1
|
||||
if absx < SQRT2_M1 { // |x| < Sqrt(2)-1
|
||||
if absx < SQRT2_M1 { // |x| < sqrt(2)-1
|
||||
if absx < SMALL { // |x| < 2**-29
|
||||
if absx < TINY { // |x| < 2**-54
|
||||
return x
|
||||
}
|
||||
return x - x*x*0.5
|
||||
}
|
||||
if x > SQRT2_HALF_M1 { // Sqrt(2)/2-1 < x
|
||||
// (Sqrt(2)/2-1) < x < (Sqrt(2)-1)
|
||||
if x > SQRT2_HALF_M1 { // sqrt(2)/2-1 < x
|
||||
// (sqrt(2)/2-1) < x < (sqrt(2)-1)
|
||||
k = 0
|
||||
f = x
|
||||
iu = 1
|
||||
@@ -163,14 +163,14 @@ log1p_f64 :: proc "contextless" (x: f64) -> f64 {
|
||||
c = 0
|
||||
}
|
||||
iu &= 0x000fffffffffffff
|
||||
if iu < 0x0006a09e667f3bcd { // mantissa of Sqrt(2)
|
||||
if iu < 0x0006a09e667f3bcd { // mantissa of sqrt(2)
|
||||
u = transmute(f64)(iu | 0x3ff0000000000000) // normalize u
|
||||
} else {
|
||||
k += 1
|
||||
u = transmute(f64)(iu | 0x3fe0000000000000) // normalize u/2
|
||||
iu = (0x0010000000000000 - iu) >> 2
|
||||
}
|
||||
f = u - 1.0 // Sqrt(2)/2 < u < Sqrt(2)
|
||||
f = u - 1.0 // sqrt(2)/2 < u < sqrt(2)
|
||||
}
|
||||
hfsq := 0.5 * f * f
|
||||
s, R, z: f64
|
||||
|
||||
@@ -11,7 +11,7 @@ String :: distinct Array(byte)
|
||||
|
||||
Version_Type_Major :: 0
|
||||
Version_Type_Minor :: 2
|
||||
Version_Type_Patch :: 0
|
||||
Version_Type_Patch :: 1
|
||||
|
||||
Version_Type :: struct {
|
||||
major, minor, patch: u8,
|
||||
|
||||
@@ -150,7 +150,7 @@ join :: proc(elems: ..string, allocator := context.allocator) -> string {
|
||||
context.allocator = allocator
|
||||
for elem, i in elems {
|
||||
if elem != "" {
|
||||
s := strings.join(elems[i:], "/")
|
||||
s := strings.join(elems[i:], "/", context.temp_allocator)
|
||||
return clean(s)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ struct OdinDocVersionType {
|
||||
|
||||
#define OdinDocVersionType_Major 0
|
||||
#define OdinDocVersionType_Minor 2
|
||||
#define OdinDocVersionType_Patch 0
|
||||
#define OdinDocVersionType_Patch 1
|
||||
|
||||
struct OdinDocHeaderBase {
|
||||
u8 magic[8];
|
||||
@@ -175,7 +175,8 @@ enum OdinDocEntityFlag : u64 {
|
||||
|
||||
struct OdinDocEntity {
|
||||
OdinDocEntityKind kind;
|
||||
u32 flags;
|
||||
u32 reserved;
|
||||
u64 flags;
|
||||
OdinDocPosition pos;
|
||||
OdinDocString name;
|
||||
OdinDocTypeIndex type;
|
||||
|
||||
2
vendor/OpenGL/constants.odin
vendored
2
vendor/OpenGL/constants.odin
vendored
@@ -1409,4 +1409,4 @@ TRANSFORM_FEEDBACK_OVERFLOW :: 0x82EC
|
||||
TRANSFORM_FEEDBACK_STREAM_OVERFLOW :: 0x82ED
|
||||
|
||||
// Extensions, extended as necessary
|
||||
DEVICE_LUID_EXT :: 0x9599;
|
||||
DEVICE_LUID_EXT :: 0x9599
|
||||
|
||||
2804
vendor/OpenGL/wrappers.odin
vendored
2804
vendor/OpenGL/wrappers.odin
vendored
File diff suppressed because it is too large
Load Diff
1
vendor/glfw/bindings/bindings.odin
vendored
1
vendor/glfw/bindings/bindings.odin
vendored
@@ -4,6 +4,7 @@ import "core:c"
|
||||
import vk "vendor:vulkan"
|
||||
|
||||
when ODIN_OS == "linux" { foreign import glfw "system:glfw" } // TODO: Add the billion-or-so static libs to link to in linux
|
||||
when ODIN_OS == "darwin" { foreign import glfw "system:glfw" }
|
||||
when ODIN_OS == "windows" {
|
||||
foreign import glfw {
|
||||
"../lib/glfw3_mt.lib",
|
||||
|
||||
306
vendor/portmidi/portmidi.odin
vendored
306
vendor/portmidi/portmidi.odin
vendored
@@ -3,7 +3,13 @@ package portmidi
|
||||
import "core:c"
|
||||
import "core:strings"
|
||||
|
||||
when ODIN_OS == "windows" { foreign import lib "portmidi.lib" }
|
||||
when ODIN_OS == "windows" {
|
||||
foreign import lib {
|
||||
"portmidi_s.lib",
|
||||
"system:Winmm.lib",
|
||||
"system:Advapi32.lib",
|
||||
}
|
||||
}
|
||||
|
||||
#assert(size_of(b32) == size_of(c.int))
|
||||
|
||||
@@ -15,17 +21,17 @@ Error :: enum c.int {
|
||||
GotData = 1, /**< A "no error" return that also indicates data available */
|
||||
HostError = -10000,
|
||||
InvalidDeviceId, /** out of range or
|
||||
* output device when input is requested or
|
||||
* input device when output is requested or
|
||||
* device is already opened
|
||||
*/
|
||||
* output device when input is requested or
|
||||
* input device when output is requested or
|
||||
* device is already opened
|
||||
*/
|
||||
InsufficientMemory,
|
||||
BufferTooSmall,
|
||||
BufferOverflow,
|
||||
BadPtr, /* Stream parameter is nil or
|
||||
* stream is not opened or
|
||||
* stream is output when input is required or
|
||||
* stream is input when output is required */
|
||||
* stream is not opened or
|
||||
* stream is output when input is required or
|
||||
* stream is input when output is required */
|
||||
BadData, /** illegal midi data, e.g. missing EOX */
|
||||
InternalError,
|
||||
BufferMaxSize, /** buffer is already as large as it can be */
|
||||
@@ -38,30 +44,30 @@ Stream :: distinct rawptr
|
||||
@(default_calling_convention="c", link_prefix="Pm_")
|
||||
foreign lib {
|
||||
/**
|
||||
Initialize() is the library initialisation function - call this before
|
||||
using the library.
|
||||
Initialize() is the library initialisation function - call this before
|
||||
using the library.
|
||||
*/
|
||||
Initialize :: proc() -> Error ---
|
||||
|
||||
/**
|
||||
Terminate() is the library termination function - call this after
|
||||
using the library.
|
||||
Terminate() is the library termination function - call this after
|
||||
using the library.
|
||||
*/
|
||||
Terminate :: proc() -> Error ---
|
||||
|
||||
/**
|
||||
Test whether stream has a pending host error. Normally, the client finds
|
||||
out about errors through returned error codes, but some errors can occur
|
||||
asynchronously where the client does not
|
||||
explicitly call a function, and therefore cannot receive an error code.
|
||||
The client can test for a pending error using HasHostError(). If true,
|
||||
the error can be accessed and cleared by calling GetErrorText().
|
||||
Errors are also cleared by calling other functions that can return
|
||||
errors, e.g. OpenInput(), OpenOutput(), Read(), Write(). The
|
||||
client does not need to call HasHostError(). Any pending error will be
|
||||
reported the next time the client performs an explicit function call on
|
||||
the stream, e.g. an input or output operation. Until the error is cleared,
|
||||
no new error codes will be obtained, even for a different stream.
|
||||
Test whether stream has a pending host error. Normally, the client finds
|
||||
out about errors through returned error codes, but some errors can occur
|
||||
asynchronously where the client does not
|
||||
explicitly call a function, and therefore cannot receive an error code.
|
||||
The client can test for a pending error using HasHostError(). If true,
|
||||
the error can be accessed and cleared by calling GetErrorText().
|
||||
Errors are also cleared by calling other functions that can return
|
||||
errors, e.g. OpenInput(), OpenOutput(), Read(), Write(). The
|
||||
client does not need to call HasHostError(). Any pending error will be
|
||||
reported the next time the client performs an explicit function call on
|
||||
the stream, e.g. an input or output operation. Until the error is cleared,
|
||||
no new error codes will be obtained, even for a different stream.
|
||||
*/
|
||||
HasHostError :: proc(stream: Stream) -> b32 ---
|
||||
}
|
||||
@@ -103,8 +109,8 @@ DeviceInfo :: struct {
|
||||
structVersion: c.int, /**< this internal structure version */
|
||||
interf: cstring, /**< underlying MIDI API, e.g. MMSystem or DirectX */
|
||||
name: cstring, /**< device name, e.g. USB MidiSport 1x1 */
|
||||
input: c.int, /**< true iff input is available */
|
||||
output: c.int, /**< true iff output is available */
|
||||
input: b32, /**< true iff input is available */
|
||||
output: b32, /**< true iff output is available */
|
||||
opened: b32, /**< used by generic PortMidi code to do error checking on arguments */
|
||||
}
|
||||
|
||||
@@ -132,79 +138,78 @@ Before :: #force_inline proc "c" (t1, t2: Timestamp) -> b32 {
|
||||
@(default_calling_convention="c", link_prefix="Pm_")
|
||||
foreign lib {
|
||||
/**
|
||||
GetDeviceInfo() returns a pointer to a DeviceInfo structure
|
||||
referring to the device specified by id.
|
||||
If id is out of range the function returns nil.
|
||||
GetDeviceInfo() returns a pointer to a DeviceInfo structure
|
||||
referring to the device specified by id.
|
||||
If id is out of range the function returns nil.
|
||||
|
||||
The returned structure is owned by the PortMidi implementation and must
|
||||
not be manipulated or freed. The pointer is guaranteed to be valid
|
||||
between calls to Initialize() and Terminate().
|
||||
The returned structure is owned by the PortMidi implementation and must
|
||||
not be manipulated or freed. The pointer is guaranteed to be valid
|
||||
between calls to Initialize() and Terminate().
|
||||
*/
|
||||
GetDeviceInfo :: proc(id: DeviceID) -> DeviceInfo ---
|
||||
GetDeviceInfo :: proc(id: DeviceID) -> ^DeviceInfo ---
|
||||
|
||||
/**
|
||||
OpenInput() and OpenOutput() open devices.
|
||||
OpenInput() and OpenOutput() open devices.
|
||||
|
||||
stream is the address of a Stream pointer which will receive
|
||||
a pointer to the newly opened stream.
|
||||
stream is the address of a Stream pointer which will receive
|
||||
a pointer to the newly opened stream.
|
||||
|
||||
inputDevice is the id of the device used for input (see DeviceID above).
|
||||
inputDevice is the id of the device used for input (see DeviceID above).
|
||||
|
||||
inputDriverInfo is a pointer to an optional driver specific data structure
|
||||
containing additional information for device setup or handle processing.
|
||||
inputDriverInfo is never required for correct operation. If not used
|
||||
inputDriverInfo should be nil.
|
||||
inputDriverInfo is a pointer to an optional driver specific data structure
|
||||
containing additional information for device setup or handle processing.
|
||||
inputDriverInfo is never required for correct operation. If not used
|
||||
inputDriverInfo should be nil.
|
||||
|
||||
outputDevice is the id of the device used for output (see DeviceID above.)
|
||||
outputDevice is the id of the device used for output (see DeviceID above.)
|
||||
|
||||
outputDriverInfo is a pointer to an optional driver specific data structure
|
||||
containing additional information for device setup or handle processing.
|
||||
outputDriverInfo is never required for correct operation. If not used
|
||||
outputDriverInfo should be nil.
|
||||
outputDriverInfo is a pointer to an optional driver specific data structure
|
||||
containing additional information for device setup or handle processing.
|
||||
outputDriverInfo is never required for correct operation. If not used
|
||||
outputDriverInfo should be nil.
|
||||
|
||||
For input, the buffersize specifies the number of input events to be
|
||||
buffered waiting to be read using Read(). For output, buffersize
|
||||
specifies the number of output events to be buffered waiting for output.
|
||||
(In some cases -- see below -- PortMidi does not buffer output at all
|
||||
and merely passes data to a lower-level API, in which case buffersize
|
||||
is ignored.)
|
||||
|
||||
latency is the delay in milliseconds applied to timestamps to determine
|
||||
when the output should actually occur. (If latency is < 0, 0 is assumed.)
|
||||
If latency is zero, timestamps are ignored and all output is delivered
|
||||
immediately. If latency is greater than zero, output is delayed until the
|
||||
message timestamp plus the latency. (NOTE: the time is measured relative
|
||||
to the time source indicated by time_proc. Timestamps are absolute,
|
||||
not relative delays or offsets.) In some cases, PortMidi can obtain
|
||||
better timing than your application by passing timestamps along to the
|
||||
device driver or hardware. Latency may also help you to synchronize midi
|
||||
data to audio data by matching midi latency to the audio buffer latency.
|
||||
For input, the buffersize specifies the number of input events to be
|
||||
buffered waiting to be read using Read(). For output, buffersize
|
||||
specifies the number of output events to be buffered waiting for output.
|
||||
(In some cases -- see below -- PortMidi does not buffer output at all
|
||||
and merely passes data to a lower-level API, in which case buffersize
|
||||
is ignored.)
|
||||
|
||||
time_proc is a pointer to a procedure that returns time in milliseconds. It
|
||||
may be nil, in which case a default millisecond timebase (PortTime) is
|
||||
used. If the application wants to use PortTime, it should start the timer
|
||||
(call Pt_Start) before calling OpenInput or OpenOutput. If the
|
||||
application tries to start the timer *after* OpenInput or OpenOutput,
|
||||
it may get a ptAlreadyStarted error from Pt_Start, and the application's
|
||||
preferred time resolution and callback function will be ignored.
|
||||
time_proc result values are appended to incoming MIDI data, and time_proc
|
||||
times are used to schedule outgoing MIDI data (when latency is non-zero).
|
||||
latency is the delay in milliseconds applied to timestamps to determine
|
||||
when the output should actually occur. (If latency is < 0, 0 is assumed.)
|
||||
If latency is zero, timestamps are ignored and all output is delivered
|
||||
immediately. If latency is greater than zero, output is delayed until the
|
||||
message timestamp plus the latency. (NOTE: the time is measured relative
|
||||
to the time source indicated by time_proc. Timestamps are absolute,
|
||||
not relative delays or offsets.) In some cases, PortMidi can obtain
|
||||
better timing than your application by passing timestamps along to the
|
||||
device driver or hardware. Latency may also help you to synchronize midi
|
||||
data to audio data by matching midi latency to the audio buffer latency.
|
||||
|
||||
time_info is a pointer passed to time_proc.
|
||||
time_proc is a pointer to a procedure that returns time in milliseconds. It
|
||||
may be nil, in which case a default millisecond timebase (PortTime) is
|
||||
used. If the application wants to use PortTime, it should start the timer
|
||||
(call Pt_Start) before calling OpenInput or OpenOutput. If the
|
||||
application tries to start the timer *after* OpenInput or OpenOutput,
|
||||
it may get a ptAlreadyStarted error from Pt_Start, and the application's
|
||||
preferred time resolution and callback function will be ignored.
|
||||
time_proc result values are appended to incoming MIDI data, and time_proc
|
||||
times are used to schedule outgoing MIDI data (when latency is non-zero).
|
||||
|
||||
Example: If I provide a timestamp of 5000, latency is 1, and time_proc
|
||||
returns 4990, then the desired output time will be when time_proc returns
|
||||
timestamp+latency = 5001. This will be 5001-4990 = 11ms from now.
|
||||
time_info is a pointer passed to time_proc.
|
||||
|
||||
return value:
|
||||
Upon success Open() returns NoError and places a pointer to a
|
||||
valid Stream in the stream argument.
|
||||
If a call to Open() fails a nonzero error code is returned (see
|
||||
PMError above) and the value of port is invalid.
|
||||
Example: If I provide a timestamp of 5000, latency is 1, and time_proc
|
||||
returns 4990, then the desired output time will be when time_proc returns
|
||||
timestamp+latency = 5001. This will be 5001-4990 = 11ms from now.
|
||||
|
||||
Any stream that is successfully opened should eventually be closed
|
||||
by calling Close().
|
||||
return value:
|
||||
Upon success Open() returns NoError and places a pointer to a
|
||||
valid Stream in the stream argument.
|
||||
If a call to Open() fails a nonzero error code is returned (see
|
||||
PMError above) and the value of port is invalid.
|
||||
|
||||
Any stream that is successfully opened should eventually be closed
|
||||
by calling Close().
|
||||
*/
|
||||
OpenInput :: proc(stream: ^Stream,
|
||||
inputDevice: DeviceID,
|
||||
@@ -373,71 +378,80 @@ MessageData2 :: #force_inline proc "c" (msg: Message) -> c.int {
|
||||
return c.int((msg >> 16) & 0xFF)
|
||||
}
|
||||
|
||||
MessageCompose :: MessageMake
|
||||
MessageDecompose :: #force_inline proc "c" (msg: Message) -> (status, data1, data2: c.int) {
|
||||
status = c.int(msg & 0xFF)
|
||||
data1 = c.int((msg >> 8) & 0xFF)
|
||||
data2 = c.int((msg >> 16) & 0xFF)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Message :: distinct i32
|
||||
/**
|
||||
All midi data comes in the form of Event structures. A sysex
|
||||
message is encoded as a sequence of Event structures, with each
|
||||
structure carrying 4 bytes of the message, i.e. only the first
|
||||
Event carries the status byte.
|
||||
All midi data comes in the form of Event structures. A sysex
|
||||
message is encoded as a sequence of Event structures, with each
|
||||
structure carrying 4 bytes of the message, i.e. only the first
|
||||
Event carries the status byte.
|
||||
|
||||
Note that MIDI allows nested messages: the so-called "real-time" MIDI
|
||||
messages can be inserted into the MIDI byte stream at any location,
|
||||
including within a sysex message. MIDI real-time messages are one-byte
|
||||
messages used mainly for timing (see the MIDI spec). PortMidi retains
|
||||
the order of non-real-time MIDI messages on both input and output, but
|
||||
it does not specify exactly how real-time messages are processed. This
|
||||
is particulary problematic for MIDI input, because the input parser
|
||||
must either prepare to buffer an unlimited number of sysex message
|
||||
bytes or to buffer an unlimited number of real-time messages that
|
||||
arrive embedded in a long sysex message. To simplify things, the input
|
||||
parser is allowed to pass real-time MIDI messages embedded within a
|
||||
sysex message, and it is up to the client to detect, process, and
|
||||
remove these messages as they arrive.
|
||||
Note that MIDI allows nested messages: the so-called "real-time" MIDI
|
||||
messages can be inserted into the MIDI byte stream at any location,
|
||||
including within a sysex message. MIDI real-time messages are one-byte
|
||||
messages used mainly for timing (see the MIDI spec). PortMidi retains
|
||||
the order of non-real-time MIDI messages on both input and output, but
|
||||
it does not specify exactly how real-time messages are processed. This
|
||||
is particulary problematic for MIDI input, because the input parser
|
||||
must either prepare to buffer an unlimited number of sysex message
|
||||
bytes or to buffer an unlimited number of real-time messages that
|
||||
arrive embedded in a long sysex message. To simplify things, the input
|
||||
parser is allowed to pass real-time MIDI messages embedded within a
|
||||
sysex message, and it is up to the client to detect, process, and
|
||||
remove these messages as they arrive.
|
||||
|
||||
When receiving sysex messages, the sysex message is terminated
|
||||
by either an EOX status byte (anywhere in the 4 byte messages) or
|
||||
by a non-real-time status byte in the low order byte of the message.
|
||||
If you get a non-real-time status byte but there was no EOX byte, it
|
||||
means the sysex message was somehow truncated. This is not
|
||||
considered an error; e.g., a missing EOX can result from the user
|
||||
disconnecting a MIDI cable during sysex transmission.
|
||||
When receiving sysex messages, the sysex message is terminated
|
||||
by either an EOX status byte (anywhere in the 4 byte messages) or
|
||||
by a non-real-time status byte in the low order byte of the message.
|
||||
If you get a non-real-time status byte but there was no EOX byte, it
|
||||
means the sysex message was somehow truncated. This is not
|
||||
considered an error; e.g., a missing EOX can result from the user
|
||||
disconnecting a MIDI cable during sysex transmission.
|
||||
|
||||
A real-time message can occur within a sysex message. A real-time
|
||||
message will always occupy a full Event with the status byte in
|
||||
the low-order byte of the Event message field. (This implies that
|
||||
the byte-order of sysex bytes and real-time message bytes may not
|
||||
be preserved -- for example, if a real-time message arrives after
|
||||
3 bytes of a sysex message, the real-time message will be delivered
|
||||
first. The first word of the sysex message will be delivered only
|
||||
after the 4th byte arrives, filling the 4-byte Event message field.
|
||||
|
||||
The timestamp field is observed when the output port is opened with
|
||||
a non-zero latency. A timestamp of zero means "use the current time",
|
||||
which in turn means to deliver the message with a delay of
|
||||
latency (the latency parameter used when opening the output port.)
|
||||
Do not expect PortMidi to sort data according to timestamps --
|
||||
messages should be sent in the correct order, and timestamps MUST
|
||||
be non-decreasing. See also "Example" for OpenOutput() above.
|
||||
A real-time message can occur within a sysex message. A real-time
|
||||
message will always occupy a full Event with the status byte in
|
||||
the low-order byte of the Event message field. (This implies that
|
||||
the byte-order of sysex bytes and real-time message bytes may not
|
||||
be preserved -- for example, if a real-time message arrives after
|
||||
3 bytes of a sysex message, the real-time message will be delivered
|
||||
first. The first word of the sysex message will be delivered only
|
||||
after the 4th byte arrives, filling the 4-byte Event message field.
|
||||
|
||||
A sysex message will generally fill many Event structures. On
|
||||
output to a Stream with non-zero latency, the first timestamp
|
||||
on sysex message data will determine the time to begin sending the
|
||||
message. PortMidi implementations may ignore timestamps for the
|
||||
remainder of the sysex message.
|
||||
|
||||
On input, the timestamp ideally denotes the arrival time of the
|
||||
status byte of the message. The first timestamp on sysex message
|
||||
data will be valid. Subsequent timestamps may denote
|
||||
when message bytes were actually received, or they may be simply
|
||||
copies of the first timestamp.
|
||||
The timestamp field is observed when the output port is opened with
|
||||
a non-zero latency. A timestamp of zero means "use the current time",
|
||||
which in turn means to deliver the message with a delay of
|
||||
latency (the latency parameter used when opening the output port.)
|
||||
Do not expect PortMidi to sort data according to timestamps --
|
||||
messages should be sent in the correct order, and timestamps MUST
|
||||
be non-decreasing. See also "Example" for OpenOutput() above.
|
||||
|
||||
Timestamps for nested messages: If a real-time message arrives in
|
||||
the middle of some other message, it is enqueued immediately with
|
||||
the timestamp corresponding to its arrival time. The interrupted
|
||||
non-real-time message or 4-byte packet of sysex data will be enqueued
|
||||
later. The timestamp of interrupted data will be equal to that of
|
||||
the interrupting real-time message to insure that timestamps are
|
||||
non-decreasing.
|
||||
A sysex message will generally fill many Event structures. On
|
||||
output to a Stream with non-zero latency, the first timestamp
|
||||
on sysex message data will determine the time to begin sending the
|
||||
message. PortMidi implementations may ignore timestamps for the
|
||||
remainder of the sysex message.
|
||||
|
||||
On input, the timestamp ideally denotes the arrival time of the
|
||||
status byte of the message. The first timestamp on sysex message
|
||||
data will be valid. Subsequent timestamps may denote
|
||||
when message bytes were actually received, or they may be simply
|
||||
copies of the first timestamp.
|
||||
|
||||
Timestamps for nested messages: If a real-time message arrives in
|
||||
the middle of some other message, it is enqueued immediately with
|
||||
the timestamp corresponding to its arrival time. The interrupted
|
||||
non-real-time message or 4-byte packet of sysex data will be enqueued
|
||||
later. The timestamp of interrupted data will be equal to that of
|
||||
the interrupting real-time message to insure that timestamps are
|
||||
non-decreasing.
|
||||
*/
|
||||
Event :: struct {
|
||||
message: Message,
|
||||
@@ -480,18 +494,18 @@ foreign lib {
|
||||
|
||||
/**
|
||||
Write() writes midi data from a buffer. This may contain:
|
||||
- short messages
|
||||
- short messages
|
||||
or
|
||||
- sysex messages that are converted into a sequence of Event
|
||||
structures, e.g. sending data from a file or forwarding them
|
||||
from midi input.
|
||||
- sysex messages that are converted into a sequence of Event
|
||||
structures, e.g. sending data from a file or forwarding them
|
||||
from midi input.
|
||||
|
||||
Use WriteSysEx() to write a sysex message stored as a contiguous
|
||||
array of bytes.
|
||||
|
||||
Sysex data may contain embedded real-time messages.
|
||||
*/
|
||||
Write :: proc(stream: Stream, buffer: [^]Event, length: i32) -> Error ---
|
||||
Write :: proc(stream: Stream, buffer: [^]Event, length: i32) -> Error ---
|
||||
|
||||
/**
|
||||
WriteShort() writes a timestamped non-system-exclusive midi message.
|
||||
|
||||
BIN
vendor/portmidi/portmidi_s.lib
vendored
BIN
vendor/portmidi/portmidi_s.lib
vendored
Binary file not shown.
Reference in New Issue
Block a user