To understand this, I want to tell the following scenario: I designed a game and finished it. I encrypted the audio data with AES. I will then decrypt these encrypted files while the game is opening. These files are encoded in bytes in memory. For example I want to create buffers for OpenAL.
NOTE: no encryption functions here. Because my example would be complicated and difficult.
Here is a simple sketch of what I want to do with CGo and Go:
package main
// #cgo windows CFLAGS: -DGO_WINDOWS -I.
// #cgo windows LDFLAGS: -L. -lsndfile-1
/*
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <math.h>
#include <string.h>
#include <errno.h>
#include "sndfile.h"
typedef struct {
sf_count_t offset, length ;
unsigned char data [16 * 1024] ;
} VIO_DATA;
static sf_count_t
vfget_filelen(void *user_data) {
VIO_DATA *vf = (VIO_DATA *) user_data;
return vf->length;
}
static sf_count_t
vfseek(sf_count_t offset, int whence, void *user_data) {
VIO_DATA *vf = (VIO_DATA *) user_data ;
switch (whence) {
case SEEK_SET :
vf->offset = offset ;
break ;
case SEEK_CUR :
vf->offset = vf->offset + offset ;
break ;
case SEEK_END :
vf->offset = vf->length + offset ;
break ;
default :
break ;
};
return vf->offset;
}
static sf_count_t
vfread (void *ptr, sf_count_t count, void *user_data) {
VIO_DATA *vf = (VIO_DATA *) user_data ;
if (vf->offset + count > vf->length)
count = vf->length - vf->offset ;
memcpy (ptr, vf->data + vf->offset, count) ;
vf->offset += count ;
return count ;
}
static sf_count_t
vfwrite (const void *ptr, sf_count_t count, void *user_data) {
VIO_DATA *vf = (VIO_DATA *) user_data ;
if(vf->offset >= sizeof(vf->data))
return 0;
if (vf->offset + count > sizeof(vf->data))
count = sizeof (vf->data) - vf->offset;
memcpy(vf->data + vf->offset, ptr, (size_t) count);
vf->offset += count;
if(vf->offset > vf->length)
vf->length = vf->offset ;
return count;
}
static sf_count_t
vftell(void *user_data) {
VIO_DATA *vf = (VIO_DATA *) user_data ;
return vf->offset;
}
void voidTest(void *data) {
printf("value in c: %s \n", (char*)data);
static VIO_DATA vio_data ;
// static short fdata [256];
SF_VIRTUAL_IO vio ;
SNDFILE * file ;
SF_INFO sfinfo ;
vio.get_filelen = vfget_filelen;
vio.seek = vfseek ;
vio.read = vfread;
vio.write = vfwrite;
vio.tell = vftell;
vio_data.offset = 0;
vio_data.length = 0;
memset (&sfinfo, 0, sizeof (sfinfo));
sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
if((file = sf_open_virtual (&vio, SFM_READ, &sfinfo, &vio_data)) == NULL) {
printf("Sndfile error: %s\n", sf_strerror(file));
exit(1);
// return;
}
// !As an example I want to know the number of channels etc.
printf("Channel: %i\n", sfinfo.channels);
sf_close(file);
}
*/
import "C"
import (
"io/ioutil"
"fmt"
"unsafe"
)
func main() {
byt, err := ioutil.ReadFile("birds22.wav")
if err != nil {
fmt.Println(err)
return
}
var v unsafe.Pointer
v = (unsafe.Pointer)(&byt[0])
C.voidTest(v)
// fmt.Println("byte:", string(byt))
fmt.Println("No crash: test successfuly")
}
Project folder:
- main.go
- birds22.wav
- libsndfile-1.dll
- sndfile.h
My build command: go build .
I am not an experienced C developer. That's why I work with CGo. But I will try to adapt C codes to CGO, which explains how to do this.
The sources I use and the codes I try to adapt: libsndfile virtualio test gosndfile virtualio test