mirror of https://github.com/mgba-emu/mgba.git
Build up DMA channel audio infrastructure from GBA.js
This commit is contained in:
parent
9bf6b571b1
commit
09b4a4a29a
|
@ -5,12 +5,14 @@ set(CMAKE_C_FLAGS_DEBUG "-g -Wall -Wextra -Wno-error=type-limits --std=gnu99")
|
||||||
set(CMAKE_C_FLAGS_RELEASE "-O3 -Wall -Wextra --std=gnu99")
|
set(CMAKE_C_FLAGS_RELEASE "-O3 -Wall -Wextra --std=gnu99")
|
||||||
file(GLOB ARM_SRC ${CMAKE_SOURCE_DIR}/src/arm/*.c)
|
file(GLOB ARM_SRC ${CMAKE_SOURCE_DIR}/src/arm/*.c)
|
||||||
file(GLOB GBA_SRC ${CMAKE_SOURCE_DIR}/src/gba/*.c)
|
file(GLOB GBA_SRC ${CMAKE_SOURCE_DIR}/src/gba/*.c)
|
||||||
|
file(GLOB UTIL_SRC ${CMAKE_SOURCE_DIR}/src/util/*.c)
|
||||||
file(GLOB RENDERER_SRC ${CMAKE_SOURCE_DIR}/src/gba/renderers/video-software.c)
|
file(GLOB RENDERER_SRC ${CMAKE_SOURCE_DIR}/src/gba/renderers/video-software.c)
|
||||||
file(GLOB DEBUGGER_SRC ${CMAKE_SOURCE_DIR}/src/debugger/*.c)
|
file(GLOB DEBUGGER_SRC ${CMAKE_SOURCE_DIR}/src/debugger/*.c)
|
||||||
file(GLOB THIRD_PARTY ${CMAKE_SOURCE_DIR}/third-party/linenoise/linenoise.c)
|
file(GLOB THIRD_PARTY ${CMAKE_SOURCE_DIR}/third-party/linenoise/linenoise.c)
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/src/arm)
|
include_directories(${CMAKE_SOURCE_DIR}/src/arm)
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/src/gba)
|
include_directories(${CMAKE_SOURCE_DIR}/src/gba)
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/src/debugger)
|
include_directories(${CMAKE_SOURCE_DIR}/src/debugger)
|
||||||
|
include_directories(${CMAKE_SOURCE_DIR}/src/util)
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/third-party/linenoise)
|
include_directories(${CMAKE_SOURCE_DIR}/third-party/linenoise)
|
||||||
|
|
||||||
find_package(SDL 1.2 REQUIRED)
|
find_package(SDL 1.2 REQUIRED)
|
||||||
|
@ -31,5 +33,5 @@ else()
|
||||||
endif()
|
endif()
|
||||||
include_directories(${SDL_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR})
|
include_directories(${SDL_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR})
|
||||||
|
|
||||||
add_executable(${BINARY_NAME} ${ARM_SRC} ${GBA_SRC} ${DEBUGGER_SRC} ${RENDERER_SRC} ${THIRD_PARTY} ${SDL_SRC} ${MAIN_SRC})
|
add_executable(${BINARY_NAME} ${ARM_SRC} ${GBA_SRC} ${DEBUGGER_SRC} ${RENDERER_SRC} ${UTIL_SRC} ${THIRD_PARTY} ${SDL_SRC} ${MAIN_SRC})
|
||||||
target_link_libraries(${BINARY_NAME} m pthread ${SDL_LIBRARY} ${OPENGL_LIBRARY})
|
target_link_libraries(${BINARY_NAME} m pthread ${SDL_LIBRARY} ${OPENGL_LIBRARY})
|
||||||
|
|
|
@ -1,13 +1,61 @@
|
||||||
#include "gba-audio.h"
|
#include "gba-audio.h"
|
||||||
|
|
||||||
#include "gba.h"
|
#include "gba.h"
|
||||||
|
#include "gba-io.h"
|
||||||
|
|
||||||
|
const unsigned GBA_AUDIO_SAMPLES = 4096 * sizeof(int32_t);
|
||||||
|
const unsigned GBA_AUDIO_FIFO_SIZE = 8 * sizeof(int32_t);
|
||||||
|
|
||||||
|
static void _sample(struct GBAAudio* audio);
|
||||||
|
|
||||||
void GBAAudioInit(struct GBAAudio* audio) {
|
void GBAAudioInit(struct GBAAudio* audio) {
|
||||||
(void)(audio);
|
audio->nextEvent = 0;
|
||||||
|
audio->eventDiff = 0;
|
||||||
|
audio->nextSample = 0;
|
||||||
|
audio->sampleRate = 0x8000;
|
||||||
|
audio->sampleInterval = GBA_ARM7TDMI_FREQUENCY / audio->sampleRate;
|
||||||
|
|
||||||
|
CircleBufferInit(&audio->left, GBA_AUDIO_SAMPLES);
|
||||||
|
CircleBufferInit(&audio->right, GBA_AUDIO_SAMPLES);
|
||||||
|
CircleBufferInit(&audio->chA.fifo, GBA_AUDIO_FIFO_SIZE);
|
||||||
|
CircleBufferInit(&audio->chB.fifo, GBA_AUDIO_FIFO_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBAAudioDeinit(struct GBAAudio* audio) {
|
void GBAAudioDeinit(struct GBAAudio* audio) {
|
||||||
(void)(audio);
|
CircleBufferDeinit(&audio->left);
|
||||||
|
CircleBufferDeinit(&audio->right);
|
||||||
|
CircleBufferDeinit(&audio->chA.fifo);
|
||||||
|
CircleBufferDeinit(&audio->chB.fifo);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t GBAAudioProcessEvents(struct GBAAudio* audio, int32_t cycles) {
|
||||||
|
audio->nextEvent -= cycles;
|
||||||
|
if (audio->nextEvent <= 0) {
|
||||||
|
audio->nextSample -= audio->eventDiff;
|
||||||
|
if (audio->nextSample <= 0) {
|
||||||
|
_sample(audio);
|
||||||
|
audio->nextSample += audio->sampleInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio->nextEvent = audio->nextSample;
|
||||||
|
audio->eventDiff = audio->nextEvent;
|
||||||
|
}
|
||||||
|
return audio->nextEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* info) {
|
||||||
|
switch (info->dest) {
|
||||||
|
case BASE_IO | REG_FIFO_A_LO:
|
||||||
|
audio->chA.dmaSource = number;
|
||||||
|
break;
|
||||||
|
case BASE_IO | REG_FIFO_B_LO:
|
||||||
|
audio->chB.dmaSource = number;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GBALog(audio->p, GBA_LOG_GAME_ERROR, "Invalid FIFO destination: 0x%08X", info->dest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
info->dstControl = DMA_FIXED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value) {
|
void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value) {
|
||||||
|
@ -51,15 +99,15 @@ void GBAAudioWriteSOUND4CNT_HI(struct GBAAudio* audio, uint16_t value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBAAudioWriteSOUNDCNT_LO(struct GBAAudio* audio, uint16_t value) {
|
void GBAAudioWriteSOUNDCNT_LO(struct GBAAudio* audio, uint16_t value) {
|
||||||
GBALog(audio->p, GBA_LOG_STUB, "Audio unimplemented");
|
audio->soundcntLo = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBAAudioWriteSOUNDCNT_HI(struct GBAAudio* audio, uint16_t value) {
|
void GBAAudioWriteSOUNDCNT_HI(struct GBAAudio* audio, uint16_t value) {
|
||||||
GBALog(audio->p, GBA_LOG_STUB, "Audio unimplemented");
|
audio->soundcntHi = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value) {
|
void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value) {
|
||||||
GBALog(audio->p, GBA_LOG_STUB, "Audio unimplemented");
|
audio->soundcntX = (value & 0xF0) | (audio->soundcntX & 0x0F);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value) {
|
void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value) {
|
||||||
|
@ -67,6 +115,46 @@ void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value) {
|
void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value) {
|
||||||
GBALog(audio->p, GBA_LOG_STUB, "Audio unimplemented");
|
struct CircleBuffer* fifo;
|
||||||
|
switch (address) {
|
||||||
|
case REG_FIFO_A_LO:
|
||||||
|
fifo = &audio->chA.fifo;
|
||||||
|
break;
|
||||||
|
case REG_FIFO_B_LO:
|
||||||
|
fifo = &audio->chB.fifo;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GBALog(audio->p, GBA_LOG_ERROR, "Bad FIFO write to address 0x%03x", address);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (!CircleBufferWrite32(fifo, value)) {
|
||||||
|
int32_t dummy;
|
||||||
|
CircleBufferRead32(fifo, &dummy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId) {
|
||||||
|
struct GBAAudioFIFO* channel;
|
||||||
|
if (fifoId == 0) {
|
||||||
|
channel = &audio->chA;
|
||||||
|
} else if (fifoId == 1) {
|
||||||
|
channel = &audio->chB;
|
||||||
|
} else {
|
||||||
|
GBALog(audio->p, GBA_LOG_ERROR, "Bad FIFO write to address 0x%03x", fifoId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (CircleBufferSize(&channel->fifo) < 4 * sizeof(int32_t)) {
|
||||||
|
struct GBADMA* dma = &audio->p->memory.dma[channel->dmaSource];
|
||||||
|
dma->nextCount = 4;
|
||||||
|
GBAMemoryServiceDMA(&audio->p->memory, channel->dmaSource, dma);
|
||||||
|
}
|
||||||
|
CircleBufferRead32(&channel->fifo, &channel->sample);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _sample(struct GBAAudio* audio) {
|
||||||
|
int32_t sampleLeft = 0;
|
||||||
|
int32_t sampleRight = 0;
|
||||||
|
|
||||||
|
CircleBufferWrite32(&audio->left, sampleLeft);
|
||||||
|
CircleBufferWrite32(&audio->right, sampleRight);
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
#ifndef GBA_AUDIO_H
|
#ifndef GBA_AUDIO_H
|
||||||
#define GBA_AUDIO_H
|
#define GBA_AUDIO_H
|
||||||
|
|
||||||
|
#include "circle-buffer.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct GBADMA;
|
||||||
|
|
||||||
union GBAAudioWave {
|
union GBAAudioWave {
|
||||||
struct {
|
struct {
|
||||||
unsigned length : 6;
|
unsigned length : 6;
|
||||||
|
@ -94,7 +98,9 @@ struct GBAAudioChannel4 {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GBAAudioFIFO {
|
struct GBAAudioFIFO {
|
||||||
|
struct CircleBuffer fifo;
|
||||||
|
int dmaSource;
|
||||||
|
int32_t sample;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GBAAudio {
|
struct GBAAudio {
|
||||||
|
@ -107,11 +113,74 @@ struct GBAAudio {
|
||||||
|
|
||||||
struct GBAAudioFIFO chA;
|
struct GBAAudioFIFO chA;
|
||||||
struct GBAAudioFIFO chB;
|
struct GBAAudioFIFO chB;
|
||||||
|
|
||||||
|
struct CircleBuffer left;
|
||||||
|
struct CircleBuffer right;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
unsigned volumeRight : 3;
|
||||||
|
unsigned : 1;
|
||||||
|
unsigned volumeLeft : 3;
|
||||||
|
unsigned : 1;
|
||||||
|
unsigned ch1Right : 1;
|
||||||
|
unsigned ch2Right : 1;
|
||||||
|
unsigned ch3Right : 1;
|
||||||
|
unsigned ch4Right : 1;
|
||||||
|
unsigned ch1Left : 1;
|
||||||
|
unsigned ch2Left : 1;
|
||||||
|
unsigned ch3Left : 1;
|
||||||
|
unsigned ch4Left : 1;
|
||||||
|
};
|
||||||
|
uint16_t soundcntLo;
|
||||||
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
unsigned volume : 2;
|
||||||
|
unsigned volumeDmaA : 1;
|
||||||
|
unsigned volumeDmaB : 1;
|
||||||
|
unsigned : 4;
|
||||||
|
unsigned dmaARight : 1;
|
||||||
|
unsigned dmaALeft : 1;
|
||||||
|
unsigned dmaATimer : 1;
|
||||||
|
unsigned dmaAReset : 1;
|
||||||
|
unsigned dmaBRight : 1;
|
||||||
|
unsigned dmaBLeft : 1;
|
||||||
|
unsigned dmaBTimer : 1;
|
||||||
|
unsigned dmaBReset : 1;
|
||||||
|
};
|
||||||
|
uint16_t soundcntHi;
|
||||||
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
unsigned playingCh1 : 1;
|
||||||
|
unsigned playingCh2 : 1;
|
||||||
|
unsigned playingCh3 : 1;
|
||||||
|
unsigned playingCh4 : 1;
|
||||||
|
unsigned : 3;
|
||||||
|
unsigned enable : 1;
|
||||||
|
unsigned : 8;
|
||||||
|
};
|
||||||
|
uint16_t soundcntX;
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned sampleRate;
|
||||||
|
|
||||||
|
int32_t nextEvent;
|
||||||
|
int32_t eventDiff;
|
||||||
|
int32_t nextSample;
|
||||||
|
|
||||||
|
int32_t sampleInterval;
|
||||||
};
|
};
|
||||||
|
|
||||||
void GBAAudioInit(struct GBAAudio* audio);
|
void GBAAudioInit(struct GBAAudio* audio);
|
||||||
void GBAAudioDeinit(struct GBAAudio* audio);
|
void GBAAudioDeinit(struct GBAAudio* audio);
|
||||||
|
|
||||||
|
int32_t GBAAudioProcessEvents(struct GBAAudio* audio, int32_t cycles);
|
||||||
|
void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* info);
|
||||||
|
|
||||||
void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value);
|
void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value);
|
||||||
void GBAAudioWriteSOUND1CNT_HI(struct GBAAudio* audio, uint16_t value);
|
void GBAAudioWriteSOUND1CNT_HI(struct GBAAudio* audio, uint16_t value);
|
||||||
void GBAAudioWriteSOUND1CNT_X(struct GBAAudio* audio, uint16_t value);
|
void GBAAudioWriteSOUND1CNT_X(struct GBAAudio* audio, uint16_t value);
|
||||||
|
@ -128,5 +197,6 @@ void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value);
|
||||||
|
|
||||||
void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value);
|
void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value);
|
||||||
void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value);
|
void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value);
|
||||||
|
void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -634,7 +634,7 @@ void GBAMemoryScheduleDMA(struct GBAMemory* memory, int number, struct GBADMA* i
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
//this.cpu.irq.audio.scheduleFIFODma(number, info);
|
GBAAudioScheduleFifoDma(&memory->p->audio, number, info);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
//this.cpu.irq.video.scheduleVCaptureDma(dma, info);
|
//this.cpu.irq.video.scheduleVCaptureDma(dma, info);
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
const uint32_t GBA_ARM7TDMI_FREQUENCY = 0x1000000;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SP_BASE_SYSTEM = 0x03FFFF00,
|
SP_BASE_SYSTEM = 0x03FFFF00,
|
||||||
SP_BASE_IRQ = 0x03FFFFA0,
|
SP_BASE_IRQ = 0x03FFFFA0,
|
||||||
|
@ -95,6 +97,11 @@ static void GBAProcessEvents(struct ARMBoard* board) {
|
||||||
nextEvent = testEvent;
|
nextEvent = testEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testEvent = GBAAudioProcessEvents(&gbaBoard->p->audio, cycles);
|
||||||
|
if (testEvent < nextEvent) {
|
||||||
|
nextEvent = testEvent;
|
||||||
|
}
|
||||||
|
|
||||||
testEvent = GBAMemoryProcessEvents(&gbaBoard->p->memory, cycles);
|
testEvent = GBAMemoryProcessEvents(&gbaBoard->p->memory, cycles);
|
||||||
if (testEvent < nextEvent) {
|
if (testEvent < nextEvent) {
|
||||||
nextEvent = testEvent;
|
nextEvent = testEvent;
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include "gba-video.h"
|
#include "gba-video.h"
|
||||||
#include "gba-audio.h"
|
#include "gba-audio.h"
|
||||||
|
|
||||||
|
const uint32_t GBA_ARM7TDMI_FREQUENCY;
|
||||||
|
|
||||||
enum GBAIRQ {
|
enum GBAIRQ {
|
||||||
IRQ_VBLANK = 0x0,
|
IRQ_VBLANK = 0x0,
|
||||||
IRQ_HBLANK = 0x1,
|
IRQ_HBLANK = 0x1,
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
#include "circle-buffer.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void CircleBufferInit(struct CircleBuffer* buffer, unsigned capacity) {
|
||||||
|
buffer->data = malloc(capacity);
|
||||||
|
buffer->capacity = capacity;
|
||||||
|
buffer->readPtr = buffer->data;
|
||||||
|
buffer->writePtr = (int8_t*) buffer->data + capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CircleBufferDeinit(struct CircleBuffer* buffer) {
|
||||||
|
free(buffer->data);
|
||||||
|
buffer->data = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned CircleBufferSize(const struct CircleBuffer* buffer) {
|
||||||
|
ptrdiff_t size = (int8_t*) buffer->readPtr - (int8_t*) buffer->writePtr;
|
||||||
|
if (size < 0) {
|
||||||
|
return buffer->capacity - size;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value) {
|
||||||
|
uint32_t* data = buffer->writePtr;
|
||||||
|
if ((int8_t*) buffer->writePtr + 1 == buffer->readPtr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((int8_t*) buffer->writePtr == (int8_t*) buffer->data + buffer->capacity - 1 && buffer->readPtr == buffer->data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*data = value;
|
||||||
|
++data;
|
||||||
|
ptrdiff_t size = (int8_t*) data - (int8_t*) buffer->data;
|
||||||
|
if (size < buffer->capacity) {
|
||||||
|
buffer->writePtr = data;
|
||||||
|
} else {
|
||||||
|
buffer->writePtr = buffer->data;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value) {
|
||||||
|
uint32_t* data = buffer->readPtr;
|
||||||
|
if (buffer->readPtr == buffer->writePtr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*value = *data;
|
||||||
|
++data;
|
||||||
|
ptrdiff_t size = (int8_t*) data - (int8_t*) buffer->data;
|
||||||
|
if (size < buffer->capacity) {
|
||||||
|
buffer->readPtr = data;
|
||||||
|
} else {
|
||||||
|
buffer->readPtr = buffer->data;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef CIRCLE_BUFFER_H
|
||||||
|
#define CIRCLE_BUFFER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct CircleBuffer {
|
||||||
|
void* data;
|
||||||
|
unsigned capacity;
|
||||||
|
void* readPtr;
|
||||||
|
void* writePtr;
|
||||||
|
};
|
||||||
|
|
||||||
|
void CircleBufferInit(struct CircleBuffer* buffer, unsigned capacity);
|
||||||
|
void CircleBufferDeinit(struct CircleBuffer* buffer);
|
||||||
|
unsigned CircleBufferSize(const struct CircleBuffer* buffer);
|
||||||
|
int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value);
|
||||||
|
int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue