mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-06-15 21:29:28 +00:00
added Emscripten src files for sdcc
This commit is contained in:
parent
e4e59d6c0d
commit
03a5745bb5
25
emsrc/cc65/Makefile.emcc
Normal file
25
emsrc/cc65/Makefile.emcc
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# Emscripten target (see https://github.com/apiaryio/emscripten-docker)
|
||||||
|
|
||||||
|
DOCKEREMCC=docker run --rm -v $(shell pwd):/src -e USERID=$(shell id -u) -t apiaryio/emcc
|
||||||
|
|
||||||
|
%.js: bin/%.bc
|
||||||
|
$(DOCKEREMCC) emcc -O2 --memory-init-file 0 \
|
||||||
|
-s ASM_JS=1 \
|
||||||
|
-s MODULARIZE=1 \
|
||||||
|
-s EXPORT_NAME=\"'$*'\" \
|
||||||
|
-s 'EXTRA_EXPORTED_RUNTIME_METHODS=["FS"]' \
|
||||||
|
-s FORCE_FILESYSTEM=1 \
|
||||||
|
bin/$*.bc -o $@ $(ARGS_$*)
|
||||||
|
|
||||||
|
bin/%.bc:
|
||||||
|
mkdir -p bin js
|
||||||
|
$(DOCKEREMCC) emmake make $*
|
||||||
|
cp bin/$*.exe bin/$*.bc
|
||||||
|
|
||||||
|
emscripten: include asminc cfg lib/apple2.lib target/apple2
|
||||||
|
cp -rp src Makefile js
|
||||||
|
make -C js cc65.js ca65.js co65.js ld65.js
|
||||||
|
$(DOCKEREMCC) \
|
||||||
|
python /emscripten/tools/file_packager.py fs65.data \
|
||||||
|
--preload include asminc cfg lib/apple2.lib target/apple2 \
|
||||||
|
--separate-metadata --js-output=fs65.js
|
1
emsrc/sdcc/.gitignore
vendored
Normal file
1
emsrc/sdcc/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
*.bz2
|
12
emsrc/sdcc/Dockerfile
Normal file
12
emsrc/sdcc/Dockerfile
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
FROM apiaryio/emcc
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get install -y bison flex bzip2 g++ texinfo sdcc
|
||||||
|
COPY boost* /tmp
|
||||||
|
RUN mkdir /boost
|
||||||
|
WORKDIR /boost
|
||||||
|
RUN tar xvjf /tmp/boost*
|
||||||
|
WORKDIR /boost/boost_1_63_0/
|
||||||
|
RUN emconfigure ./bootstrap.sh
|
||||||
|
RUN emmake ./b2 install --prefix=/emscripten/system --with-graph link=static variant=release threading=single runtime-link=static
|
||||||
|
RUN apt-get install -y zlib1g-dev
|
||||||
|
WORKDIR /src
|
11
emsrc/sdcc/Makefile.emcc
Normal file
11
emsrc/sdcc/Makefile.emcc
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
all: js/sdcc.js js/sdasz80.js js/sdldz80.js
|
||||||
|
|
||||||
|
js/%.js: js/%.bc
|
||||||
|
docker run --rm -v $(shell pwd):/src -e USERID=1000 -t apiaryio/emcc emcc -O2 --memory-init-file 0 \
|
||||||
|
-s ASM_JS=1 \
|
||||||
|
-s MODULARIZE=1 \
|
||||||
|
-s EXPORT_NAME=\"'$*'\" \
|
||||||
|
-s 'EXTRA_EXPORTED_RUNTIME_METHODS=["FS"]' \
|
||||||
|
-s FORCE_FILESYSTEM=1 \
|
||||||
|
$< -o $@ $(ARGS_$*) \
|
||||||
|
|
45
emsrc/sdcc/build.sh
Normal file
45
emsrc/sdcc/build.sh
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
|
||||||
|
rm -fr /tmp/sdcc
|
||||||
|
mkdir /tmp/sdcc
|
||||||
|
git archive --format tar HEAD |tar xv -C /tmp/sdcc
|
||||||
|
cd /tmp/sdcc/sdcc
|
||||||
|
|
||||||
|
echo Configuring SDCC...
|
||||||
|
docker run --rm -v `pwd`:/src -e USERID=$UID -t sehugg/emcc emconfigure ./configure --host x86_64-unknown-linux-gnu --includedir /src \
|
||||||
|
--enable-z80-port \
|
||||||
|
--disable-mcs51-port \
|
||||||
|
--disable-z180-port \
|
||||||
|
--disable-r2k-port \
|
||||||
|
--disable-r3ka-port \
|
||||||
|
--enable-gbz80-port \
|
||||||
|
--disable-tlcs90-port \
|
||||||
|
--disable-ds390-port \
|
||||||
|
--disable-ds400-port \
|
||||||
|
--disable-pic14-port \
|
||||||
|
--disable-pic16-port \
|
||||||
|
--disable-hc08-port \
|
||||||
|
--disable-s08-port \
|
||||||
|
--disable-stm8-port \
|
||||||
|
--disable-ucsim \
|
||||||
|
--disable-device-lib \
|
||||||
|
--disable-packihx \
|
||||||
|
--disable-sdcpp \
|
||||||
|
--disable-sdcdb \
|
||||||
|
--disable-sdbinutils \
|
||||||
|
--disable-non-free \
|
||||||
|
|
||||||
|
echo Configuring sdbinutils...
|
||||||
|
cd support/sdbinutils
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
cd ../..
|
||||||
|
|
||||||
|
echo Making SDCC...
|
||||||
|
docker run --rm -v `pwd`:/src -e USERID=$UID -t sehugg/emcc emmake make
|
||||||
|
|
||||||
|
echo Making JS files...
|
||||||
|
mkdir -p ./js
|
||||||
|
cp /tmp/sdcc/sdcc/bin/sdcc js/sdcc.bc
|
||||||
|
cp /tmp/sdcc/sdcc/bin/sdasz80 js/sdasz80.bc
|
||||||
|
cp /tmp/sdcc/sdcc/bin/sdldz80 js/sdldz80.bc
|
||||||
|
make -f Makefile.emcc
|
1
emsrc/sdcc/mkdocker.sh
Normal file
1
emsrc/sdcc/mkdocker.sh
Normal file
|
@ -0,0 +1 @@
|
||||||
|
docker build -t sehugg/emcc .
|
4
emsrc/votrax/Makefile
Normal file
4
emsrc/votrax/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
main: main.c
|
||||||
|
gcc -o main *.c -lm
|
||||||
|
|
BIN
emsrc/votrax/main
Executable file
BIN
emsrc/votrax/main
Executable file
Binary file not shown.
38
emsrc/votrax/main.c
Normal file
38
emsrc/votrax/main.c
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "votrax.h"
|
||||||
|
|
||||||
|
static double ratio = 1.0;
|
||||||
|
static int votrax_sync_samples = 0;
|
||||||
|
static int votrax_written = FALSE;
|
||||||
|
static int votrax_written_byte = 0x3f;
|
||||||
|
static char VOTRAXSND_busy = 0;
|
||||||
|
|
||||||
|
void VOTRAXSND_PutByte(UBYTE byte)
|
||||||
|
{
|
||||||
|
/* put byte to voice box */
|
||||||
|
votrax_sync_samples = (int)((1.0/ratio)*(double)Votrax_Samples((votrax_written_byte&0x3f), (byte&0x3f), votrax_sync_samples));
|
||||||
|
votrax_written = TRUE;
|
||||||
|
votrax_written_byte = byte;
|
||||||
|
if (!VOTRAXSND_busy) {
|
||||||
|
VOTRAXSND_busy = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
|
struct Votrax_interface interface;
|
||||||
|
SWORD buf[2048];
|
||||||
|
|
||||||
|
if (Votrax_Start(&interface)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
VOTRAXSND_PutByte(0xc);
|
||||||
|
Votrax_Update(0, buf, sizeof(buf)/sizeof(SWORD));
|
||||||
|
write(STDOUT_FILENO, &buf, sizeof(buf));
|
||||||
|
Votrax_Stop();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
12
emsrc/votrax/util.h
Normal file
12
emsrc/votrax/util.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef uint8_t UBYTE;
|
||||||
|
typedef int8_t SBYTE;
|
||||||
|
typedef uint16_t UWORD;
|
||||||
|
typedef int16_t SWORD;
|
||||||
|
|
||||||
|
#define Util_malloc malloc
|
||||||
|
|
||||||
|
#define FALSE 0
|
||||||
|
#define TRUE 1
|
472
emsrc/votrax/votrax.c
Executable file
472
emsrc/votrax/votrax.c
Executable file
|
@ -0,0 +1,472 @@
|
||||||
|
/* License note by perry_m:
|
||||||
|
Permission has been granted by the authors Mike Coates and Tom Haukap
|
||||||
|
to distribute this file under the terms of the GNU GPL license of Atari800.
|
||||||
|
The original version written by Mike Coates is from MAME.
|
||||||
|
This extensively modified version with new samples and mixing written
|
||||||
|
by Tom Haukap is from PinMAME.
|
||||||
|
I have also made modifications to this file for use in Atari800 and
|
||||||
|
allow any modifications to be distributed under any of the licenses
|
||||||
|
of Atari800, MAME and PinMAME. */
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
|
||||||
|
Votrax SC-01 Emulator
|
||||||
|
|
||||||
|
Mike@Dissfulfils.co.uk
|
||||||
|
Tom.Haukap@t-online.de
|
||||||
|
modified for Atari800 by perry_m@fastmail.fm
|
||||||
|
|
||||||
|
**************************************************************************
|
||||||
|
|
||||||
|
Votrax_Start - Start emulation, load samples from Votrax subdirectory
|
||||||
|
Votrax_Stop - End emulation, free memory used for samples
|
||||||
|
Votrax_PutByte - Write data to votrax port
|
||||||
|
Votrax_GetStatus - Return busy status (1 = busy)
|
||||||
|
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifdef PBI_DEBUG
|
||||||
|
#define VERBOSE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if VERBOSE
|
||||||
|
#define LOG(x) printf x
|
||||||
|
#else
|
||||||
|
#define LOG(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "votrax.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
int busy;
|
||||||
|
|
||||||
|
int actPhoneme;
|
||||||
|
int actIntonation;
|
||||||
|
|
||||||
|
struct Votrax_interface *intf;
|
||||||
|
|
||||||
|
SWORD* pActPos;
|
||||||
|
int iRemainingSamples;
|
||||||
|
|
||||||
|
SWORD *lpBuffer;
|
||||||
|
SWORD* pBufferPos;
|
||||||
|
|
||||||
|
int iSamplesInBuffer;
|
||||||
|
int iDelay; /* a count of samples to output '0' in a Delay state */
|
||||||
|
|
||||||
|
} votraxsc01_locals;
|
||||||
|
|
||||||
|
#define INT16 SWORD
|
||||||
|
#define UINT16 UWORD
|
||||||
|
#include "vtxsmpls.inc"
|
||||||
|
|
||||||
|
#if VERBOSE
|
||||||
|
static const char *PhonemeNames[65] =
|
||||||
|
{
|
||||||
|
"EH3","EH2","EH1","PA0","DT" ,"A2" ,"A1" ,"ZH",
|
||||||
|
"AH2","I3" ,"I2" ,"I1" ,"M" ,"N" ,"B" ,"V",
|
||||||
|
"CH" ,"SH" ,"Z" ,"AW1","NG" ,"AH1","OO1","OO",
|
||||||
|
"L" ,"K" ,"J" ,"H" ,"G" ,"F" ,"D" ,"S",
|
||||||
|
"A" ,"AY" ,"Y1" ,"UH3","AH" ,"P" ,"O" ,"I",
|
||||||
|
"U" ,"Y" ,"T" ,"R" ,"E" ,"W" ,"AE" ,"AE1",
|
||||||
|
"AW2","UH2","UH1","UH" ,"O2" ,"O1" ,"IU" ,"U1",
|
||||||
|
"THV","TH" ,"ER" ,"EH" ,"E1" ,"AW" ,"PA1","STOP",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* phoneme types*/
|
||||||
|
#define PT_NS 0
|
||||||
|
#define PT_V 1
|
||||||
|
#define PT_VF 2
|
||||||
|
#define PT_F 3
|
||||||
|
#define PT_N 4
|
||||||
|
#define PT_VS 5
|
||||||
|
#define PT_FS 6
|
||||||
|
|
||||||
|
|
||||||
|
static int sample_rate[4] = {22050, 22050, 22050, 22050};
|
||||||
|
|
||||||
|
/* converts milliseconds to a count of samples */
|
||||||
|
static int time_to_samples(int ms)
|
||||||
|
{
|
||||||
|
return sample_rate[votraxsc01_locals.actIntonation]*ms/1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PrepareVoiceData(int nextPhoneme, int nextIntonation)
|
||||||
|
{
|
||||||
|
int iNextRemainingSamples;
|
||||||
|
SWORD *pNextPos, *lpHelp;
|
||||||
|
|
||||||
|
int iFadeOutSamples;
|
||||||
|
int iFadeOutPos;
|
||||||
|
|
||||||
|
int iFadeInSamples;
|
||||||
|
int iFadeInPos;
|
||||||
|
|
||||||
|
int doMix;
|
||||||
|
/* used only for SecondStart phonemes */
|
||||||
|
int AdditionalSamples;
|
||||||
|
/* dwCount is the length of samples to produce in ms from iLengthms */
|
||||||
|
int dwCount, i;
|
||||||
|
|
||||||
|
SWORD data;
|
||||||
|
|
||||||
|
AdditionalSamples = 0;
|
||||||
|
/* some phonenemes have a SecondStart */
|
||||||
|
if ( PhonemeData[votraxsc01_locals.actPhoneme].iType>=PT_VS && votraxsc01_locals.actPhoneme!=nextPhoneme ) {
|
||||||
|
AdditionalSamples = PhonemeData[votraxsc01_locals.actPhoneme].iSecondStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( PhonemeData[nextPhoneme].iType>=PT_VS ) {
|
||||||
|
/* 'stop phonemes' will stop playing until the next phoneme is sent*/
|
||||||
|
votraxsc01_locals.iRemainingSamples = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* length of samples to produce*/
|
||||||
|
dwCount = time_to_samples(PhonemeData[nextPhoneme].iLengthms);
|
||||||
|
|
||||||
|
votraxsc01_locals.iSamplesInBuffer = dwCount+AdditionalSamples;
|
||||||
|
|
||||||
|
if ( AdditionalSamples )
|
||||||
|
memcpy(votraxsc01_locals.lpBuffer, PhonemeData[votraxsc01_locals.actPhoneme].lpStart[votraxsc01_locals.actIntonation], AdditionalSamples*sizeof(SWORD));
|
||||||
|
|
||||||
|
lpHelp = votraxsc01_locals.lpBuffer + AdditionalSamples;
|
||||||
|
|
||||||
|
iNextRemainingSamples = 0;
|
||||||
|
pNextPos = NULL;
|
||||||
|
|
||||||
|
iFadeOutSamples = 0;
|
||||||
|
iFadeOutPos = 0;
|
||||||
|
|
||||||
|
iFadeInSamples = 0;
|
||||||
|
iFadeInPos = 0;
|
||||||
|
|
||||||
|
doMix = 0;
|
||||||
|
|
||||||
|
/* set up processing*/
|
||||||
|
if ( PhonemeData[votraxsc01_locals.actPhoneme].sameAs!=PhonemeData[nextPhoneme].sameAs ) {
|
||||||
|
/* do something, if they are the same all FadeIn/Out values are 0, */
|
||||||
|
/* the buffer is simply filled with the samples of the new phoneme */
|
||||||
|
|
||||||
|
switch ( PhonemeData[votraxsc01_locals.actPhoneme].iType ) {
|
||||||
|
case PT_NS:
|
||||||
|
/* "fade" out NS:*/
|
||||||
|
iFadeOutSamples = time_to_samples(30);
|
||||||
|
iFadeOutPos = 0;
|
||||||
|
|
||||||
|
/* fade in new phoneme*/
|
||||||
|
iFadeInPos = -time_to_samples(30);
|
||||||
|
iFadeInSamples = time_to_samples(30);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PT_V:
|
||||||
|
case PT_VF:
|
||||||
|
switch ( PhonemeData[nextPhoneme].iType ){
|
||||||
|
case PT_F:
|
||||||
|
case PT_VF:
|
||||||
|
/* V-->F, V-->VF: fade out 30 ms fade in from 30 ms to 60 ms without mixing*/
|
||||||
|
iFadeOutPos = 0;
|
||||||
|
iFadeOutSamples = time_to_samples(30);
|
||||||
|
|
||||||
|
iFadeInPos = -time_to_samples(30);
|
||||||
|
iFadeInSamples = time_to_samples(30);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PT_N:
|
||||||
|
/* V-->N: fade out 40 ms fade from 0 ms to 40 ms without mixing*/
|
||||||
|
iFadeOutPos = 0;
|
||||||
|
iFadeOutSamples = time_to_samples(40);
|
||||||
|
|
||||||
|
iFadeInPos = -time_to_samples(10);
|
||||||
|
iFadeInSamples = time_to_samples(10);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* fade out 20 ms, no fade in from 10 ms to 30 ms*/
|
||||||
|
iFadeOutPos = 0;
|
||||||
|
iFadeOutSamples = time_to_samples(20);
|
||||||
|
|
||||||
|
iFadeInPos = -time_to_samples(0);
|
||||||
|
iFadeInSamples = time_to_samples(20);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PT_N:
|
||||||
|
switch ( PhonemeData[nextPhoneme].iType ){
|
||||||
|
case PT_V:
|
||||||
|
case PT_VF:
|
||||||
|
/* N-->V, N-->VF: fade out 30 ms fade in from 10 ms to 50 ms without mixing*/
|
||||||
|
iFadeOutPos = 0;
|
||||||
|
iFadeOutSamples = time_to_samples(30);
|
||||||
|
|
||||||
|
iFadeInPos = -time_to_samples(10);
|
||||||
|
iFadeInSamples = time_to_samples(40);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PT_VS:
|
||||||
|
case PT_FS:
|
||||||
|
iFadeOutPos = 0;
|
||||||
|
iFadeOutSamples = PhonemeData[votraxsc01_locals.actPhoneme].iLength[votraxsc01_locals.actIntonation] - PhonemeData[votraxsc01_locals.actPhoneme].iSecondStart;
|
||||||
|
votraxsc01_locals.pActPos = PhonemeData[votraxsc01_locals.actPhoneme].lpStart[votraxsc01_locals.actIntonation] + PhonemeData[votraxsc01_locals.actPhoneme].iSecondStart;
|
||||||
|
votraxsc01_locals.iRemainingSamples = iFadeOutSamples;
|
||||||
|
doMix = 1;
|
||||||
|
|
||||||
|
iFadeInPos = -time_to_samples(0);
|
||||||
|
iFadeInSamples = time_to_samples(0);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* fade out 30 ms, no fade in*/
|
||||||
|
iFadeOutPos = 0;
|
||||||
|
iFadeOutSamples = time_to_samples(20);
|
||||||
|
|
||||||
|
iFadeInPos = -time_to_samples(20);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !votraxsc01_locals.iDelay ) {
|
||||||
|
/* this is true if after a stop and a phoneme was sent a second phoneme is sent*/
|
||||||
|
/* during the delay time of the chip. Ignore the first phoneme data*/
|
||||||
|
iFadeOutPos = 0;
|
||||||
|
iFadeOutSamples = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* the next one is of the same type as the previous one; continue to use the samples of the last phoneme*/
|
||||||
|
iNextRemainingSamples = votraxsc01_locals.iRemainingSamples;
|
||||||
|
pNextPos = votraxsc01_locals.pActPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<dwCount; i++)
|
||||||
|
{
|
||||||
|
data = 0x00;
|
||||||
|
|
||||||
|
/* fade out*/
|
||||||
|
if ( iFadeOutPos<iFadeOutSamples )
|
||||||
|
{
|
||||||
|
double dFadeOut = 1.0;
|
||||||
|
|
||||||
|
if ( !doMix )
|
||||||
|
dFadeOut = 1.0-sin((1.0*iFadeOutPos/iFadeOutSamples)*3.1415/2);
|
||||||
|
|
||||||
|
if ( !votraxsc01_locals.iRemainingSamples ) {
|
||||||
|
votraxsc01_locals.iRemainingSamples = PhonemeData[votraxsc01_locals.actPhoneme].iLength[votraxsc01_locals.actIntonation];
|
||||||
|
votraxsc01_locals.pActPos = PhonemeData[votraxsc01_locals.actPhoneme].lpStart[votraxsc01_locals.actIntonation];
|
||||||
|
}
|
||||||
|
|
||||||
|
data = (SWORD) (*votraxsc01_locals.pActPos++ * dFadeOut);
|
||||||
|
|
||||||
|
votraxsc01_locals.iRemainingSamples--;
|
||||||
|
iFadeOutPos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fade in or copy*/
|
||||||
|
if ( iFadeInPos>=0 )
|
||||||
|
{
|
||||||
|
double dFadeIn = 1.0;
|
||||||
|
|
||||||
|
if ( iFadeInPos<iFadeInSamples ) {
|
||||||
|
dFadeIn = sin((1.0*iFadeInPos/iFadeInSamples)*3.1415/2);
|
||||||
|
iFadeInPos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !iNextRemainingSamples ) {
|
||||||
|
iNextRemainingSamples = PhonemeData[nextPhoneme].iLength[nextIntonation];
|
||||||
|
pNextPos = PhonemeData[nextPhoneme].lpStart[nextIntonation];
|
||||||
|
}
|
||||||
|
|
||||||
|
data += (SWORD) (*pNextPos++ * dFadeIn);
|
||||||
|
|
||||||
|
iNextRemainingSamples--;
|
||||||
|
}
|
||||||
|
iFadeInPos++;
|
||||||
|
|
||||||
|
*lpHelp++ = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
votraxsc01_locals.pBufferPos = votraxsc01_locals.lpBuffer;
|
||||||
|
|
||||||
|
votraxsc01_locals.pActPos = pNextPos;
|
||||||
|
votraxsc01_locals.iRemainingSamples = iNextRemainingSamples;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Votrax_PutByte(UBYTE data)
|
||||||
|
{
|
||||||
|
int Phoneme, Intonation;
|
||||||
|
|
||||||
|
Phoneme = data & 0x3F;
|
||||||
|
Intonation = (data >> 6)&0x03;
|
||||||
|
|
||||||
|
#ifdef VERBOSE
|
||||||
|
if (!votraxsc01_locals.intf) {
|
||||||
|
LOG(("Error: votraxsc01_locals.intf not set"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif /* VERBOSE */
|
||||||
|
LOG(("Votrax SC-01: %s at intonation %d\n", PhonemeNames[Phoneme], Intonation));
|
||||||
|
PrepareVoiceData(Phoneme, Intonation);
|
||||||
|
|
||||||
|
if ( votraxsc01_locals.actPhoneme==0x3f )
|
||||||
|
votraxsc01_locals.iDelay = time_to_samples(20);
|
||||||
|
|
||||||
|
if ( !votraxsc01_locals.busy )
|
||||||
|
{
|
||||||
|
votraxsc01_locals.busy = 1;
|
||||||
|
if ( votraxsc01_locals.intf->BusyCallback )
|
||||||
|
(*votraxsc01_locals.intf->BusyCallback)(votraxsc01_locals.busy);
|
||||||
|
}
|
||||||
|
|
||||||
|
votraxsc01_locals.actPhoneme = Phoneme;
|
||||||
|
votraxsc01_locals.actIntonation = Intonation;
|
||||||
|
}
|
||||||
|
|
||||||
|
UBYTE Votrax_GetStatus(void)
|
||||||
|
{
|
||||||
|
return votraxsc01_locals.busy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Votrax_Update(int num, SWORD *buffer, int length)
|
||||||
|
{
|
||||||
|
int samplesToCopy;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* if it is a different intonation */
|
||||||
|
if ( num!=votraxsc01_locals.actIntonation ) {
|
||||||
|
/* clear buffer */
|
||||||
|
memset(buffer, 0x00, length*sizeof(SWORD));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while ( length ) {
|
||||||
|
/* Case 1: if in a delay state, output 0's*/
|
||||||
|
if ( votraxsc01_locals.iDelay ) {
|
||||||
|
samplesToCopy = (length<=votraxsc01_locals.iDelay)?length:votraxsc01_locals.iDelay;
|
||||||
|
|
||||||
|
memset(buffer, 0x00, samplesToCopy*sizeof(SWORD));
|
||||||
|
buffer += samplesToCopy;
|
||||||
|
|
||||||
|
votraxsc01_locals.iDelay -= samplesToCopy;
|
||||||
|
length -= samplesToCopy; /* missing in the original */
|
||||||
|
}
|
||||||
|
/* Case 2: there are no samples left in the buffer */
|
||||||
|
else if ( votraxsc01_locals.iSamplesInBuffer==0 ) {
|
||||||
|
if ( votraxsc01_locals.busy ) {
|
||||||
|
/* busy -> idle */
|
||||||
|
votraxsc01_locals.busy = 0;
|
||||||
|
if ( votraxsc01_locals.intf->BusyCallback )
|
||||||
|
(*votraxsc01_locals.intf->BusyCallback)(votraxsc01_locals.busy);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( votraxsc01_locals.iRemainingSamples==0 ) {
|
||||||
|
if ( PhonemeData[votraxsc01_locals.actPhoneme].iType>=PT_VS ) {
|
||||||
|
votraxsc01_locals.pActPos = PhonemeData[0x3f].lpStart[0];
|
||||||
|
votraxsc01_locals.iRemainingSamples = PhonemeData[0x3f].iLength[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
votraxsc01_locals.pActPos = PhonemeData[votraxsc01_locals.actPhoneme].lpStart[votraxsc01_locals.actIntonation];
|
||||||
|
votraxsc01_locals.iRemainingSamples = PhonemeData[votraxsc01_locals.actPhoneme].iLength[votraxsc01_locals.actIntonation];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if there aren't enough remaining, reduce the amount */
|
||||||
|
samplesToCopy = (length<=votraxsc01_locals.iRemainingSamples)?length:votraxsc01_locals.iRemainingSamples;
|
||||||
|
|
||||||
|
memcpy(buffer, votraxsc01_locals.pActPos, samplesToCopy*sizeof(SWORD));
|
||||||
|
buffer += samplesToCopy;
|
||||||
|
|
||||||
|
votraxsc01_locals.pActPos += samplesToCopy;
|
||||||
|
votraxsc01_locals.iRemainingSamples -= samplesToCopy;
|
||||||
|
|
||||||
|
length -= samplesToCopy;
|
||||||
|
}
|
||||||
|
/* Case 3: output the samples in the buffer */
|
||||||
|
else {
|
||||||
|
samplesToCopy = (length<=votraxsc01_locals.iSamplesInBuffer)?length:votraxsc01_locals.iSamplesInBuffer;
|
||||||
|
|
||||||
|
memcpy(buffer, votraxsc01_locals.pBufferPos, samplesToCopy*sizeof(SWORD));
|
||||||
|
buffer += samplesToCopy;
|
||||||
|
|
||||||
|
votraxsc01_locals.pBufferPos += samplesToCopy;
|
||||||
|
votraxsc01_locals.iSamplesInBuffer -= samplesToCopy;
|
||||||
|
|
||||||
|
length -= samplesToCopy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Votrax_Start(void *sound_interface)
|
||||||
|
{
|
||||||
|
int i, buffer_size;
|
||||||
|
/* clear local variables */
|
||||||
|
memset(&votraxsc01_locals, 0x00, sizeof votraxsc01_locals);
|
||||||
|
|
||||||
|
/* copy interface */
|
||||||
|
votraxsc01_locals.intf = (struct Votrax_interface *)sound_interface;
|
||||||
|
|
||||||
|
votraxsc01_locals.actPhoneme = 0x3f;
|
||||||
|
|
||||||
|
/* find the largest possible size of iSamplesInBuffer */
|
||||||
|
buffer_size = 0;
|
||||||
|
for (i = 0; i <= 0x3f; i++) {
|
||||||
|
int dwCount;
|
||||||
|
int size;
|
||||||
|
int AdditionalSamples;
|
||||||
|
AdditionalSamples = PhonemeData[i].iSecondStart;
|
||||||
|
dwCount = time_to_samples(PhonemeData[i].iLengthms);
|
||||||
|
size = dwCount + AdditionalSamples;
|
||||||
|
if (size > buffer_size) buffer_size = size;
|
||||||
|
}
|
||||||
|
votraxsc01_locals.lpBuffer = (SWORD*) Util_malloc(buffer_size*sizeof(SWORD));
|
||||||
|
PrepareVoiceData(votraxsc01_locals.actPhoneme, votraxsc01_locals.actIntonation);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Votrax_Stop(void)
|
||||||
|
{
|
||||||
|
if ( votraxsc01_locals.lpBuffer ) {
|
||||||
|
free(votraxsc01_locals.lpBuffer);
|
||||||
|
votraxsc01_locals.lpBuffer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Votrax_Samples(int currentP, int nextP, int cursamples)
|
||||||
|
{
|
||||||
|
int AdditionalSamples = 0;
|
||||||
|
int dwCount;
|
||||||
|
int delay = 0;
|
||||||
|
/* some phonemes have a SecondStart */
|
||||||
|
if ( PhonemeData[currentP].iType>=PT_VS && currentP!=nextP) {
|
||||||
|
AdditionalSamples = PhonemeData[currentP].iSecondStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( PhonemeData[nextP].iType>=PT_VS ) {
|
||||||
|
/* 'stop phonemes' will stop playing until the next phoneme is sent*/
|
||||||
|
/* votraxsc01_locals.iRemainingSamples = 0; */
|
||||||
|
return cursamples;
|
||||||
|
}
|
||||||
|
if (currentP == 0x3f) delay = time_to_samples(20);
|
||||||
|
|
||||||
|
/* length of samples to produce*/
|
||||||
|
dwCount = time_to_samples(PhonemeData[nextP].iLengthms);
|
||||||
|
return dwCount + AdditionalSamples + delay ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
vim:ts=4:sw=4:
|
||||||
|
*/
|
23
emsrc/votrax/votrax.h
Executable file
23
emsrc/votrax/votrax.h
Executable file
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef VOTRAX_H_
|
||||||
|
#define VOTRAX_H_
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
typedef void (*Votrax_BusyCallBack)(int);
|
||||||
|
|
||||||
|
struct Votrax_interface
|
||||||
|
{
|
||||||
|
int num; /* total number of chips */
|
||||||
|
Votrax_BusyCallBack BusyCallback; /* callback function when busy signal changes */
|
||||||
|
};
|
||||||
|
|
||||||
|
int Votrax_Start(void *sound_interface);
|
||||||
|
void Votrax_Stop(void);
|
||||||
|
|
||||||
|
void Votrax_PutByte(UBYTE data);
|
||||||
|
UBYTE Votrax_GetStatus(void);
|
||||||
|
|
||||||
|
void Votrax_Update(int num, SWORD *buffer, int length);
|
||||||
|
int Votrax_Samples(int currentP, int nextP, int cursamples);
|
||||||
|
|
||||||
|
#endif /* VOTRAX_H_ */
|
6917
emsrc/votrax/vtxsmpls.inc
Executable file
6917
emsrc/votrax/vtxsmpls.inc
Executable file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user