
Similar to InlineASM there is needed a new chapter about InlineC.... see for example this thread with questions/discussions: viewtopic.php?t=81776
Moderator: Documentation Editors
Code: Select all
; Sample for a Codeline C in PureBasic.
ProcedureCDLL HelloStar(q.q)
*p=AllocateMemory(100)
! sprintf(p_p,"Hello visible universe on star %.0lf.",v_q*108420.0);
ProcedureReturn *p
EndProcedure
*p=HelloStar(Random(9223372036854775807))
Debug PeekS(*p,-1,#PB_Ascii)
FreeMemory(*p)
; Hello visible universe on star 889966170588799872008192.
Code: Select all
; Sample for a Codeline C in PureBasic.
Procedure InitDLL()
Global *retval = AllocateMemory(1024)
EndProcedure : InitDLL()
ProcedureCDLL HelloStar(q.q) ; Retval static string
! sprintf(gp_retval,"Hello visible universe on star %.0lf.", v_q * 108420.0);
ProcedureReturn *retval
EndProcedure
*p=HelloStar(Random(9223372036854775807))
Debug PeekS(*p,-1,#PB_Ascii)
FreeMemory(*p)
; Hello visible universe on star 889966170588799872008192.
Code: Select all
CompilerIf #PB_Compiler_Backend = #PB_Backend_C
Procedure.q FastHash64(*buf,len,Seed.q=0)
Protected result.q
;FastHash64 algorithm by Zilong Tan
!typedef unsigned long long uint64_t;
!#define mix(h) ({ \
! (h) ^= (h) >> 23; \
! (h) *= 0x2127599bf4325c37ULL; \
! (h) ^= (h) >> 47; })
!
! const uint64_t m = 0x880355f21e6d1965ULL;
! const uint64_t *pos = (const uint64_t *)p_buf;
! const uint64_t *end = pos + (v_len / 8);
! const unsigned char *pos2;
! uint64_t h = v_seed ^ (v_len * m);
! uint64_t v;
! uint64_t result;
! while (pos != end) {
! v = *pos++;
! h ^= mix(v);
! h *= m;
! }
! pos2 = (const unsigned char*)pos;
! v = 0;
! switch (v_len & 7) {
! case 7: v ^= (uint64_t)pos2[6] << 48;
! case 6: v ^= (uint64_t)pos2[5] << 40;
! case 5: v ^= (uint64_t)pos2[4] << 32;
! case 4: v ^= (uint64_t)pos2[3] << 24;
! case 3: v ^= (uint64_t)pos2[2] << 16;
! case 2: v ^= (uint64_t)pos2[1] << 8;
! case 1: v ^= (uint64_t)pos2[0];
! h ^= mix(v);
! h *= m;
! }
!
! v_result = mix(h);
ProcedureReturn result
EndProcedure
CompilerElse
Procedure.q FastHash64(*Buffer, Len, Seed.q=0)
; FastHash64 algorithm by Zilong Tan ported by wilbert
!mov r10, 0x2127599bf4325c37
!mov r11, 0x880355f21e6d1965
!mov rdx, [p.p_Buffer]
!mov rcx, [p.v_Len]
!mov rax, rcx ; h = seed ^ (len * m);
!imul rax, r11
!xor rax, [p.v_Seed]
!sub rcx, 8
!jc .l1
; 8 byte loop
!.l0:
!mov r8, [rdx] ; v = *pos++;
!add rdx, 8
; -- mix(v) start --
!mov r9, r8
!shr r9, 23
!xor r8, r9
!imul r8, r10
!mov r9, r8
!shr r9, 47
!xor r8, r9
; -- mix end --
!xor rax, r8 ; h ^= mix(v);
!imul rax, r11 ; h *= m;
!sub rcx, 8
!jnc .l0
; remaining bytes
!.l1:
!add rcx, 8
!jz .l5
!xor r8, r8
!test rcx, 4
!jz .l2
; get 4 bytes
!mov r8d, [rdx]
!add rdx, 4
!ror r8, 32
!.l2:
!test rcx, 2
!jz .l3
; get 2 bytes
!movzx r9d, word [rdx]
!add rdx, 2
!xor r8, r9
!ror r8, 16
!.l3:
!test rcx, 1
!jz .l4
; get 1 byte
!movzx r9d, byte [rdx]
!xor r8, r9
!ror r8, 8
!.l4:
!and rcx, 7
!shl rcx, 3
!rol r8, cl
; -- mix(v) start --
!mov r9, r8
!shr r9, 23
!xor r8, r9
!imul r8, r10
!mov r9, r8
!shr r9, 47
!xor r8, r9
; -- mix end --
!xor rax, r8 ; h ^= mix(v);
!imul rax, r11 ; h *= m;
; -- mix(h) start --
!.l5:
!mov r9, rax
!shr r9, 23
!xor rax, r9
!imul rax, r10
!mov r9, rax
!shr r9, 47
!xor rax, r9
; -- mix end --
ProcedureReturn ; return mix(h);
EndProcedure
CompilerEndIf
Global s.s = "hello world c"
Debug FastHash64(@s,StringByteLength(s))
;-5558325713940964056 fasm
;-5558325713940964056 c backend
Code: Select all
#ifndef PORTAUDIO_H
#define PORTAUDIO_H
/*
* $Id$
* PortAudio Portable Real-Time Audio Library
* PortAudio API Header File
* Latest version available at: http://www.portaudio.com/
*
* Copyright (c) 1999-2002 Ross Bencina and Phil Burk
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version. It is also
* requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@ingroup public_header
@brief The portable PortAudio API.
*/
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/** Retrieve the release number of the currently running PortAudio build.
For example, for version "19.5.1" this will return 0x00130501.
@see paMakeVersionNumber
*/
int Pa_GetVersion( void );
/** Retrieve a textual description of the current PortAudio build,
e.g. "PortAudio V19.5.0-devel, revision 1952M".
The format of the text may change in the future. Do not try to parse the
returned string.
@deprecated As of 19.5.0, use Pa_GetVersionInfo()->versionText instead.
*/
const char* Pa_GetVersionText( void );
/**
Generate a packed integer version number in the same format used
by Pa_GetVersion(). Use this to compare a specified version number with
the currently running version. For example:
@code
if( Pa_GetVersion() < paMakeVersionNumber(19,5,1) ) {}
@endcode
@see Pa_GetVersion, Pa_GetVersionInfo
@version Available as of 19.5.0.
*/
#define paMakeVersionNumber(major, minor, subminor) \
(((major)&0xFF)<<16 | ((minor)&0xFF)<<8 | ((subminor)&0xFF))
/**
A structure containing PortAudio API version information.
@see Pa_GetVersionInfo, paMakeVersionNumber
@version Available as of 19.5.0.
*/
typedef struct PaVersionInfo {
int versionMajor;
int versionMinor;
int versionSubMinor;
/**
This is currently the Git revision hash but may change in the future.
The versionControlRevision is updated by running a script before compiling the library.
If the update does not occur, this value may refer to an earlier revision.
*/
const char *versionControlRevision;
/** Version as a string, for example "PortAudio V19.5.0-devel, revision 1952M" */
const char *versionText;
} PaVersionInfo;
/** Retrieve version information for the currently running PortAudio build.
@return A pointer to an immutable PaVersionInfo structure.
@note This function can be called at any time. It does not require PortAudio
to be initialized. The structure pointed to is statically allocated. Do not
attempt to free it or modify it.
@see PaVersionInfo, paMakeVersionNumber
@version Available as of 19.5.0.
*/
const PaVersionInfo* Pa_GetVersionInfo();
/** Error codes returned by PortAudio functions.
Note that with the exception of paNoError, all PaErrorCodes are negative.
*/
typedef int PaError;
typedef enum PaErrorCode
{
paNoError = 0,
paNotInitialized = -10000,
paUnanticipatedHostError,
paInvalidChannelCount,
paInvalidSampleRate,
paInvalidDevice,
paInvalidFlag,
paSampleFormatNotSupported,
paBadIODeviceCombination,
paInsufficientMemory,
paBufferTooBig,
paBufferTooSmall,
paNullCallback,
paBadStreamPtr,
paTimedOut,
paInternalError,
paDeviceUnavailable,
paIncompatibleHostApiSpecificStreamInfo,
paStreamIsStopped,
paStreamIsNotStopped,
paInputOverflowed,
paOutputUnderflowed,
paHostApiNotFound,
paInvalidHostApi,
paCanNotReadFromACallbackStream,
paCanNotWriteToACallbackStream,
paCanNotReadFromAnOutputOnlyStream,
paCanNotWriteToAnInputOnlyStream,
paIncompatibleStreamHostApi,
paBadBufferPtr
} PaErrorCode;
/** Translate the supplied PortAudio error code into a human readable
message.
*/
const char *Pa_GetErrorText( PaError errorCode );
/** Library initialization function - call this before using PortAudio.
This function initializes internal data structures and prepares underlying
host APIs for use. With the exception of Pa_GetVersion(), Pa_GetVersionText(),
and Pa_GetErrorText(), this function MUST be called before using any other
PortAudio API functions.
If Pa_Initialize() is called multiple times, each successful
call must be matched with a corresponding call to Pa_Terminate().
Pairs of calls to Pa_Initialize()/Pa_Terminate() may overlap, and are not
required to be fully nested.
Note that if Pa_Initialize() returns an error code, Pa_Terminate() should
NOT be called.
@return paNoError if successful, otherwise an error code indicating the cause
of failure.
@see Pa_Terminate
*/
PaError Pa_Initialize( void );
/** Library termination function - call this when finished using PortAudio.
This function deallocates all resources allocated by PortAudio since it was
initialized by a call to Pa_Initialize(). In cases where Pa_Initialise() has
been called multiple times, each call must be matched with a corresponding call
to Pa_Terminate(). The final matching call to Pa_Terminate() will automatically
close any PortAudio streams that are still open.
Pa_Terminate() MUST be called before exiting a program which uses PortAudio.
Failure to do so may result in serious resource leaks, such as audio devices
not being available until the next reboot.
@return paNoError if successful, otherwise an error code indicating the cause
of failure.
@see Pa_Initialize
*/
PaError Pa_Terminate( void );
....
Code: Select all
ImportC "portaudio_x64.lib" : EndImport
!#include "D:\portaudio\portaudio.h";
!#define SAMPLE_RATE (44100)
!#define PA_SAMPLE_TYPE paFloat32
!typedef float SAMPLE;
#DOUBLEPREC = 1
CompilerIf #DOUBLEPREC = 0
Structure complex
Re.d
Im.d
EndStructure
CompilerElse
Structure complex
Re.f
Im.f
EndStructure
CompilerEndIf
Structure arcomplex
ar.complex[0]
EndStructure
Procedure _stockham(*x.arcomplex,n.i,flag.i,n2.i,*y.arcomplex)
Protected *y_orig.arcomplex
Protected *tmp.complex
Protected i.i, j.i, k.i, k2.i, Ls.i, r.i, jrs.i
Protected half, m, m2
Protected wr.d, wi.d, tr.d, ti.d
*y_orig = *y
half = n >> 1
r = half
Ls = 1
While(r >= n2)
*tmp = *x
*x = *y
*y = *tmp
m = 0
m2 = half
j=0
While j < ls
wr = Cos(#PI*j/Ls)
wi = -flag * Sin(#PI*j/Ls)
jrs = j*(r+r)
k = jrs
While k < jrs+r
k2 = k + r
tr = wr * *y\ar[k2]\Re - wi * *y\ar[k2]\Im
ti = wr * *y\ar[k2]\Im + wi * *y\ar[k2]\Re
*x\ar[m]\Re = *y\ar[k]\Re + tr
*x\ar[m]\Im = *y\ar[k]\Im + ti
*x\ar[m2]\Re = *y\ar[k]\Re - tr
*x\ar[m2]\Im = *y\ar[k]\Im - ti
m+1
m2+1
k+1
Wend
j+1
Wend
r >> 1
Ls << 1
Wend
CopyMemory(*x,*y,n*SizeOf(complex))
EndProcedure
Procedure fft(*x.arcomplex,n.i,flag.i=1)
Protected *y.arcomplex
*y = AllocateMemory((n)*SizeOf(complex))
_stockham(*x, n, flag, 1, *y)
FreeMemory(*y)
EndProcedure
#PI2 = 2 * #PI
#hamming =1
#Hanning = 2
#Blackman = 3
Global gNumNoInputs = 0;
Global fftpoints = 4096
Global Dim inp.complex(fftpoints)
Global Dim windowing.f(fftpoints)
Global windowtype = 1
Global samplesize = fftpoints / 4
Global *buf = AllocateMemory(fftpoints*SizeOf(complex))
For a = 0 To fftpoints
If windowtype = #Hamming
windowing(a) = 0.54 - (0.46 * Cos(#PI2 * a / ((fftpoints/2)-1)))
ElseIf windowtype = #Hanning
windowing(a) = 0.5 * (1.0-Cos((#pi2*a /(fftpoints/2)-1)))
ElseIf windowtype = #BLackman
windowing(a) = 0.42- ((0.5 * Cos(#PI2*a / (fftpoints-1))) + (0.08 * Cos(4*#PI*a/(fftpoints-1))))
EndIf
Next
Procedure Freqency()
Protected res.d, time.d
res = (44100 / 2.0 / fftpoints)
time = 1/res
EndProcedure
Procedure.f Mag(*val.complex)
ProcedureReturn Sqr(*val\Re * *val\re + *val\Im * *val\Im)
EndProcedure
Procedure.f CubicAmplifier(input.f)
Protected output.f, temp.f;
If input < 0.0
temp = input + 1.0;
output = (temp * temp * temp) - 1.0;
Else
temp = input - 1.0;
output = (temp * temp * temp) + 1.0;
EndIf
ProcedureReturn output;
EndProcedure
Macro FUZZ(x)
CubicAmplifier(CubicAmplifier(CubicAmplifier(CubicAmplifier(x))))
EndMacro
ProcedureCDLL fuzzCallback(*in.float,*out.float,framesPerBuffer,*timeInfo,statusFlags,*userData)
Protected a,half,*pbuf.float, in.s, out.s ,shift
half = fftpoints >> 1
For a = 0 To half-1
inp(a)\Re = *in\f * windowing(a)
inp(a)\Im = 0
*in+4
Next
fft(@inp(0),fftpoints,1) ;do forward fft
For a = 0 To half-256
inp(a)\Re = inp(a+256)\Re ;mag(@inp(Random(64,half))) ;mess with the signal
inp(a)\Im = inp(a+256)\Im
Next
fft(@inp(0),fftpoints,-1) ;do inverse fft
For a = 1 To half-1
If a < 20
*out\f = 0
Else
*out\f = inp(a)\re ;* windowing(a) ;write it out should really divide by ftpoints
EndIf
*out+4
Next
FillMemory(@inp(0),fftpoints*SizeOf(complex),0,#PB_Long)
ProcedureReturn 0
EndProcedure
OpenConsole()
!PaStreamParameters inputParameters;
!PaStreamParameters outputParameters;
!PaStream *stream;
Global err,pcb ;
pcb= @fuzzCallback()
!g_err = Pa_Initialize();
If err <> 0
Goto error;
EndIf
!inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
!if (inputParameters.device == paNoDevice) {
Debug "Error: No default input device."
Goto error;
!}
!inputParameters.channelCount = 2; /* stereo input */
!inputParameters.sampleFormat = PA_SAMPLE_TYPE;
!inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device )->defaultLowInputLatency;
!inputParameters.hostApiSpecificStreamInfo = 0;
!outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
!if (outputParameters.device == paNoDevice) {
Debug "Error: No Default output device."
Goto error;
!}
!outputParameters.channelCount = 2; /* stereo output */
!outputParameters.sampleFormat = PA_SAMPLE_TYPE;
!outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
!outputParameters.hostApiSpecificStreamInfo = 0;
!g_err = Pa_OpenStream(&stream,&inputParameters,&outputParameters,SAMPLE_RATE,g_samplesize,0,g_pcb,0);
If err <> 0
Goto error;
EndIf
!g_err = Pa_StartStream( stream );
If err <> 0
Goto error;
EndIf
PrintN("Hit ENTER to stop program.");
Input()
!g_err = Pa_CloseStream( stream );
If err <> 0
Goto error;
EndIf
PrintN("Finished.");
Input()
!Pa_Terminate();
error:
!Pa_Terminate();