From c1c59978b040d2a33ddda6609511fae3d96b8940 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Tue, 20 Nov 2018 17:37:14 +0100 Subject: [PATCH 01/62] first Amiga Version. fixed endianess in wave-header --- AF_readme | 33 +++++++++++++++++++++++++++++++++ Makefile | 2 +- Makefile.amiga | 27 +++++++++++++++++++++++++++ src/endian.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/endian.h | 8 ++++++++ src/main.c | 20 ++++++++++++-------- 6 files changed, 126 insertions(+), 9 deletions(-) create mode 100644 AF_readme create mode 100644 Makefile.amiga create mode 100644 src/endian.c create mode 100644 src/endian.h diff --git a/AF_readme b/AF_readme new file mode 100644 index 0000000..1a71cec --- /dev/null +++ b/AF_readme @@ -0,0 +1,33 @@ +18.11.2018 +---------- +sudo apt-get install libsdl1.2-dev +make + +sdl-config ist ein Programm, das die Parameter ausgibt, die dann im Makefile benutzt werden. + +sdl-config --cflags +-I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT + +sdl-config --libs +-L/usr/lib/x86_64-linux-gnu -lSDL + +./sam -wav sam.wav My name is sam. +play sam.wav + +oder direkt + +./sam My name is sam. + + +Amiga +----- +Im Makefile erst mal das SDL-Zeug auskommentieren. -noixemul bei Compiler- und Linker-Flags! (newlib hat falsches argc !???) +make CC=~/opt/m68k-amigaos_24Oct18/bin/m68k-amigaos-gcc + +Das erzeugte Wav-File hat Endian-Fehler. Alles wird direkt geschrieben, ohne auf Endianes zu achten! + +20.11.2018 +---------- +* eigenes Makefile fuer Amiga (wegen -noixemul un anderer SDL-Einstellungen) +* make CC=~/opt/m68k-amigaos_14Nov18/bin/m68k-amigaos-gcc -f Makefile.amiga + diff --git a/Makefile b/Makefile index 5a62202..8a7c5f4 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -OBJS = reciter.o sam.o render.o main.o debug.o +OBJS = reciter.o sam.o render.o main.o debug.o endian.o CC = gcc diff --git a/Makefile.amiga b/Makefile.amiga new file mode 100644 index 0000000..138fc32 --- /dev/null +++ b/Makefile.amiga @@ -0,0 +1,27 @@ +OBJS = reciter.o sam.o render.o main.o debug.o endian.o + +CC = gcc + +# libsdl present +#CFLAGS = -Wall -Os -DUSESDL `sdl-config --cflags` +#LFLAGS = `sdl-config --libs` + +# no libsdl present +CFLAGS = -DPLATFORM_IS_BIG_ENDIAN -Wall -Os -noixemul -g +LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace + +sam: $(OBJS) + $(CC) -o sam $(OBJS) $(LFLAGS) + +%.o: src/%.c + $(CC) $(CFLAGS) -c $< + +package: + tar -cvzf sam.tar.gz README.md Makefile sing src/ + +clean: + rm -f *.o + +archive: + rm -f sam_windows.zip + cd ..; zip SAM/sam_windows.zip SAM/sam.exe SAM/SDL.dll SAM/README.md SAM/demos/*.bat diff --git a/src/endian.c b/src/endian.c new file mode 100644 index 0000000..24a8ecc --- /dev/null +++ b/src/endian.c @@ -0,0 +1,45 @@ + + +unsigned short swaps( unsigned short val) +{ + return ((val & 0xff) << 8) | ((val & 0xff00) >> 8); +} + +/* host to little endian */ + +#if PLATFORM_IS_BIG_ENDIAN + +unsigned short htoles( unsigned short val) +{ + /* need to swap bytes on a big endian platform */ + return swaps( val); +} +unsigned int htolew( unsigned int val) +{ + + /* need to swap bytes and words on a big endian platform */ + int RetVal; + ((unsigned char *)&RetVal)[0]=((unsigned char *)&val)[3]; + ((unsigned char *)&RetVal)[1]=((unsigned char *)&val)[2]; + ((unsigned char *)&RetVal)[2]=((unsigned char *)&val)[1]; + ((unsigned char *)&RetVal)[3]=((unsigned char *)&val)[0]; + + return RetVal; +} + + +#else + +unsigned short htoles( unsigned short val) +{ + /* no-op on a little endian platform */ + return val; +} + +unsigned int htolew( unsigned int val) +{ + /* no-op on a little endian platform */ + return val; +} + +#endif diff --git a/src/endian.h b/src/endian.h new file mode 100644 index 0000000..a38c0f0 --- /dev/null +++ b/src/endian.h @@ -0,0 +1,8 @@ + +/* + * AF, 20.Nov.2018 + * convert host to little endian short + * found at https://stackoverflow.com/questions/1873352/how-do-i-convert-a-value-from-host-byte-order-to-little-endian + */ +unsigned short htoles( unsigned short val); /* hotToLittleEndian Short */ +unsigned int htolew( unsigned int val); /* hotToLittleEndian Word */ diff --git a/src/main.c b/src/main.c index 966bc9f..06fe18a 100644 --- a/src/main.c +++ b/src/main.c @@ -12,35 +12,39 @@ #include #endif +#include "endian.h" // AF, Endian + void WriteWav(char* filename, char* buffer, int bufferlength) { FILE *file = fopen(filename, "wb"); + unsigned int le_bufferlength; // AF, Endian if (file == NULL) return; //RIFF header fwrite("RIFF", 4, 1,file); - unsigned int filesize=bufferlength + 12 + 16 + 8 - 8; + unsigned int filesize=htolew(bufferlength + 12 + 16 + 8 - 8); // AF, Endian fwrite(&filesize, 4, 1, file); fwrite("WAVE", 4, 1, file); //format chunk fwrite("fmt ", 4, 1, file); - unsigned int fmtlength = 16; + unsigned int fmtlength = htolew(16); // AF, Endian fwrite(&fmtlength, 4, 1, file); - unsigned short int format=1; //PCM + unsigned short int format=htoles(1); //PCM // AF, Endian fwrite(&format, 2, 1, file); - unsigned short int channels=1; + unsigned short int channels=htoles(1); // AF, Endian fwrite(&channels, 2, 1, file); - unsigned int samplerate = 22050; + unsigned int samplerate = htolew(22050); // AF, Endian fwrite(&samplerate, 4, 1, file); fwrite(&samplerate, 4, 1, file); // bytes/second - unsigned short int blockalign = 1; + unsigned short int blockalign = htoles(1); // AF, Endian fwrite(&blockalign, 2, 1, file); - unsigned short int bitspersample=8; + unsigned short int bitspersample=htoles(8); // AF, Endian fwrite(&bitspersample, 2, 1, file); //data chunk fwrite("data", 4, 1, file); - fwrite(&bufferlength, 4, 1, file); + le_bufferlength=htolew(bufferlength); // AF, Endian + fwrite(&le_bufferlength, 4, 1, file); fwrite(buffer, bufferlength, 1, file); fclose(file); From 3d6717b2d1f8ba4c57d70d64cd56fc0fdd387e98 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Tue, 20 Nov 2018 19:23:55 +0100 Subject: [PATCH 02/62] Program works also with SDL, i.e. direct sound otput --- AF_readme | 10 ++++++++++ Makefile.amiga | 8 ++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/AF_readme b/AF_readme index 1a71cec..3b955e3 100644 --- a/AF_readme +++ b/AF_readme @@ -31,3 +31,13 @@ Das erzeugte Wav-File hat Endian-Fehler. Alles wird direkt geschrieben, ohne auf * eigenes Makefile fuer Amiga (wegen -noixemul un anderer SDL-Einstellungen) * make CC=~/opt/m68k-amigaos_14Nov18/bin/m68k-amigaos-gcc -f Makefile.amiga +Fixed WriteWav() in main.c (changed endianess where necessary) +-> Amiga Executable works! + +enabled SDL. -> Funktioniert! +ABER: sam wird viel groesser. + +ohne SDL (gestripped) 44 kBytes +mit SDL (gestripped) 256 kBytes ! + +Der linkt alles moegliche ran, z.B. sind Youstick-Meldungen im Executable... diff --git a/Makefile.amiga b/Makefile.amiga index 138fc32..790cfed 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -3,12 +3,12 @@ OBJS = reciter.o sam.o render.o main.o debug.o endian.o CC = gcc # libsdl present -#CFLAGS = -Wall -Os -DUSESDL `sdl-config --cflags` -#LFLAGS = `sdl-config --libs` +CFLAGS = -DPLATFORM_IS_BIG_ENDIAN -Wall -Os -noixemul -g -DUSESDL -I/home/osboxes/opt/m68k-amigaos_14Nov18/include/SDL #`sdl-config --cflags` +LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace -lSDL -ldebug #`sdl-config --libs` # no libsdl present -CFLAGS = -DPLATFORM_IS_BIG_ENDIAN -Wall -Os -noixemul -g -LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace +#CFLAGS = -DPLATFORM_IS_BIG_ENDIAN -Wall -Os -noixemul -g +#LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace sam: $(OBJS) $(CC) -o sam $(OBJS) $(LFLAGS) From dc4931bfb0bef8378da0c2822b4fd5ded4715212 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Thu, 22 Nov 2018 13:29:13 +0100 Subject: [PATCH 03/62] use an SDL-to-portaudio wrapper instead of libsdl. The executable is 200 kBytes smaller and supports AHI.device and plain audio.device --- Makefile.amiga | 20 +- src/amiga/portaudio/portaudio.c | 134 +++ src/amiga/portaudio/portaudio_ahidev.c | 947 +++++++++++++++++++ src/amiga/portaudio/portaudio_ahidev.h | 56 ++ src/amiga/portaudio/portaudio_audev.c | 1190 ++++++++++++++++++++++++ src/amiga/portaudio/portaudio_audev.h | 54 ++ src/amiga/portaudio/subtask_support.c | 118 +++ src/amiga/portaudio/subtask_support.h | 47 + src/amiga/portaudio18.h | 466 ++++++++++ src/amiga/sdlwrapper.c | 142 +++ src/main.c | 4 + 11 files changed, 3172 insertions(+), 6 deletions(-) create mode 100644 src/amiga/portaudio/portaudio.c create mode 100644 src/amiga/portaudio/portaudio_ahidev.c create mode 100644 src/amiga/portaudio/portaudio_ahidev.h create mode 100644 src/amiga/portaudio/portaudio_audev.c create mode 100644 src/amiga/portaudio/portaudio_audev.h create mode 100644 src/amiga/portaudio/subtask_support.c create mode 100644 src/amiga/portaudio/subtask_support.h create mode 100644 src/amiga/portaudio18.h create mode 100644 src/amiga/sdlwrapper.c diff --git a/Makefile.amiga b/Makefile.amiga index 790cfed..f5e01b2 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -1,15 +1,23 @@ -OBJS = reciter.o sam.o render.o main.o debug.o endian.o +OBJS = reciter.o sam.o render.o main.o debug.o endian.o sdlwrapper.o portaudio_ahidev.o portaudio_audev.o portaudio.o subtask_support.o -CC = gcc +CC = ~/opt/m68k-amigaos_14Nov18/bin/m68k-amigaos-gcc #gcc -# libsdl present -CFLAGS = -DPLATFORM_IS_BIG_ENDIAN -Wall -Os -noixemul -g -DUSESDL -I/home/osboxes/opt/m68k-amigaos_14Nov18/include/SDL #`sdl-config --cflags` -LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace -lSDL -ldebug #`sdl-config --libs` + +CFLAGS = -DPLATFORM_IS_BIG_ENDIAN -DSTATIC_FUNC= -Iamiga/ -Iamiga/portaudio/ -I. -Wall -Os -noixemul -g -DUSESDL -I/home/osboxes/opt/m68k-amigaos_14Nov18/include/SDL #`sdl-config --cflags` +LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace -ldebug #-lSDL #`sdl-config --libs` # no libsdl present -#CFLAGS = -DPLATFORM_IS_BIG_ENDIAN -Wall -Os -noixemul -g +#CFLAGS = -DPLATFORM_IS_BIG_ENDIAN -DSTATIC_FUNC= -Iamiga/ -Iamiga/portaudio/ -I. -Wall -Os -noixemul -g #LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace +vpath sdlwrapper.c src/amiga/ +vpath portaudio.c src/amiga/portaudio/ +vpath portaudio_ahidev.c src/amiga/portaudio/ +vpath portaudio_audev.c src/amiga/portaudio/ +vpath portaudio.c src/amiga/portaudio/ +vpath subtask_support.c src/amiga/portaudio/ + + sam: $(OBJS) $(CC) -o sam $(OBJS) $(LFLAGS) diff --git a/src/amiga/portaudio/portaudio.c b/src/amiga/portaudio/portaudio.c new file mode 100644 index 0000000..91d5ee4 --- /dev/null +++ b/src/amiga/portaudio/portaudio.c @@ -0,0 +1,134 @@ +/*************************************************************************** + * Copyright (C) 2017 by Alexander Fritsch * + * email: selco@t-online.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write see: * + * . * + ***************************************************************************/ + +#include "portaudio_audev.h" +#include "portaudio_ahidev.h" +#include + + +///////////////////////////////////////////////////////////////////////////////////////// +// Functions are called via function pointers +// pointers point to audio.device or ahi.device functions + +// defaults to amiga audio.device +PaError (*Pa_StartStream_FctPtr)( PortAudioStream *stream ) = Pa_StartStream_audev; +PaError (*Pa_AbortStream_FctPtr)( PortAudioStream *stream ) = Pa_AbortStream_audev; +PaError (*Pa_StreamActive_FctPtr)( PortAudioStream *stream ) =Pa_StreamActive_audev; +PaError (*Pa_OpenDefaultStream_FctPtr)( PortAudioStream** stream, + int numInputChannels, + int numOutputChannels, + PaSampleFormat sampleFormat, + double sampleRate, + unsigned long framesPerBuffer, + unsigned long numberOfBuffers, + PortAudioCallback *callback, + void *userData ) = Pa_OpenDefaultStream_audev; +PaError (*Pa_CloseStream_FctPtr)( PortAudioStream *stream ) =Pa_CloseStream_audev; +PaError (*Pa_Initialize_FctPtr)( void ) =Pa_Initialize_audev; +PaError (*Pa_GetSampleSize_FctPtr)( PaSampleFormat format ) =Pa_GetSampleSize_audev; +void (*Abort_Pa_CloseStream_FctPtr) (void) =Abort_Pa_CloseStream_audev; + + +void set_paula_devide(void) +{ + Pa_StartStream_FctPtr = Pa_StartStream_audev; + Pa_AbortStream_FctPtr = Pa_AbortStream_audev; + Pa_StreamActive_FctPtr = Pa_StreamActive_audev; + Pa_OpenDefaultStream_FctPtr= Pa_OpenDefaultStream_audev; + Pa_CloseStream_FctPtr = Pa_CloseStream_audev; + Pa_Initialize_FctPtr = Pa_Initialize_audev; + Pa_GetSampleSize_FctPtr = Pa_GetSampleSize_audev; + Abort_Pa_CloseStream_FctPtr = Abort_Pa_CloseStream_audev; + + //printf("Setting portaudio to to audio.device\n"); +} + +void set_ahi_devide(unsigned int unit) +{ + Pa_StartStream_FctPtr = Pa_StartStream_ahidev; + Pa_AbortStream_FctPtr = Pa_AbortStream_ahidev; + Pa_StreamActive_FctPtr = Pa_StreamActive_ahidev; + Pa_OpenDefaultStream_FctPtr= Pa_OpenDefaultStream_ahidev; + Pa_CloseStream_FctPtr = Pa_CloseStream_ahidev; + Pa_Initialize_FctPtr = Pa_Initialize_ahidev; + Pa_GetSampleSize_FctPtr = Pa_GetSampleSize_ahidev; + Abort_Pa_CloseStream_FctPtr = Abort_Pa_CloseStream_ahidev; + g_AHI_Unit=unit; + //printf("Setting portaudio to to ahi.device, Unit %d\n",unit); +} + + +PaError Pa_StartStream( PortAudioStream *stream ) +{ + return (*Pa_StartStream_FctPtr)( stream); +} + + +PaError Pa_AbortStream( PortAudioStream *stream ) +{ + return (*Pa_AbortStream_FctPtr)( stream); +} + +PaError Pa_StreamActive( PortAudioStream *stream ) +{ + return (*Pa_StreamActive_FctPtr)( stream ); +} + +PaError Pa_OpenDefaultStream( PortAudioStream** stream, + int numInputChannels, + int numOutputChannels, + PaSampleFormat sampleFormat, + double sampleRate, + unsigned long framesPerBuffer, + unsigned long numberOfBuffers, + PortAudioCallback *callback, + void *userData ) +{ + return (*Pa_OpenDefaultStream_FctPtr)( stream, + numInputChannels, + numOutputChannels, + sampleFormat, + sampleRate, + framesPerBuffer, + numberOfBuffers, + callback, + userData ); + +} + +PaError Pa_CloseStream( PortAudioStream *stream ) +{ + return (*Pa_CloseStream_FctPtr)( stream ); +} + +PaError Pa_Initialize( void ) +{ + return (*Pa_Initialize_FctPtr)(); +} + +PaError Pa_GetSampleSize( PaSampleFormat format ) +{ + return (*Pa_GetSampleSize_FctPtr)( format ); +} + +void __attribute__((no_instrument_function)) Abort_Pa_CloseStream (void) +{ + (*Abort_Pa_CloseStream_FctPtr)(); +} + diff --git a/src/amiga/portaudio/portaudio_ahidev.c b/src/amiga/portaudio/portaudio_ahidev.c new file mode 100644 index 0000000..b62034f --- /dev/null +++ b/src/amiga/portaudio/portaudio_ahidev.c @@ -0,0 +1,947 @@ +/*************************************************************************** + * Copyright (C) 2017 by Alexander Fritsch * + * email: selco@t-online.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write see: * + * . * + ***************************************************************************/ + +/* Amiga ahi.device part */ + +#include "../portaudio18.h" +#include +#include + +/* AF, Gwd, 28.Nov 2017 */ + +#include +#include "subtask_support.h" + +#include + +#include +#include + +#include /* for CreatePort */ + +#include +#include + +#include +#include // sleep + +#include "portaudio_ahidev.h" + +#ifdef mc68060 +#define __CPU__ "mc68060" +#elif defined mc68040 +#define __CPU__ "mc68040" +#elif defined mc68030 +#define __CPU__ "mc68030" +#elif defined mc68020 +#define __CPU__ "mc68020" +#elif defined mc68000 +#define __CPU__ "mc68000" +#else +#define __CPU__ "???????" +#endif + +#ifdef __HAVE_68881__ +#define __FPU__ "mc68881" +#else +#define __FPU__ "" +#endif + +/*extern "C"*/ LONG KPrintF(STRPTR format, ...); + +extern unsigned int global_bufsize_factor; // AF Test einstellbare Audio Buffergroesse n mal 512 Bytes +extern unsigned int global_benchmark_flag; // AF Einschalten der Ausgabe der durchschnittlichen Zeit fuer die portaudio-Callbackfunktion +extern char *global_ProgramName; // AF argv[0] + + +FILE *File_ahi=NULL; // testweise samples in File schreiben + +unsigned int g_AHI_Unit=0; // can be changed via command line (speak.cpp) + +//UBYTE chans[] ={1,2,4,8}; /* get any of the four channels RKRM Audio-example */ +UBYTE chans_ahi[] ={3,5,10,12}; /* get a pair of stereo channels, RKRM Devices */ +//UBYTE chans[] ={1,8}; /* test, nur rechts */ +//UBYTE chans[] ={2,4}; /* test, nur links */ + +typedef struct +{ + int StreamActive; + unsigned int AF_StreamID; // just a number to see which stream is referred to + + struct SubTask *st; + struct SignalSemaphore sema; /* data item protection */ + + int numInputChannels; + int numOutputChannels; // 1 for mono, 2 for stereo + PaSampleFormat sampleFormat; + ULONG AhiSampleType; + double sampleRate; + unsigned long framesPerBuffer; // a frames is one complete sample from each channel + unsigned long numberOfBuffers; // suggestion for (double) bufering + PortAudioCallback *callback; + void *userData; + struct AHIRequest *AHIio; // audio I/O block + struct AHIRequest *AHIio2; // audio I/O block + struct AHIRequest *AIOptrStartStop;// for CMD_START and CMD_STOP + struct MsgPort *AHImp; + struct MsgPort *portStartStop; + ULONG device; // Audio device handle + BYTE *ChipMemBuf1; // Amiga-Audiobuffer + BYTE *ChipMemBuf2; // Amiga-Audiobuffer + SHORT *FastMemBuf1; // Espeak-AudioBuffer used in Callback + SHORT *FastMemBuf2; // Espeak-AudioBuffer used in Callback + unsigned int LeftChannel; // left Audiochannel we got allocated in OpenDevice() or 0 + unsigned int RightChannel; // right Audiochannel we got allocated in OpenDevice() or 0 + + +}PortAudioStreamStruct; + +//static UWORD Convert16SSamples(SHORT *Source16S, BYTE *Dest8S, ULONG SampleCount); /* reads 16Bit Signed Samples from Source and writes 8Bit Signed Samples to Dest. DestLen Samples will be read */ + +STATIC_FUNC ULONG getAHISampleType(PaSampleFormat format ); + + +// Loeschen! +struct MsgPort *AHImp = NULL; + +extern struct Device* TimerBase; // nur zum Benchmarking +static struct IORequest timereq; // nur zum Benchmarking + +VOID /*__asm __saveds*/ EspeakAudioTask_AHI(VOID) +{ + // KPrintF("%s() called\n",__FUNCTION__); + + + + struct Task *me = FindTask(NULL); + struct SubTask *st; + struct SubTaskMsg *stm; + + //KPrintF("Begin EspeakAudioTask_AHI\n"); + + + /* + ** Wait for our startup message from the SpawnSubTask() function. + */ + + WaitPort(&((struct Process *)me)->pr_MsgPort); + stm = (struct SubTaskMsg *)GetMsg(&((struct Process *)me)->pr_MsgPort); + st = (struct SubTask *)stm->stm_Parameter; + + + + + { + // struct Data *data = (struct Data *)st->st_Data; + BOOL running = TRUE; + BOOL worktodo = FALSE; + + PortAudioStreamStruct *PortAudioStreamData=(PortAudioStreamStruct*)(st->st_Data); + int Error=paInternalError; + + if(0==OpenDevice((CONST_STRPTR)TIMERNAME, UNIT_MICROHZ, &timereq, 0)) // nur zum test + { + TimerBase = timereq.io_Device; // nur zum test + + /* Make four Reply-Ports */ + PortAudioStreamData->AHImp=CreatePort(0,0); + if(PortAudioStreamData->AHImp) + { + + PortAudioStreamData->portStartStop=CreatePort(0,0); + if(PortAudioStreamData->portStartStop) + { + //KPrintF("if(PortAudioStreamData->portStartStop)\n"); + + /* Now Open AHI Device */ + // KPrintF("Attempting to open Audio.device\n"); + /* set up audio I/O block for channel */ + /* allocation and Open the audio.device */ + PortAudioStreamData->AHIio->ahir_Std.io_Message.mn_ReplyPort=PortAudioStreamData->AHImp; + PortAudioStreamData->AHIio->ahir_Std.io_Message.mn_Length=sizeof(struct AHIRequest); + PortAudioStreamData->AHIio->ahir_Version = 4; + + + // ((struct IORequest*)(PortAudioStreamData->AHIio))->io_Message.mn_ReplyPort=PortAudioStreamData->AHImp; + // PortAudioStreamData->AHIio=(struct AHIRequest *)CreateIORequest(PortAudioStreamData->AHImp,sizeof(struct AHIRequest)); + // PortAudioStreamData->AHIio->ahir_Version = 4; + + //KPrintF("Vor Open AHI-Device()\n"); + PortAudioStreamData->device=OpenDevice((CONST_STRPTR)AHINAME,g_AHI_Unit,(struct IORequest*)PortAudioStreamData->AHIio,0L); + //KPrintF("Nach Open AHI-Device()\n"); + + if(PortAudioStreamData->device==0) + { + /* + // PortAudioStreamData->AHIio->ahir_Std.io_Message.mn_Node.ln_Pri = pri; + // PortAudioStreamData->AHIio->ahir_Std.io_Data = ; + // PortAudioStreamData->AHIio->ahir_Std.io_Length = ; + PortAudioStreamData->AHIio->ahir_Std.io_Offset = 0; + PortAudioStreamData->AHIio->ahir_Frequency = (ULONG) PortAudioStreamData->sampleRate; + // PortAudioStreamData->AHIio->ahir_Type = TYPE; // AHIST_M16S + PortAudioStreamData->AHIio->ahir_Volume = 0x10000; // Full volume + PortAudioStreamData->AHIio->ahir_Position = 0x8000; // Centered + // PortAudioStreamData->AHIio->ahir_Link = ; + */ + // Make a copy of the request (for double buffer + *(PortAudioStreamData->AHIio2)=*(PortAudioStreamData->AHIio); + + PortAudioStreamData->AHIio->ahir_Std.io_Command=CMD_WRITE; + + + + /* Set Up Audio IO Blocks for Sample Playing */ + + + + // Data... + + if ((st->st_Port = CreateMsgPort())) + { + /* + ** Reply startup message, everything ok. + ** Note that if the initialization fails, the code falls + ** through and replies the startup message with a stm_Result + ** of 0 after a Forbid(). This tells SpawnSubTask() that the + ** sub task failed to run. + */ + + /* variables are declared here because they should be initialized to Zero */ + /* in the for loop they would become initialized at the beginning of every turn - which is wrong */ + ULONG CallbackTime=0; /* For Callback benchmarking */ + ULONG CallBackCount=0; + ULONG CallBackMaxTime=0; + + ULONG BufferLength=PortAudioStreamData->framesPerBuffer * Pa_GetSampleSize_ahidev(PortAudioStreamData->sampleFormat); + + + + // struct IOAudio *Aptr=NULL; /* for double buffer switching */ + // struct MsgPort *port=NULL; /* for double buffer switching */ + // struct MsgPort *port_2=NULL; /* for double buffer switching for the second audio channel (we do 2-channel(MONO) playback)*/ + // BYTE *ChipMemBuf=NULL; /* Amiga-Audiobuffer for double buffer switching */ + // SHORT *FastMemBuf=NULL; /* Espeak-AudioBuffer used in Callback for double buffer switching */ + + struct AHIRequest *AHIio =PortAudioStreamData->AHIio; + struct AHIRequest *AHIio2=PortAudioStreamData->AHIio2; + struct AHIRequest *tmpReq=NULL; + struct AHIRequest *link = NULL; + WORD *tmpBuf=NULL; + WORD *p1=PortAudioStreamData->FastMemBuf1; + WORD *p2=PortAudioStreamData->FastMemBuf2; + + + stm->stm_Result = TRUE; + ReplyMsg((struct Message *)stm); + // Ok, all opened successfully + // KPrintF("Opened Audio.device successfully\n"); + + /* + ** after the sub task is up and running, we go into + ** a loop and process the messages from the main task. + */ + for (;;) + { + while ((stm = (struct SubTaskMsg *)GetMsg(st->st_Port))) + { + switch (stm->stm_Command) + { + case STC_SHUTDOWN: + /* + ** This is the shutdown message from KillSubTask(). + */ + // printf("Task STC_SHUTDOWN\n"); + //KPrintF("STC_SHUTDOWN\n"); + running = FALSE; + break; + + case STC_START: + /* + ** we received a start message with a fractal description. + ** clear the rastport and the line update array and start + ** rendering. + */ + // printf("Task STC_START\n"); + //KPrintF("STC_START\n"); + worktodo = TRUE; + link=NULL; // Start with link=NULL + break; + + case STC_STOP: + /* this message is not used in this example */ + // printf("Task STC_STOP\n"); + //KPrintF("STC_STOP\n"); + worktodo = FALSE; + break; + } + + /* + ** If we received a shutdown message, we do not reply it + ** immediately. First, we need to free our resources. + */ + if (!running) break; + + ReplyMsg((struct Message *)stm); + } + + if (!running) break; + + if (worktodo) + { + //#ifdef ALEXANDER + int LastBuf; + ULONG signals; + + /* if there is work to do,... + */ + // Fill buffer + if( 0!=PortAudioStreamData->callback(NULL,p1,PortAudioStreamData->framesPerBuffer,0,NULL)) /* Last Buffer */ + { + PortAudioStreamData->StreamActive=0; + worktodo=FALSE; + LastBuf=TRUE; + } + else + { + // more buffers to come + LastBuf=FALSE; + } + + // Play buffer + AHIio->ahir_Std.io_Message.mn_Node.ln_Pri = 75; /* speech, prio of narrator.device */ + AHIio->ahir_Std.io_Command = CMD_WRITE; + AHIio->ahir_Std.io_Data = p1; + AHIio->ahir_Std.io_Length = BufferLength; + AHIio->ahir_Std.io_Offset = 0; + AHIio->ahir_Frequency = (ULONG)PortAudioStreamData->sampleRate; + AHIio->ahir_Type = PortAudioStreamData->AhiSampleType; + AHIio->ahir_Volume = 0x10000; // Full volume + AHIio->ahir_Position = 0x8000; // Centered + AHIio->ahir_Link = link; + SendIO((struct IORequest *) AHIio); + + if(link) { + + // Wait until the last buffer is finished (== the new buffer is started) + signals=Wait(SIGBREAKF_CTRL_C | (1L << PortAudioStreamData->AHImp->mp_SigBit)); +#ifdef ALEXANDER + // Check for Ctrl-C and abort if pressed + if(signals & SIGBREAKF_CTRL_C) { + SetIoErr(ERROR_BREAK); + break; + } +#endif +// Remove the reply and abort on error + if(WaitIO((struct IORequest *) link)) { + SetIoErr(ERROR_WRITE_PROTECTED); + // break; + worktodo=FALSE; // AF + + } + } + + // Check for end-of-sound, and wait until it is finished before aborting + if(LastBuf) { + WaitIO((struct IORequest *) AHIio); + // break; + worktodo=FALSE; // AF + } + + link = AHIio; + + // Swap buffer and request pointers, and restart + tmpBuf = p1; + p1 = p2; + p2 = tmpBuf; + + tmpReq = AHIio; + AHIio = AHIio2; + AHIio2 = tmpReq; + //#endif + } + else + { + /* We have nothing to do, just sit quietly and wait for something to happen */ + //KPrintF("Nothing to do\n"); + WaitPort(st->st_Port); + } + } + + //KPrintF("stm=%lx\n",stm); + Error=paNoError; + // return;// Error; + + if(global_benchmark_flag) /* if Benchmarking was done */ + { + printf("%s, Average BufferTime %lums, Max Buffertime %lums, (Buffer is %lums), Compiled for " __CPU__ " " __FPU__ "\n",global_ProgramName,CallbackTime/CallBackCount,CallBackMaxTime,(ULONG)(global_bufsize_factor*512*1000/PortAudioStreamData->sampleRate)); + } + //KPrintF("Calling DeletePort st->st_Port\n"); + DeletePort(st->st_Port); + st->st_Port=NULL; + } + else // st->st_Port = CreateMsgPort() failed + { + printf(" Subtask CreateMsgPort() failed\n"); + Error=paInsufficientMemory; + } + //KPrintF("Calling CloseDevice\n"); + CloseDevice((struct IORequest*)PortAudioStreamData->AHIio); + PortAudioStreamData->device=1; + } + else + { + printf(" Could not open " AHINAME " version 4\n"); + Error=paDeviceUnavailable; + } + + //KPrintF("Calling DeletePortStartStop\n"); + DeletePort(PortAudioStreamData->portStartStop); + PortAudioStreamData->portStartStop=NULL; + } + else + { + printf(" Could not create portStartStop\n"); + Error=paInsufficientMemory; + } + //KPrintF("Calling DeleteAHImp\n"); + DeletePort(PortAudioStreamData->AHImp); + PortAudioStreamData->AHImp=NULL; + + } + else + { + printf(" Could not create AHImp\n"); + Error=paInsufficientMemory; + } + CloseDevice(&timereq); + } + else + { + printf(" Could not open " TIMERNAME"\n"); + } + + // Error uebergeben? + //KPrintF("Calling ExitSubtask. stm=%lx\n",(ULONG)stm); + ExitSubTask(st,stm); + } +} + + +/* ##################################################################################################### */ + +PortAudioStream *GlobalPaStreamPtr_ahi=NULL; /* used for atexit(). Functions there have void parameter -> global Pointer needed */ + + +/* + Pa_StartStream() and Pa_StopStream() begin and terminate audio processing. + Pa_StopStream() waits until all pending audio buffers have been played. + Pa_AbortStream() stops playing immediately without waiting for pending + buffers to complete. + */ + +PaError Pa_StartStream_ahidev( PortAudioStream *stream ) +{ + int Error; + // KPrintF("%s() called\n",__FUNCTION__); + //KPrintF("Zeile %ld\n",__LINE__); + if(stream) + { + // printf(" %s called for Stream %u\n",__FUNCTION__,((PortAudioStreamStruct*)stream)->AF_StreamID); + ((PortAudioStreamStruct*)stream)->StreamActive=1; + SendSubTaskMsg(((PortAudioStreamStruct*)stream)->st,STC_START,NULL); + //KPrintF("Zeile %ld\n",__LINE__); + Error=paNoError; + } + else + { + // printf(" %s called with NULL-Ptr\n",__FUNCTION__); + Error=paBadStreamPtr; + + } + + return Error; +} + +/* ########################################################################## */ + + +//PaError Pa_StopStream( PortAudioStream *stream ); + +PaError Pa_AbortStream_ahidev( PortAudioStream *stream ) +{ + // KPrintF("%s() called\n",__FUNCTION__); + // printf(" %s called for Stream %u\n",__FUNCTION__,((PortAudioStreamStruct*)stream)->AF_StreamID); + //KPrintF("Zeile %ld\n",__LINE__); + ((PortAudioStreamStruct*)stream)->StreamActive=0; + return paNoError; +} + +/* ########################################################################## */ +/* + Pa_StreamActive() returns one when the stream is playing audio, + zero when not playing, or a negative error number if the + stream is invalid. + The stream is active between calls to Pa_StartStream() and Pa_StopStream(), + but may also become inactive if the callback returns a non-zero value. + In the latter case, the stream is considered inactive after the last + buffer has finished playing. + */ + + +PaError Pa_StreamActive_ahidev( PortAudioStream *stream ) +{ + // KPrintF("%s() called\n",__FUNCTION__); + + if(stream) + { + // printf(" %s called for Stream %u\n returning %u\n",__FUNCTION__,((PortAudioStreamStruct*)stream)->AF_StreamID,((PortAudioStreamStruct*)stream)->StreamActive); + //KPrintF("Zeile %ld\n",__LINE__); + return ((PortAudioStreamStruct*)stream)->StreamActive; //paNoError; + } + else + { + // printf(" %s called with NULL-Ptr\n",__FUNCTION__); + // printf(" returning paBadStreamPtr\n"); + //KPrintF("Zeile %ld\n",__LINE__); + return paBadStreamPtr; // <0 is error + + } +} + +/* ########################################################################## */ +/* + Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that + opens the default input and/or ouput devices. Most parameters have + identical meaning to their Pa_OpenStream() counterparts, with the following + exceptions: + + If either numInputChannels or numOutputChannels is 0 the respective device + is not opened (same as passing paNoDevice in the device arguments to Pa_OpenStream() ) + + sampleFormat applies to both the input and output buffers. + */ + + + +PaError Pa_OpenDefaultStream_ahidev( PortAudioStream** stream, + int numInputChannels, + int numOutputChannels, + PaSampleFormat sampleFormat, + double sampleRate, + unsigned long framesPerBuffer, + unsigned long numberOfBuffers, + PortAudioCallback *callback, + void *userData ) +{ + //KPrintF("Zeile %ld\n",__LINE__); + // KPrintF("%s() called\n",__FUNCTION__); + /* + File_ahi=fopen("Samples","w"); + if(!File_ahi) + { + printf("Kann File nicht oeffnen\n"); + return paInternalError; + } + */ + + static unsigned int StreamNr=1; + PortAudioStreamStruct* StreamStruct; + int Error=paInternalError; + + // printf(" %s called\n",__FUNCTION__); + // printf(" numInputChannels=%d\n",numInputChannels); + // printf(" numOutputChannels=%d\n",numOutputChannels); + // printf(" sampleFormat=%lu (%u bytes)\n",sampleFormat,Pa_GetSampleSize(sampleFormat)); + // printf(" sampleRate=%f\n",sampleRate); + // printf(" framesPerBuffer=%lu\n",framesPerBuffer); // a frame is numOutputChannels * BytesPerSample + // printf(" numberOfBuffers=%lu\n",numberOfBuffers); // this is only a suggestion how many buffers to use, e.g double buffering + // printf(" userData=$%p\n",userData); + + + StreamStruct=(PortAudioStreamStruct*)malloc(sizeof(PortAudioStreamStruct)); + if(StreamStruct) + { + //KPrintF("Zeile %ld\n",__LINE__); + memset(StreamStruct,0,sizeof(PortAudioStreamStruct)); /* initilize all entries */ + StreamStruct->device=1; /* device must be initialized to !=0 (for 0 is success) */ + + // printf(" Setting Stream to %u\n",StreamNr); + StreamStruct->AF_StreamID=StreamNr; + StreamNr++; + + StreamStruct->callback=callback; // store ptr to callback function + StreamStruct->framesPerBuffer=framesPerBuffer*global_bufsize_factor; // AF Test mit n mal 512 Byte Puffern + StreamStruct->numInputChannels=numInputChannels; + StreamStruct->numOutputChannels=numOutputChannels; + StreamStruct->sampleFormat=sampleFormat; + StreamStruct->sampleRate=sampleRate; + StreamStruct->AhiSampleType=getAHISampleType(sampleFormat); + + + // ######################################## + + *stream=StreamStruct; + + GlobalPaStreamPtr_ahi=StreamStruct; /* in case of CTRL-C atexit()-Functions are void so a global pointer is needed */ + + /* Allocate two Audio Buffers in ChipMem for Amiga-8Bit-Samples */ + StreamStruct->ChipMemBuf1=(BYTE*)AllocMem(StreamStruct->framesPerBuffer,MEMF_CHIP); + if(StreamStruct->ChipMemBuf1) + { + //KPrintF("Zeile %ld\n",__LINE__); + + StreamStruct->ChipMemBuf2=(BYTE*)AllocMem(StreamStruct->framesPerBuffer,MEMF_CHIP); + if(StreamStruct->ChipMemBuf2) + { + //KPrintF("Zeile %ld\n",__LINE__); + + /* Allocate two Audio Buffers in FastMem for Espeak-16Bit-Samples */ + StreamStruct->FastMemBuf1=(SHORT*)AllocMem(StreamStruct->framesPerBuffer*Pa_GetSampleSize(StreamStruct->sampleFormat),MEMF_PUBLIC); + //KPrintF("Allocating %lu Bytes for FastMemBuf1, Ptr=$%08lx\n",(ULONG)StreamStruct->framesPerBuffer*Pa_GetSampleSize(StreamStruct->sampleFormat),(ULONG)StreamStruct->FastMemBuf1); + if(StreamStruct->FastMemBuf1) + { + //KPrintF("Zeile %ld\n",__LINE__); + + StreamStruct->FastMemBuf2=(SHORT*)AllocMem(StreamStruct->framesPerBuffer*Pa_GetSampleSize(StreamStruct->sampleFormat),MEMF_PUBLIC); + if(StreamStruct->FastMemBuf2) + { + //KPrintF("Zeile %ld\n",__LINE__); + + /* Allocate two audio IO Blocks */ + StreamStruct->AHIio=(struct AHIRequest*)AllocMem(sizeof(struct AHIRequest),MEMF_PUBLIC|MEMF_CLEAR); + if(StreamStruct->AHIio) + { + //KPrintF("Zeile %ld, AHIio=%08lx\n",__LINE__,StreamStruct->AHIio); + + StreamStruct->AHIio2=(struct AHIRequest*)AllocMem(sizeof(struct AHIRequest),MEMF_PUBLIC|MEMF_CLEAR); + if(StreamStruct->AHIio2) + { + //KPrintF("Zeile %ld\n",__LINE__); + + StreamStruct->AIOptrStartStop=(struct AHIRequest*)AllocMem(sizeof(struct AHIRequest),MEMF_PUBLIC|MEMF_CLEAR); + if(StreamStruct->AIOptrStartStop) + { + //KPrintF("Zeile %ld\n",__LINE__); + + StreamStruct->st = SpawnSubTask("EspeakAudioTask_AHI",EspeakAudioTask_AHI,StreamStruct); + if (StreamStruct->st) + { + //KPrintF("Zeile %ld\n",__LINE__); + + Error=paNoError; + return Error; + } + Error=paInternalError; + } + else + { + printf(" not enough memory for allocating AIOptrStartStop\n"); + Error=paInsufficientMemory; + } + FreeMem(StreamStruct->AHIio2,sizeof(struct AHIRequest)); + StreamStruct->AHIio2=NULL; + } + else + { + printf(" not enough memory for allocating AHIio2\n"); + Error=paInsufficientMemory; + } + FreeMem(StreamStruct->AHIio,sizeof(struct AHIRequest)); + StreamStruct->AHIio=NULL; + } + else + { + printf(" not enough memory for allocating AHIio\n"); + Error=paInsufficientMemory; + } + FreeMem(StreamStruct->FastMemBuf2,StreamStruct->framesPerBuffer*Pa_GetSampleSize(StreamStruct->sampleFormat)); + StreamStruct->FastMemBuf2=NULL; + } + else + { + printf(" Could not allocate FastMemBuf2 (%lu Bytes)\n",StreamStruct->framesPerBuffer*Pa_GetSampleSize(StreamStruct->sampleFormat)); + Error=paInsufficientMemory; + } + FreeMem(StreamStruct->FastMemBuf1,StreamStruct->framesPerBuffer*Pa_GetSampleSize(StreamStruct->sampleFormat)); + StreamStruct->FastMemBuf1=NULL; + } + else + { + printf(" Could not allocate FastMemBuf1 (%lu Bytes)\n",StreamStruct->framesPerBuffer*Pa_GetSampleSize(StreamStruct->sampleFormat)); + Error=paInsufficientMemory; + } + FreeMem(StreamStruct->ChipMemBuf2,StreamStruct->framesPerBuffer); + StreamStruct->ChipMemBuf2=NULL; + } + else + { + printf(" Could not allocate ChipMemBuf2 (%lu Bytes)\n",StreamStruct->framesPerBuffer); + Error=paInsufficientMemory; + } + FreeMem(StreamStruct->ChipMemBuf1,StreamStruct->framesPerBuffer); + StreamStruct->ChipMemBuf1=NULL; + } + else + { + printf(" Could not allocate ChipMemBuf1 (%lu Bytes)\n",StreamStruct->framesPerBuffer); + Error=paInsufficientMemory; + } + + free(StreamStruct); + StreamStruct=NULL; + *stream=NULL; + GlobalPaStreamPtr_ahi=NULL; /* in case of CTRL-C atexit()-Functions are void so a global pointer is needed */ + + } + else + { + printf(" not enough memory for allocating stream %u\n",StreamNr); + Error=paInsufficientMemory; + } + + // KPrintF("Finished %s\n",__FUNCTION__); + return Error; +} + + +/* ########################################################################## */ +/* + Pa_CloseStream() closes an audio stream, flushing any pending buffers. + */ + +PaError __attribute__((no_instrument_function)) Pa_CloseStream_ahidev( PortAudioStream *stream ) +{ + //KPrintF("%s() called\n",__FUNCTION__); + //KPrintF("Zeile %ld\n",__LINE__); + PortAudioStreamStruct *StreamStruct=(PortAudioStreamStruct*)stream; + + if(stream) + { + // printf(" %s called for Stream %u\n",__FUNCTION__,StreamStruct->AF_StreamID); + + if(StreamStruct->st) + { + KillSubTask(StreamStruct->st); + StreamStruct->st=NULL; + } + + if(StreamStruct->device==0) + { + CloseDevice((struct IORequest*)StreamStruct->AHIio); + StreamStruct->device=1; + } + + if(StreamStruct->portStartStop) + { + DeletePort(StreamStruct->portStartStop); + StreamStruct->portStartStop=0; + } + + if(StreamStruct->AHImp) + { + DeletePort(StreamStruct->AHImp); + StreamStruct->AHImp=0; + } + + if(StreamStruct->AIOptrStartStop) + { + FreeMem(StreamStruct->AIOptrStartStop,sizeof(struct AHIRequest)); + StreamStruct->AIOptrStartStop=NULL; + } + + if(StreamStruct->AHIio2) + { + FreeMem(StreamStruct->AHIio2,sizeof(struct AHIRequest)); + StreamStruct->AHIio2=NULL; + } + + if(StreamStruct->AHIio) + { + FreeMem(StreamStruct->AHIio,sizeof(struct AHIRequest)); + StreamStruct->AHIio=NULL; + } + + if(StreamStruct->FastMemBuf2) + { + FreeMem(StreamStruct->FastMemBuf2,StreamStruct->framesPerBuffer*Pa_GetSampleSize(StreamStruct->sampleFormat)); + StreamStruct->FastMemBuf2=NULL; + } + + if(StreamStruct->FastMemBuf1) + { + FreeMem(StreamStruct->FastMemBuf1,StreamStruct->framesPerBuffer*Pa_GetSampleSize(StreamStruct->sampleFormat)); + StreamStruct->FastMemBuf1=NULL; + } + + + if(StreamStruct->ChipMemBuf2) + { + FreeMem(StreamStruct->ChipMemBuf2,StreamStruct->framesPerBuffer); + StreamStruct->ChipMemBuf2=NULL; + } + + if(StreamStruct->ChipMemBuf1) + { + FreeMem(StreamStruct->ChipMemBuf1,StreamStruct->framesPerBuffer); + StreamStruct->ChipMemBuf1=NULL; + } + + free(StreamStruct); + GlobalPaStreamPtr_ahi=NULL; /* in case of CTRL-C atexit()-Functions are void so a global pointer is needed */ + + + // printf(" returning paNoError\n"); + return paNoError; + } + else + { + // printf(" %s called with NULL-Ptr\n",__FUNCTION__); + // printf(" returning paBadStreamPtr\n"); + return paBadStreamPtr; // <0 is error + + } + + if(File_ahi) + { + fclose(File_ahi); + File_ahi=NULL; + } + +} + + +/* ########################################################################## */ +/* + Pa_Initialize() is the library initialisation function - call this before + using the library. + */ + + +PaError Pa_Initialize_ahidev( void ) +{ + int Error; + //KPrintF("Zeile %ld\n",__LINE__); + // printf(" %s called\n",__FUNCTION__); + // KPrintF("%s() called\n",__FUNCTION__); + + Error=paNoError; + + return Error; +} + + + +// ############################################################################## +// not needed by espeak but used by myself, AF 18.May2017 + +/* + Return size in bytes of a single sample in a given PaSampleFormat + or paSampleFormatNotSupported. + */ +PaError Pa_GetSampleSize_ahidev( PaSampleFormat format ) +{ + // KPrintF("%s() called\n",__FUNCTION__); + //KPrintF("Zeile %ld\n",__LINE__); + switch (format) + { + case paFloat32 : return 4; /*always available*/ + case paInt16 : return 2; /*always available*/ + case paInt32 : return 4; /*always available*/ + case paInt24 : return 6; + case paPackedInt24 : return 6; + case paInt8 : return 1; + case paUInt8 : return 1; /* unsigned 8 bit, 128 is "ground" */ + default : return paSampleFormatNotSupported; + } +} + + + +STATIC_FUNC ULONG getAHISampleType(PaSampleFormat format ) +{ + //KPrintF("Zeile %ld\n",__LINE__); + // KPrintF("%s() called\n",__FUNCTION__); + switch (format) + { + // case paFloat32 : return ; /*always available*/ + case paInt16 : return AHIST_M16S; /* Mono, 16 bit signed (WORD) */ /*always available*/ + case paInt32 : return AHIST_M32S; /* Mono, 32 bit signed (LONG) */ /*always available*/ + // case paInt24 : return ; + // case paPackedInt24 : return ; + case paInt8 : return AHIST_M8S; /* Mono, 8 bit signed (BYTE) */ + case paUInt8 : return AHIST_M8U; /* OBSOLETE! */ /* unsigned 8 bit, 128 is "ground" */ + default : return AHIE_BADSAMPLETYPE; /* Unknown/unsupported sample type */; + } + +} + + +// ############################################################################## +/* reads 16Bit Signed Samples from Source and writes 8Bit Signed Samples to Dest. */ +/* 16 Bit Samples must be BIG_ENDIAN */ +/* SampleCount Samples will be read */ +/* SampleCount must be multiple of 2 */ +/* Returns number of copied samples */ +/* AF, 15.76.2017 */ + +//static UWORD Convert16SSamples(SHORT *Source16S, BYTE *Dest8S, ULONG SampleCount) +//{ +// UWORD i=0; +// ULONG *SourcePtr=(ULONG*)Source16S; /* we read 2 16Bit-Samples at once */ +// USHORT *DestPtr=(USHORT*)Dest8S; /* we write 2 8Bit-Samples at once */ +// ULONG SourceSamples; +// USHORT DestSamples; +// //KPrintF("Zeile %ld\n",__LINE__); +// if(SampleCount%2) +// { +// printf("%s() SampleCount %lu is not even!\n",__FUNCTION__,SampleCount); + /* we read probably one bad sample but continue anyway */ +// } + +// for(;i>16) | ((SourceSamples &0xff00) >> 8); /* extract the two High-Bytes */ +// *DestPtr++=DestSamples; + + /*printf("SourceSamples=0x%0lx, DestSamples=0x%0hx\n",SourceSamples,DestSamples);*/ +// } +// return i*2; +//} + + + +/* used for atexit(). Therefore void parameter -> global Pointer needed */ +void __attribute__((no_instrument_function)) Abort_Pa_CloseStream_ahidev (void) +{ + //KPrintF("Zeile %ld\n",__LINE__); + if(GlobalPaStreamPtr_ahi) + { + // KPrintF("%s() called with Stream=$%08lx\n",__FUNCTION__,GlobalPaStreamPtr_ahi); + Pa_CloseStream(GlobalPaStreamPtr_ahi); + GlobalPaStreamPtr_ahi=NULL; + } + else + { + // KPrintF("%s() called but nothing to do\n",__FUNCTION__); + } +} + + + diff --git a/src/amiga/portaudio/portaudio_ahidev.h b/src/amiga/portaudio/portaudio_ahidev.h new file mode 100644 index 0000000..4b7b07d --- /dev/null +++ b/src/amiga/portaudio/portaudio_ahidev.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2017 by Alexander Fritsch * + * email: selco@t-online.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write see: * + * . * + ***************************************************************************/ + +/* + * * portaudio_ahidev.h + * + * Created on: Nov 28, 2017 + * Author: developer + */ + +#ifndef SRC_AMIGA_PORTAUDIO_PORTAUDIO_AHIDEV_H_ +#define SRC_AMIGA_PORTAUDIO_PORTAUDIO_AHIDEV_H_ + + + +#include "../portaudio18.h" + +/* prototypes to be used in general portaudio.cpp only */ + +PaError Pa_StartStream_ahidev( PortAudioStream *stream ); +PaError Pa_AbortStream_ahidev( PortAudioStream *stream ); +PaError Pa_StreamActive_ahidev( PortAudioStream *stream ); +PaError Pa_OpenDefaultStream_ahidev( PortAudioStream** stream, + int numInputChannels, + int numOutputChannels, + PaSampleFormat sampleFormat, + double sampleRate, + unsigned long framesPerBuffer, + unsigned long numberOfBuffers, + PortAudioCallback *callback, + void *userData ); +PaError Pa_CloseStream_ahidev( PortAudioStream *stream ); +PaError Pa_Initialize_ahidev( void ); +PaError Pa_GetSampleSize_ahidev( PaSampleFormat format ); +void Abort_Pa_CloseStream_ahidev (void); + +extern unsigned int g_AHI_Unit; + + +#endif /* SRC_AMIGA_PORTAUDIO_PORTAUDIO_AHIDEV_H_ */ diff --git a/src/amiga/portaudio/portaudio_audev.c b/src/amiga/portaudio/portaudio_audev.c new file mode 100644 index 0000000..e5e450c --- /dev/null +++ b/src/amiga/portaudio/portaudio_audev.c @@ -0,0 +1,1190 @@ +/*************************************************************************** + * Copyright (C) 2017 by Alexander Fritsch * + * email: selco@t-online.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write see: * + * . * + ***************************************************************************/ + +/* Amiga audio.device part */ + +#include "../portaudio18.h" +#include +#include + +/* AF, Gwd, 5.May 2017 */ + +#include +#include "subtask_support.h" + +#include + +#include +#include + +#include /* for CreatePort */ +#include +#include +#include // sleep + +#include "portaudio_audev.h" + +#ifdef mc68060 +#define __CPU__ "mc68060" +#elif defined mc68040 +#define __CPU__ "mc68040" +#elif defined mc68030 +#define __CPU__ "mc68030" +#elif defined mc68020 +#define __CPU__ "mc68020" +#elif defined mc68000 +#define __CPU__ "mc68000" +#else +#define __CPU__ "???????" +#endif + +#ifdef __HAVE_68881__ +#define __FPU__ "mc68881" +#else +#define __FPU__ "" +#endif + +/*extern "C"*/ LONG KPrintF(STRPTR format, ...); + +#include +static struct timeval startTime; + +void TimerAuDevStartup() { + GetSysTime(&startTime); +} + + +extern unsigned int global_bufsize_factor; // AF Test einstellbare Audio Buffergroesse n mal 512 Bytes +extern unsigned int global_benchmark_flag; // AF Einschalten der Ausgabe der durchschnittlichen Zeit fuer die portaudio-Callbackfunktion +extern char *global_ProgramName; // AF argv[0] + +ULONG TimerAuDevGetMilliseconds() { + struct timeval endTime; + + GetSysTime(&endTime); + SubTime(&endTime, &startTime); + + return (endTime.tv_secs * 1000 + endTime.tv_micro / 1000); +} + + + +FILE *File=NULL; // testweise samples in File schreiben + + +//UBYTE chans[] ={1,2,4,8}; /* get any of the four channels RKRM Audio-example */ +UBYTE chans[] ={3,5,10,12}; /* get a pair of stereo channels, RKRM Devices */ +//UBYTE chans[] ={1,8}; /* test, nur rechts */ +//UBYTE chans[] ={2,4}; /* test, nur links */ + +typedef struct +{ + int StreamActive; + unsigned int AF_StreamID; // just a number to see which stream is referred to + + struct SubTask *st; + struct SignalSemaphore sema; /* data item protection */ + + int numInputChannels; + int numOutputChannels; // 1 for mono, 2 for stereo + PaSampleFormat sampleFormat; + double sampleRate; + unsigned long framesPerBuffer; // a frames is one complete sample from each channel + unsigned long numberOfBuffers; // suggestion for (double) bufering + PortAudioCallback *callback; + void *userData; + unsigned int clock; // Amiga Systemclock 3546895 for PAL, 3579545 for NTSC */ + unsigned long speed; // clock / samplerate + struct IOAudio *AIOptr1; // four audio I/O blocks + struct IOAudio *AIOptr1_2; // second channel + struct IOAudio *AIOptr2; + struct IOAudio *AIOptr2_2; // second channel + struct IOAudio *AIOptrStartStop;// for CMD_START and CMD_STOP + struct MsgPort *port1; + struct MsgPort *port1_2; + struct MsgPort *port2; + struct MsgPort *port2_2; + struct MsgPort *portStartStop; + ULONG device; // Audio device handle + BYTE *ChipMemBuf1; // Amiga-Audiobuffer + BYTE *ChipMemBuf2; // Amiga-Audiobuffer + SHORT *FastMemBuf1; // Espeak-AudioBuffer used in Callback + SHORT *FastMemBuf2; // Espeak-AudioBuffer used in Callback + unsigned int LeftChannel; // left Audiochannel we got allocated in OpenDevice() or 0 + unsigned int RightChannel; // right Audiochannel we got allocated in OpenDevice() or 0 + + +}PortAudioStreamStruct; + + + +// This function writes the channel-Bit to io.Unit. It saves some pointer magic +// old code was +// (ULONG)PortAudioStreamData->AIOptr1 ->ioa_Request.io_Unit &=0xf0; (ULONG)&PortAudioStreamData->AIOptr1 ->ioa_Request.io_Unit |= PortAudioStreamData->LeftChannel; /* lower 4 Bits contain ONE channel bit */ +// but does not compile under gcc6 nay more +void SetAudioUnit(struct IOAudio *AIOptr,unsigned int Channel) +{ + ULONG Temp; + Temp= (ULONG) AIOptr->ioa_Request.io_Unit; + Temp&=0xf0; + Temp|=Channel; + AIOptr->ioa_Request.io_Unit =(struct Unit*)Temp; + +} + + +STATIC_FUNC UWORD Convert16SSamples(SHORT *Source16S, BYTE *Dest8S, ULONG SampleCount); /* reads 16Bit Signed Samples from Source and writes 8Bit Signed Samples to Dest. DestLen Samples will be read */ + + +struct Device* TimerBase; // nur zum Benchmarking +static struct IORequest timereq; // nur zum Benchmarking + +VOID /*__asm __saveds*/ SamAudioTask(VOID) +{ + + // KPrintF("%s() called\n",__FUNCTION__); + + + + struct Task *me = FindTask(NULL); + struct SubTask *st; + struct SubTaskMsg *stm; + + /* + ** Wait for our startup message from the SpawnSubTask() function. + */ + + WaitPort(&((struct Process *)me)->pr_MsgPort); + stm = (struct SubTaskMsg *)GetMsg(&((struct Process *)me)->pr_MsgPort); + st = (struct SubTask *)stm->stm_Parameter; + + + + + { + // struct Data *data = (struct Data *)st->st_Data; + BOOL running = TRUE; + BOOL worktodo = FALSE; + + PortAudioStreamStruct *PortAudioStreamData=(PortAudioStreamStruct*)(st->st_Data); + int Error=paInternalError; + + if(0==OpenDevice((CONST_STRPTR)TIMERNAME, UNIT_MICROHZ, &timereq, 0)) // nur zum test + { + TimerBase = timereq.io_Device; // nur zum test + + /* Make four Reply-Ports */ + PortAudioStreamData->port1=CreatePort(0,0); + if(PortAudioStreamData->port1) + { + PortAudioStreamData->port1_2=CreatePort(0,0); + if(PortAudioStreamData->port1_2) + { + PortAudioStreamData->port2=CreatePort(0,0); + if(PortAudioStreamData->port2) + { + PortAudioStreamData->port2_2=CreatePort(0,0); + if(PortAudioStreamData->port2_2) + { + PortAudioStreamData->portStartStop=CreatePort(0,0); + if(PortAudioStreamData->portStartStop) + { + + /* Now Open Audio Device */ + // KPrintF("Attempting to open Audio.device\n"); + /* set up audio I/O block for channel */ + /* allocation and Open the audio.device */ + PortAudioStreamData->AIOptr1->ioa_Request.io_Message.mn_ReplyPort=PortAudioStreamData->port1; + PortAudioStreamData->AIOptr1->ioa_Request.io_Message.mn_Node.ln_Pri=127; /* no stealing */ + PortAudioStreamData->AIOptr1->ioa_Request.io_Message.mn_Length=sizeof(struct IOAudio); + + PortAudioStreamData->AIOptr1->ioa_AllocKey=0; + PortAudioStreamData->AIOptr1->ioa_Data=chans; + PortAudioStreamData->AIOptr1->ioa_Length=sizeof(chans); + + + PortAudioStreamData->device=OpenDevice((CONST_STRPTR)AUDIONAME,0L,(struct IORequest*)PortAudioStreamData->AIOptr1,0L); + + if(PortAudioStreamData->device==0) + { + UBYTE GotChannels; + + /* Set Up Audio IO Blocks for Sample Playing */ + //printf("AllocKey is 0x%02u\n",PortAudioStreamData->AIOptr1->ioa_AllocKey); + //printf("ioa_Request.io_Unit=0x%02u\n",(UBYTE)PortAudioStreamData->AIOptr1->ioa_Request.io_Unit); /* the channels I got are in ioUnit, lower 4 bits. */ + + + GotChannels=((/*UBYTE*/ULONG)PortAudioStreamData->AIOptr1->ioa_Request.io_Unit) & 0x0f; /* the channels I got are in ioUnit, lower 4 bits. */ + if(GotChannels & 0x02) PortAudioStreamData->LeftChannel=0x02; + else if(GotChannels & 0x04) PortAudioStreamData->LeftChannel=0x04; + else PortAudioStreamData->LeftChannel=0; + + if(GotChannels & 0x01) PortAudioStreamData->RightChannel=0x01; + else if(GotChannels & 0x08) PortAudioStreamData->RightChannel=0x08; + else PortAudioStreamData->RightChannel=0; + + //printf("Left Channel: %u\n",PortAudioStreamData->LeftChannel); + //printf("Right Channel: %u\n",PortAudioStreamData->RightChannel); + + PortAudioStreamData->AIOptr1->ioa_Request.io_Command=CMD_WRITE; + PortAudioStreamData->AIOptr1->ioa_Request.io_Flags=ADIOF_PERVOL; + + /* Volume */ + PortAudioStreamData->AIOptr1->ioa_Volume=64; /* (0 thru 64, linear) */ + + /* Period/Cycles */ + PortAudioStreamData->AIOptr1->ioa_Period=(UWORD)PortAudioStreamData->speed; + PortAudioStreamData->AIOptr1->ioa_Cycles=1; + + *(PortAudioStreamData->AIOptr1_2)=*(PortAudioStreamData->AIOptr1); /* Make sure we have the same allocation keys */ + *(PortAudioStreamData->AIOptr2) =*(PortAudioStreamData->AIOptr1); /* Make sure we have the same allocation keys */ + *(PortAudioStreamData->AIOptr2_2)=*(PortAudioStreamData->AIOptr1); /* Make sure we have the same allocation keys */ + *(PortAudioStreamData->AIOptrStartStop)=*(PortAudioStreamData->AIOptr1); /* Make sure we have the same allocation keys */ + /* same channel selected (allocKeys) and same flags */ + /* but different ports... */ + PortAudioStreamData->AIOptr1 ->ioa_Request.io_Message.mn_ReplyPort=PortAudioStreamData->port1; /* Left and right Channels are running exactly synchronous. They can therefore use the same port */ + PortAudioStreamData->AIOptr1_2->ioa_Request.io_Message.mn_ReplyPort=PortAudioStreamData->port1_2; + PortAudioStreamData->AIOptr2 ->ioa_Request.io_Message.mn_ReplyPort=PortAudioStreamData->port2; + PortAudioStreamData->AIOptr2_2->ioa_Request.io_Message.mn_ReplyPort=PortAudioStreamData->port2_2; + PortAudioStreamData->AIOptrStartStop->ioa_Request.io_Message.mn_ReplyPort=PortAudioStreamData->portStartStop; + /* and different Channels in ioUnit -> CMD_WRITE is a single channel command */ + + // (ULONG)PortAudioStreamData->AIOptr1 ->ioa_Request.io_Unit &=0xf0; (ULONG)&PortAudioStreamData->AIOptr1 ->ioa_Request.io_Unit |= PortAudioStreamData->LeftChannel; /* lower 4 Bits contain ONE channel bit */ + // (ULONG)PortAudioStreamData->AIOptr1_2->ioa_Request.io_Unit &=0xf0; (ULONG)PortAudioStreamData->AIOptr1_2->ioa_Request.io_Unit |= PortAudioStreamData->RightChannel; + // (ULONG)PortAudioStreamData->AIOptr2 ->ioa_Request.io_Unit &=0xf0; (ULONG)PortAudioStreamData->AIOptr2 ->ioa_Request.io_Unit |= PortAudioStreamData->LeftChannel; + // (ULONG)PortAudioStreamData->AIOptr2_2->ioa_Request.io_Unit &=0xf0; (ULONG)PortAudioStreamData->AIOptr2_2->ioa_Request.io_Unit |= PortAudioStreamData->RightChannel; + // use new function SetAudioUnit() instead + SetAudioUnit(PortAudioStreamData->AIOptr1, PortAudioStreamData->LeftChannel); /* lower 4 Bits contain ONE channel bit */ + SetAudioUnit(PortAudioStreamData->AIOptr1_2, PortAudioStreamData->RightChannel); /* lower 4 Bits contain ONE channel bit */ + SetAudioUnit(PortAudioStreamData->AIOptr2, PortAudioStreamData->LeftChannel); /* lower 4 Bits contain ONE channel bit */ + SetAudioUnit(PortAudioStreamData->AIOptr2_2, PortAudioStreamData->RightChannel); /* lower 4 Bits contain ONE channel bit */ + + + + // Data... + + if ((st->st_Port = CreateMsgPort())) + { + /* + ** Reply startup message, everything ok. + ** Note that if the initialization fails, the code falls + ** through and replies the startup message with a stm_Result + ** of 0 after a Forbid(). This tells SpawnSubTask() that the + ** sub task failed to run. + */ + + /* variables are declared here because they should be initialized to Zero */ + /* in the for loop they would become initialized at the beginning of every turn - which is wrong */ + struct IOAudio *Aptr=NULL; /* for double buffer switching */ + struct MsgPort *port=NULL; /* for double buffer switching */ + struct MsgPort *port_2=NULL; /* for double buffer switching for the second audio channel (we do 2-channel(MONO) playback)*/ + BYTE *ChipMemBuf=NULL; /* Amiga-Audiobuffer for double buffer switching */ + SHORT *FastMemBuf=NULL; /* Espeak-AudioBuffer used in Callback for double buffer switching */ + + ULONG CallbackTime=0; /* For Callback benchmarking */ + ULONG CallBackCount=0; + ULONG CallBackMaxTime=0; + + stm->stm_Result = TRUE; + ReplyMsg((struct Message *)stm); + // Ok, all opened sucessfully + // KPrintF("Opened Audio.device successfully\n"); + + /* + ** after the sub task is up and running, we go into + ** a loop and process the messages from the main task. + */ + + for (;;) + { + while ((stm = (struct SubTaskMsg *)GetMsg(st->st_Port))) + { + switch (stm->stm_Command) + { + case STC_SHUTDOWN: + /* + ** This is the shutdown message from KillSubTask(). + */ + // printf("Task STC_SHUTDOWN\n"); + //KPrintF("STC_SHUTDOWN\n"); + + running = FALSE; + break; + + case STC_START: + /* + ** we received a start message with a fractal description. + ** clear the rastport and the line update array and start + ** rendering. + */ + // printf("Task STC_START\n"); + //KPrintF("STC_START\n"); + + worktodo = TRUE; + + /* read two buffers. cannot fail. (just end of data but that does not matter here) */ + PortAudioStreamData->callback(NULL,PortAudioStreamData->FastMemBuf1,PortAudioStreamData->framesPerBuffer,0,NULL); + + Convert16SSamples(PortAudioStreamData->FastMemBuf1, PortAudioStreamData->ChipMemBuf1 ,PortAudioStreamData->framesPerBuffer); + PortAudioStreamData->AIOptr1->ioa_Length=PortAudioStreamData->framesPerBuffer; + PortAudioStreamData->AIOptr1->ioa_Data=(UBYTE*)PortAudioStreamData->ChipMemBuf1; + + PortAudioStreamData->AIOptr1_2->ioa_Length=PortAudioStreamData->framesPerBuffer; /* second channel */ + PortAudioStreamData->AIOptr1_2->ioa_Data=(UBYTE*)PortAudioStreamData->ChipMemBuf1; /* second channel */ + + + + PortAudioStreamData->callback(NULL,PortAudioStreamData->FastMemBuf2,PortAudioStreamData->framesPerBuffer,0,NULL); + Convert16SSamples(PortAudioStreamData->FastMemBuf2, PortAudioStreamData->ChipMemBuf2 ,PortAudioStreamData->framesPerBuffer); + PortAudioStreamData->AIOptr2->ioa_Length=PortAudioStreamData->framesPerBuffer; + PortAudioStreamData->AIOptr2->ioa_Data=(UBYTE*)PortAudioStreamData->ChipMemBuf2; + + PortAudioStreamData->AIOptr2_2->ioa_Length=PortAudioStreamData->framesPerBuffer; /* second channel */ + PortAudioStreamData->AIOptr2_2->ioa_Data=(UBYTE*)PortAudioStreamData->ChipMemBuf2; /* second channel */ + + /* Synchonized Start of both stereo channels -> CMD_STOP, CMD_WRITE, CMD_START */ + PortAudioStreamData->AIOptrStartStop->ioa_Request.io_Command=CMD_STOP; + DoIO((struct IORequest*)PortAudioStreamData->AIOptrStartStop); /* synchronous call, cares about complete-message */ + + /* Start playback */ + BeginIO((struct IORequest*)PortAudioStreamData->AIOptr1); + BeginIO((struct IORequest*)PortAudioStreamData->AIOptr1_2); + BeginIO((struct IORequest*)PortAudioStreamData->AIOptr2); + BeginIO((struct IORequest*)PortAudioStreamData->AIOptr2_2); + + //KPrintF("AIOptr1=0x%08lx\n",PortAudioStreamData->AIOptr1); + //KPrintF("AIOptr1_2=0x%08lx\n",PortAudioStreamData->AIOptr1_2); + //KPrintF("AIOptr2=0x%08lx\n",PortAudioStreamData->AIOptr2); + //KPrintF("AIOptr2_2=0x%08lx\n",PortAudioStreamData->AIOptr2_2); + + PortAudioStreamData->AIOptrStartStop->ioa_Request.io_Command=CMD_START; + DoIO((struct IORequest*)PortAudioStreamData->AIOptrStartStop); /* synchronous call, cares about complete-message */ + + /* set the double buffer switching */ + Aptr=PortAudioStreamData->AIOptr1; + port=PortAudioStreamData->port1; + port_2=PortAudioStreamData->port1_2; + FastMemBuf=PortAudioStreamData->FastMemBuf1; + ChipMemBuf=PortAudioStreamData->ChipMemBuf1; + break; + + case STC_STOP: + /* this message is not used in this example */ + // printf("Task STC_STOP\n"); + //KPrintF("STC_STOP\n"); + worktodo = FALSE; + break; + }// switch + + /* + ** If we received a shutdown message, we do not reply it + ** immediately. First, we need to free our resources. + */ + if (!running) break; + + ReplyMsg((struct Message *)stm); + } + + if (!running) + { + break; // while + } + + if (worktodo) + { + /* if there is work to do,... + */ + /* + void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, PaTimestamp outTime, void *userData ); + */ + + struct Message *msg; + ULONG wakebit; + + wakebit=Wait(1 << port->mp_SigBit); + while((msg=GetMsg(port))==0) + { + }; + //KPrintF("GetMsg() returned 0x%08lx\n",msg); + wakebit=Wait(1 << port_2->mp_SigBit); + while((msg=GetMsg(port_2))==0) // the 2. channel has also finished. Clear that message queue, too + { + }; + + + if(global_benchmark_flag) + { + TimerAuDevStartup(); /* set CallbackTime startvalue */ + } + // printf("Callback() called %u\n",count); + if( 0!=PortAudioStreamData->callback(NULL,FastMemBuf,PortAudioStreamData->framesPerBuffer,0,NULL)) /* Last Buffer */ + { + /* we queue this last buffer for playback and wait for the previous one and this one to finish */ + + // printf("Callback() called %u, return != paContinue. End of stream.\n",count); + PortAudioStreamData->StreamActive=0; + worktodo=FALSE; + Convert16SSamples(FastMemBuf, ChipMemBuf ,PortAudioStreamData->framesPerBuffer); + BeginIO((struct IORequest*)Aptr); + BeginIO((Aptr==PortAudioStreamData->AIOptr1)?(struct IORequest*)PortAudioStreamData->AIOptr1_2:(struct IORequest*)PortAudioStreamData->AIOptr2_2); /* also corresponding 2. stereo-channel */ + /* Wait for the last two buffers to finish */ + if(Aptr==(struct IOAudio*)PortAudioStreamData->AIOptr1) + { + Aptr=PortAudioStreamData->AIOptr2; + port=PortAudioStreamData->port2; + port_2=PortAudioStreamData->port2_2; + } + else + { + Aptr=PortAudioStreamData->AIOptr1; + port=PortAudioStreamData->port1; + port_2=PortAudioStreamData->port1_2; + } + wakebit=Wait(1 << port->mp_SigBit); /* wait until last buffer has finished */ + while((msg=GetMsg(port))==0) {}; + wakebit=Wait(1 << port_2->mp_SigBit); /* wait until last buffer has finished */ + while((msg=GetMsg(port_2))==0) {}; + + if(Aptr==(struct IOAudio*)PortAudioStreamData->AIOptr1) + { + port=PortAudioStreamData->port2; + port_2=PortAudioStreamData->port2_2; + } + else + { + port=PortAudioStreamData->port1; + port_2=PortAudioStreamData->port1_2; + } + wakebit=Wait(1 << port->mp_SigBit); /* wait until last bufer has finished */ + while((msg=GetMsg(port))==0) {}; + wakebit=Wait(1 << port_2->mp_SigBit); /* wait until last bufer has finished */ + while((msg=GetMsg(port_2))==0) {}; + } + else /* There are more buffers to come */ + { + if(global_benchmark_flag) + { + unsigned long Time=TimerAuDevGetMilliseconds(); /* measure time for callbacks for benchmarking */ + if(Time>CallBackMaxTime) + { + CallBackMaxTime=Time; + } + CallbackTime+=Time; + CallBackCount+=1; + } + //KPrintF("Convert16SSamples($%08lx,$%08lx)\n",(ULONG)PortAudioStreamData->FastMemBuf1, (ULONG)PortAudioStreamData->ChipMemBuf1); + + //fwrite(PortAudioStreamData->FastMemBuf1,PortAudioStreamData->framesPerBuffer,1,File); + Convert16SSamples(FastMemBuf, ChipMemBuf ,PortAudioStreamData->framesPerBuffer); + // fwrite(PortAudioStreamData->ChipMemBuf1,PortAudioStreamData->framesPerBuffer,1,File); + BeginIO((struct IORequest*)Aptr); + BeginIO((Aptr==PortAudioStreamData->AIOptr1)?(struct IORequest*)PortAudioStreamData->AIOptr1_2:(struct IORequest*)PortAudioStreamData->AIOptr2_2); /* also corresponding 2. stereo-channel */ + + /* Double buffer switching */ + if(Aptr==(struct IOAudio*)PortAudioStreamData->AIOptr1) + { + Aptr=PortAudioStreamData->AIOptr2; + port=PortAudioStreamData->port2; + port_2=PortAudioStreamData->port2_2; + FastMemBuf=PortAudioStreamData->FastMemBuf2; + ChipMemBuf=PortAudioStreamData->ChipMemBuf2; + } + else + { + Aptr=PortAudioStreamData->AIOptr1; + port=PortAudioStreamData->port1; + port_2=PortAudioStreamData->port1_2; + FastMemBuf=PortAudioStreamData->FastMemBuf1; + ChipMemBuf=PortAudioStreamData->ChipMemBuf1; + } + + } + + //TimerAuuDevstartup(); // Zeit Anfang + //KPrintF("PortAudioStreamData->port1->mp_SigBit = 0x%04lx\n",(ULONG)PortAudioStreamData->port1->mp_SigBit); + //KPrintF("wakebit = 0x%04lx\n",(ULONG)wakebit); + //KPrintF("st->st_Port->mp_SigBit = 0x%04lx\n\n",(ULONG)st->st_Port->mp_SigBit); + + //ULONG Zeit=getMilliseconds(); + //KPrintF("Dauer: %lums\n",Zeit); + + // fwrite(PortAudioStreamData->ChipMemBuf1,PortAudioStreamData->framesPerBuffer,1,File); + /* Since we are very busy working, we do not Wait() for signals. */ + } + else + { + //KPrintF("Nothing to do\n"); + /* We have nothing to do, just sit quietly and wait for something to happen */ + WaitPort(st->st_Port); + } + }//for + + + //KPrintF("stm=%lx\n",stm); + + Error=paNoError; + // return;// Error; + + /* Wait for sound to finish ALEXANDER */ + PortAudioStreamData->AIOptr1->ioa_Request.io_Command=ADCMD_FINISH; + BeginIO((struct IORequest*)PortAudioStreamData->AIOptr1); + PortAudioStreamData->AIOptr2->ioa_Request.io_Command=ADCMD_FINISH; + BeginIO((struct IORequest*)PortAudioStreamData->AIOptr2); + + if(global_benchmark_flag) /* if Benchmarking was done */ + { + printf("%s, Average BufferTime %lums, Max Buffertime %lums, (Buffer is %lums), Compiled for " __CPU__ " " __FPU__ "\n",global_ProgramName,CallbackTime/CallBackCount,CallBackMaxTime,(ULONG)(global_bufsize_factor*512*1000/PortAudioStreamData->sampleRate)); + } + //KPrintF("Calling DeletePort st->st_Port\n"); + DeletePort(st->st_Port); + st->st_Port=NULL; + } + else // st->st_Port = CreateMsgPort() failed + { + printf(" Subtask CreateMsgPort() failed\n"); + Error=paInsufficientMemory; + } + //KPrintF("Calling CloseDevice\n"); + CloseDevice((struct IORequest*)PortAudioStreamData->AIOptr1); + PortAudioStreamData->device=1; + } + else + { + printf(" Could not open " AUDIONAME "\n"); + Error=paDeviceUnavailable; + } + /* --------------------- */ + //KPrintF("Calling DeletePortStartStop\n"); + DeletePort(PortAudioStreamData->portStartStop); + PortAudioStreamData->portStartStop=NULL; + } + else + { + printf(" Could not create portStartStop\n"); + Error=paInsufficientMemory; + } + //KPrintF("Calling DeletePort2_2\n"); + DeletePort(PortAudioStreamData->port2_2); + PortAudioStreamData->port2_2=NULL; + + } + else + { + printf(" Could not create port2_2\n"); + Error=paInsufficientMemory; + } + //KPrintF("Calling DeletePort2\n"); + DeletePort(PortAudioStreamData->port2); + PortAudioStreamData->port2=NULL; + } + else + { + printf(" Could not create port2\n"); + Error=paInsufficientMemory; + } + //KPrintF("Calling DeletePort1_2\n"); + DeletePort(PortAudioStreamData->port1_2); + PortAudioStreamData->port1_2=NULL; + } + else + { + printf(" Could not create port1_2\n"); + Error=paInsufficientMemory; + } + //KPrintF("Calling DeletePort1\n"); + DeletePort(PortAudioStreamData->port1); + PortAudioStreamData->port1=NULL; + } + else + { + printf(" Could not create port1\n"); + Error=paInsufficientMemory; + } + + CloseDevice(&timereq); + } + else + { + printf(" Could not open " TIMERNAME "\n"); + } + + // Error uebergeben? + //KPrintF("Calling ExitSubtask. stm=%lx\n",(ULONG)stm); + ExitSubTask(st,stm); + } +} + + +/* ##################################################################################################### */ + +PortAudioStream *GlobalPaStreamPtr=NULL; /* used for atexit(). Functions there have void parameter -> global Pointer needed */ + + +/* + Pa_StartStream() and Pa_StopStream() begin and terminate audio processing. + Pa_StopStream() waits until all pending audio buffers have been played. + Pa_AbortStream() stops playing immediately without waiting for pending + buffers to complete. + */ + +PaError Pa_StartStream_audev( PortAudioStream *stream ) +{ + int Error; + // KPrintF("%s() called\n",__FUNCTION__); + if(stream) + { + // printf(" %s called for Stream %u\n",__FUNCTION__,((PortAudioStreamStruct*)stream)->AF_StreamID); + ((PortAudioStreamStruct*)stream)->StreamActive=1; + SendSubTaskMsg(((PortAudioStreamStruct*)stream)->st,STC_START,NULL); + Error=paNoError; + } + else + { + // printf(" %s called with NULL-Ptr\n",__FUNCTION__); + Error=paBadStreamPtr; + + } + + return Error; +} + +/* ########################################################################## */ + + +//PaError Pa_StopStream( PortAudioStream *stream ); + +PaError Pa_AbortStream_audev( PortAudioStream *stream ) +{ + // KPrintF("%s() called\n",__FUNCTION__); + // printf(" %s called for Stream %u\n",__FUNCTION__,((PortAudioStreamStruct*)stream)->AF_StreamID); + ((PortAudioStreamStruct*)stream)->StreamActive=0; + return paNoError; +} + +/* ########################################################################## */ +/* + Pa_StreamActive() returns one when the stream is playing audio, + zero when not playing, or a negative error number if the + stream is invalid. + The stream is active between calls to Pa_StartStream() and Pa_StopStream(), + but may also become inactive if the callback returns a non-zero value. + In the latter case, the stream is considered inactive after the last + buffer has finished playing. + */ + + +PaError Pa_StreamActive_audev( PortAudioStream *stream ) +{ + // KPrintF("%s() called\n",__FUNCTION__); + + if(stream) + { + // printf(" %s called for Stream %u\n returning %u\n",__FUNCTION__,((PortAudioStreamStruct*)stream)->AF_StreamID,((PortAudioStreamStruct*)stream)->StreamActive); + + return ((PortAudioStreamStruct*)stream)->StreamActive; //paNoError; + } + else + { + // printf(" %s called with NULL-Ptr\n",__FUNCTION__); + // printf(" returning paBadStreamPtr\n"); + return paBadStreamPtr; // <0 is error + + } +} + +/* ########################################################################## */ +/* + Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that + opens the default input and/or ouput devices. Most parameters have + identical meaning to their Pa_OpenStream() counterparts, with the following + exceptions: + + If either numInputChannels or numOutputChannels is 0 the respective device + is not opened (same as passing paNoDevice in the device arguments to Pa_OpenStream() ) + + sampleFormat applies to both the input and output buffers. + */ + + + +PaError Pa_OpenDefaultStream_audev( PortAudioStream** stream, + int numInputChannels, + int numOutputChannels, + PaSampleFormat sampleFormat, + double sampleRate, + unsigned long framesPerBuffer, + unsigned long numberOfBuffers, + PortAudioCallback *callback, + void *userData ) +{ + + KPrintF("%s() called\n",__FUNCTION__); + // KPrintF("%s() called\n",__FUNCTION__); + /* + File=fopen("Samples","w"); + if(!File) + { + printf("Kann File nicht oeffnen\n"); + return paInternalError; + } + */ + + static unsigned int StreamNr=1; + PortAudioStreamStruct* StreamStruct; + int Error=paInternalError; + struct GfxBase *GfxBase; + unsigned int clock; + + // printf(" %s called\n",__FUNCTION__); + // printf(" numInputChannels=%d\n",numInputChannels); + // printf(" numOutputChannels=%d\n",numOutputChannels); + // printf(" sampleFormat=%lu (%u bytes)\n",sampleFormat,Pa_GetSampleSize_audev(sampleFormat)); + // printf(" sampleRate=%f\n",sampleRate); + // printf(" framesPerBuffer=%lu\n",framesPerBuffer); // a frame is numOutputChannels * BytesPerSample + // printf(" numberOfBuffers=%lu\n",numberOfBuffers); // this is only a suggestion how many buffers to use, e.g double buffering + // printf(" userData=$%p\n",userData); + + + GfxBase = (struct GfxBase *)OpenLibrary((CONST_STRPTR)"graphics.library",0L); + if (GfxBase) + { + if (GfxBase->DisplayFlags & PAL) + { + clock = 3546895; /* PAL clock */ + } + else + { + clock = 3579545; /* NTSC clock */ + } + CloseLibrary((struct Library *) GfxBase); + + StreamStruct=(PortAudioStreamStruct*)malloc(sizeof(PortAudioStreamStruct)); + if(StreamStruct) + { + memset(StreamStruct,0,sizeof(PortAudioStreamStruct)); /* initilize all entries */ + StreamStruct->device=1; /* device must be initialized to !=0 (for 0 is success) */ + + // printf(" Setting Stream to %u\n",StreamNr); + StreamStruct->AF_StreamID=StreamNr; + StreamNr++; + + StreamStruct->callback=callback; // store ptr to callback function + StreamStruct->framesPerBuffer=framesPerBuffer*global_bufsize_factor; // AF Test mit n mal 512 Byte Puffern + StreamStruct->numInputChannels=numInputChannels; + StreamStruct->numOutputChannels=numOutputChannels; + StreamStruct->sampleFormat=sampleFormat; + StreamStruct->sampleRate=sampleRate; + + StreamStruct->clock=clock; + + /*----------------------------------*/ + /* Calculate playback sampling rate */ + /*----------------------------------*/ + StreamStruct->speed = (ULONG) (clock / sampleRate); + + + // ######################################## + + *stream=StreamStruct; + + GlobalPaStreamPtr=StreamStruct; /* in case of CTRL-C atexit()-Functions are void so a global pointer is needed */ + + /* Allocate two Audio Buffers in ChipMem for Amiga-8Bit-Samples */ + StreamStruct->ChipMemBuf1=(BYTE*)AllocMem(StreamStruct->framesPerBuffer,MEMF_CHIP); + if(StreamStruct->ChipMemBuf1) + { + StreamStruct->ChipMemBuf2=(BYTE*)AllocMem(StreamStruct->framesPerBuffer,MEMF_CHIP); + if(StreamStruct->ChipMemBuf2) + { + /* Allocate two Audio Buffers in FastMem for Espeak-16Bit-Samples */ + StreamStruct->FastMemBuf1=(SHORT*)AllocMem(StreamStruct->framesPerBuffer*Pa_GetSampleSize_audev(StreamStruct->sampleFormat),MEMF_PUBLIC); + //KPrintF("Allocating %lu Bytes for FastMemBuf1, Ptr=$%08lx\n",(ULONG)StreamStruct->framesPerBuffer*Pa_GetSampleSize_audev(StreamStruct->sampleFormat),(ULONG)StreamStruct->FastMemBuf1); + if(StreamStruct->FastMemBuf1) + { + StreamStruct->FastMemBuf2=(SHORT*)AllocMem(StreamStruct->framesPerBuffer*Pa_GetSampleSize_audev(StreamStruct->sampleFormat),MEMF_PUBLIC); + if(StreamStruct->FastMemBuf2) + { + /* Allocate two audio IO Blocks */ + StreamStruct->AIOptr1=(struct IOAudio*)AllocMem(sizeof(struct IOAudio),MEMF_PUBLIC|MEMF_CLEAR); + if(StreamStruct->AIOptr1) + { + StreamStruct->AIOptr1_2=(struct IOAudio*)AllocMem(sizeof(struct IOAudio),MEMF_PUBLIC|MEMF_CLEAR); + if(StreamStruct->AIOptr1_2) + { + StreamStruct->AIOptr2=(struct IOAudio*)AllocMem(sizeof(struct IOAudio),MEMF_PUBLIC|MEMF_CLEAR); + if(StreamStruct->AIOptr2) + { + StreamStruct->AIOptr2_2=(struct IOAudio*)AllocMem(sizeof(struct IOAudio),MEMF_PUBLIC|MEMF_CLEAR); + if(StreamStruct->AIOptr2_2) + { + StreamStruct->AIOptrStartStop=(struct IOAudio*)AllocMem(sizeof(struct IOAudio),MEMF_PUBLIC|MEMF_CLEAR); + if(StreamStruct->AIOptrStartStop) + { + + StreamStruct->st = SpawnSubTask("SamAudioTask",SamAudioTask,StreamStruct); + if (StreamStruct->st) + { + Error=paNoError; + return Error; + } + Error=paInternalError; + FreeMem(StreamStruct->AIOptr2,sizeof(struct IOAudio)); + StreamStruct->AIOptr2=NULL; + } + else + { + printf(" not enough memory for allocating AIOptrStartStop\n"); + Error=paInsufficientMemory; + } + FreeMem(StreamStruct->AIOptr2_2,sizeof(struct IOAudio)); + } + else + { + printf(" not enough memory for allocating AIOptr2_2\n"); + Error=paInsufficientMemory; + } + FreeMem(StreamStruct->AIOptr2,sizeof(struct IOAudio)); + StreamStruct->AIOptr2=NULL; + } + else + { + printf(" not enough memory for allocating AIOptr2\n"); + Error=paInsufficientMemory; + } + FreeMem(StreamStruct->AIOptr1_2,sizeof(struct IOAudio)); + StreamStruct->AIOptr1_2=NULL; + + } + else + { + printf(" not enough memory for allocating AIOptr1_2\n"); + Error=paInsufficientMemory; + } + FreeMem(StreamStruct->AIOptr1,sizeof(struct IOAudio)); + StreamStruct->AIOptr1=NULL; + } + else + { + printf(" not enough memory for allocating AIOptr1\n"); + Error=paInsufficientMemory; + } + FreeMem(StreamStruct->FastMemBuf2,StreamStruct->framesPerBuffer*Pa_GetSampleSize_audev(StreamStruct->sampleFormat)); + StreamStruct->FastMemBuf2=NULL; + } + else + { + printf(" Could not allocate FastMemBuf2 (%lu Bytes)\n",StreamStruct->framesPerBuffer*Pa_GetSampleSize_audev(StreamStruct->sampleFormat)); + Error=paInsufficientMemory; + } + FreeMem(StreamStruct->FastMemBuf1,StreamStruct->framesPerBuffer*Pa_GetSampleSize_audev(StreamStruct->sampleFormat)); + StreamStruct->FastMemBuf1=NULL; + } + else + { + printf(" Could not allocate FastMemBuf1 (%lu Bytes)\n",StreamStruct->framesPerBuffer*Pa_GetSampleSize_audev(StreamStruct->sampleFormat)); + Error=paInsufficientMemory; + } + FreeMem(StreamStruct->ChipMemBuf2,StreamStruct->framesPerBuffer); + StreamStruct->ChipMemBuf2=NULL; + } + else + { + printf(" Could not allocate ChipMemBuf2 (%lu Bytes)\n",StreamStruct->framesPerBuffer); + Error=paInsufficientMemory; + } + FreeMem(StreamStruct->ChipMemBuf1,StreamStruct->framesPerBuffer); + StreamStruct->ChipMemBuf1=NULL; + } + else + { + printf(" Could not allocate ChipMemBuf1 (%lu Bytes)\n",StreamStruct->framesPerBuffer); + Error=paInsufficientMemory; + } + + free(StreamStruct); + StreamStruct=NULL; + *stream=NULL; + GlobalPaStreamPtr=NULL; /* in case of CTRL-C atexit()-Functions are void so a global pointer is needed */ + + } + else + { + printf(" not enough memory for allocating stream %u\n",StreamNr); + Error=paInsufficientMemory; + } + + } + else + { + printf("Unable to open graphics.library\n"); + Error=paInternalError; + + } + // KPrintF("Finished %s\n",__FUNCTION__); + return Error; +} + + +/* ########################################################################## */ +/* + Pa_CloseStream() closes an audio stream, flushing any pending buffers. + */ + +PaError __attribute__((no_instrument_function)) Pa_CloseStream_audev( PortAudioStream *stream ) +{ + //KPrintF("%s() called\n",__FUNCTION__); + + PortAudioStreamStruct *StreamStruct=(PortAudioStreamStruct*)stream; + + if(stream) + { + // printf(" %s called for Stream %u\n",__FUNCTION__,StreamStruct->AF_StreamID); + + if(StreamStruct->st) + { + KillSubTask(StreamStruct->st); + StreamStruct->st=NULL; + } + + if(StreamStruct->device==0) + { + CloseDevice((struct IORequest*)StreamStruct->AIOptr1); + StreamStruct->device=1; + } + + if(StreamStruct->portStartStop) + { + DeletePort(StreamStruct->portStartStop); + StreamStruct->portStartStop=0; + } + + if(StreamStruct->port2_2) + { + DeletePort(StreamStruct->port2_2); + StreamStruct->port2_2=0; + } + + + if(StreamStruct->port2) + { + DeletePort(StreamStruct->port2); + StreamStruct->port2=0; + } + + if(StreamStruct->port1_2) + { + DeletePort(StreamStruct->port1_2); + StreamStruct->port1_2=0; + } + + if(StreamStruct->port1) + { + DeletePort(StreamStruct->port1); + StreamStruct->port1=0; + } + + if(StreamStruct->AIOptrStartStop) + { + FreeMem(StreamStruct->AIOptrStartStop,sizeof(struct IOAudio)); + StreamStruct->AIOptrStartStop=NULL; + } + + if(StreamStruct->AIOptr2_2) + { + FreeMem(StreamStruct->AIOptr2_2,sizeof(struct IOAudio)); + StreamStruct->AIOptr2_2=NULL; + } + + if(StreamStruct->AIOptr2) + { + FreeMem(StreamStruct->AIOptr2,sizeof(struct IOAudio)); + StreamStruct->AIOptr2=NULL; + } + + if(StreamStruct->AIOptr1_2) + { + FreeMem(StreamStruct->AIOptr1_2,sizeof(struct IOAudio)); + StreamStruct->AIOptr1_2=NULL; + } + + if(StreamStruct->AIOptr1) + { + FreeMem(StreamStruct->AIOptr1,sizeof(struct IOAudio)); + StreamStruct->AIOptr1=NULL; + } + + if(StreamStruct->FastMemBuf2) + { + FreeMem(StreamStruct->FastMemBuf2,StreamStruct->framesPerBuffer*Pa_GetSampleSize_audev(StreamStruct->sampleFormat)); + StreamStruct->FastMemBuf2=NULL; + } + + if(StreamStruct->FastMemBuf1) + { + FreeMem(StreamStruct->FastMemBuf1,StreamStruct->framesPerBuffer*Pa_GetSampleSize_audev(StreamStruct->sampleFormat)); + StreamStruct->FastMemBuf1=NULL; + } + + + if(StreamStruct->ChipMemBuf2) + { + FreeMem(StreamStruct->ChipMemBuf2,StreamStruct->framesPerBuffer); + StreamStruct->ChipMemBuf2=NULL; + } + + if(StreamStruct->ChipMemBuf1) + { + FreeMem(StreamStruct->ChipMemBuf1,StreamStruct->framesPerBuffer); + StreamStruct->ChipMemBuf1=NULL; + } + + free(StreamStruct); + GlobalPaStreamPtr=NULL; /* in case of CTRL-C atexit()-Functions are void so a global pointer is needed */ + + + // printf(" returning paNoError\n"); + return paNoError; + } + else + { + // printf(" %s called with NULL-Ptr\n",__FUNCTION__); + // printf(" returning paBadStreamPtr\n"); + return paBadStreamPtr; // <0 is error + + } + + if(File) + { + fclose(File); + File=NULL; + } + +} + + +/* ########################################################################## */ +/* + Pa_Initialize() is the library initialisation function - call this before + using the library. + */ + + +PaError Pa_Initialize_audev( void ) +{ + int Error; + // printf(" %s called\n",__FUNCTION__); + // KPrintF("%s() called\n",__FUNCTION__); + + Error=paNoError; + + return Error; +} + + + +// ############################################################################## +// not needed by espeak but used by myself, AF 18.May2017 + +/* + Return size in bytes of a single sample in a given PaSampleFormat + or paSampleFormatNotSupported. + */ +PaError Pa_GetSampleSize_audev( PaSampleFormat format ) +{ + // KPrintF("%s() called\n",__FUNCTION__); + switch (format) + { + case paFloat32 : return 4; /*always available*/ + case paInt16 : return 2; /*always available*/ + case paInt32 : return 4; /*always available*/ + case paInt24 : return 6; + case paPackedInt24 : return 6; + case paInt8 : return 1; + case paUInt8 : return 1; /* unsigned 8 bit, 128 is "ground" */ + default : return paSampleFormatNotSupported; + } +} + + + + + +// ############################################################################## +/* reads 16Bit Signed Samples from Source and writes 8Bit Signed Smaples to Dest. */ +/* 16 Bit Samples must be BIG_ENDIAN */ +/* SampleCount Samples will be read */ +/* SampleCount must be multiple of 2 */ +/* Returns number of copied samples */ +/* AF, 15.76.2017 */ + +#ifdef HFHFHFHF +STATIC_FUNC UWORD Convert16SSamples(SHORT *Source16S, BYTE *Dest8S, ULONG SampleCount) +{ + UWORD i=0; + ULONG *SourcePtr=(ULONG*)Source16S; /* we read 2 16Bit-Samples at once */ + USHORT *DestPtr=(USHORT*)Dest8S; /* we write 2 8Bit-Samples at once */ + ULONG SourceSamples; + USHORT DestSamples; + + if(SampleCount%2) + { + printf("%s() SampleCount %lu is not even!\n",__FUNCTION__,SampleCount); + /* we read probably one bad sample but continue anyway */ + } + + for(;i>16) | ((SourceSamples &0xff00) >> 8); /* extract the two High-Bytes */ + *DestPtr++=DestSamples; + + /*printf("SourceSamples=0x%0lx, DestSamples=0x%0hx\n",SourceSamples,DestSamples);*/ + } + return i*2; +} +#else +STATIC_FUNC UWORD Convert16SSamples(SHORT *Source16S, BYTE *Dest8S, ULONG SampleCount) +{ + char *Src=(char*)Source16S; + unsigned long i; + for(i=0;i global Pointer needed */ +void __attribute__((no_instrument_function)) Abort_Pa_CloseStream_audev (void) +{ + if(GlobalPaStreamPtr) + { + // KPrintF("%s() called with Stream=$%08lx\n",__FUNCTION__,GlobalPaStreamPtr); + Pa_CloseStream_audev(GlobalPaStreamPtr); + GlobalPaStreamPtr=NULL; + } + else + { + // KPrintF("%s() called but nothing to do\n",__FUNCTION__); + } +} + + + diff --git a/src/amiga/portaudio/portaudio_audev.h b/src/amiga/portaudio/portaudio_audev.h new file mode 100644 index 0000000..065362f --- /dev/null +++ b/src/amiga/portaudio/portaudio_audev.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2017 by Alexander Fritsch * + * email: selco@t-online.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write see: * + * . * + ***************************************************************************/ +/* + * portaudio_audev.h + * + * Created on: Nov 28, 2017 + * Author: Alexander Fritsch + */ + +#ifndef SRC_AMIGA_PORTAUDIO_PORTAUDIO_AUDEV_H_ +#define SRC_AMIGA_PORTAUDIO_PORTAUDIO_AUDEV_H_ + +#include "../portaudio18.h" + +/* prototypes to be used in general portaudio.cpp only */ + +PaError Pa_StartStream_audev( PortAudioStream *stream ); +PaError Pa_AbortStream_audev( PortAudioStream *stream ); +PaError Pa_StreamActive_audev( PortAudioStream *stream ); +PaError Pa_OpenDefaultStream_audev( PortAudioStream** stream, + int numInputChannels, + int numOutputChannels, + PaSampleFormat sampleFormat, + double sampleRate, + unsigned long framesPerBuffer, + unsigned long numberOfBuffers, + PortAudioCallback *callback, + void *userData ); +PaError Pa_CloseStream_audev( PortAudioStream *stream ); +PaError Pa_Initialize_audev( void ); +PaError Pa_GetSampleSize_audev( PaSampleFormat format ); +void Abort_Pa_CloseStream_audev (void); + + + + + +#endif /* SRC_AMIGA_PORTAUDIO_PORTAUDIO_AUDEV_H_ */ diff --git a/src/amiga/portaudio/subtask_support.c b/src/amiga/portaudio/subtask_support.c new file mode 100644 index 0000000..7bd1ac8 --- /dev/null +++ b/src/amiga/portaudio/subtask_support.c @@ -0,0 +1,118 @@ +/**************************************************************/ +/* Functions for easy and secure spawning/killing of subtasks */ +/* taken from MUI subtask example - A.F. March 10th 2004 */ +/**************************************************************/ + +#include "subtask_support.h" +#include +//#include +#include +#include +#include +#include + + + + +LONG SendSubTaskMsg(struct SubTask *st,WORD command,APTR params) +{ + st->st_Message.stm_Message.mn_ReplyPort = st->st_Reply; + st->st_Message.stm_Message.mn_Length = sizeof(struct SubTaskMsg); + st->st_Message.stm_Command = command; + st->st_Message.stm_Parameter = params; + st->st_Message.stm_Result = 0; + + PutMsg(command==STC_STARTUP ? &((struct Process *)st->st_Task)->pr_MsgPort : st->st_Port,(struct Message *)&st->st_Message); + WaitPort(st->st_Reply); + GetMsg(st->st_Reply); + + return(st->st_Message.stm_Result); +} + +struct SubTask *SpawnSubTask(char *name,VOID (*func)(VOID),APTR data) +{ + struct SubTask *st; + + st = (struct SubTask*) AllocVec(sizeof(struct SubTask),MEMF_PUBLIC|MEMF_CLEAR); + if (st) + { + st->st_Reply = CreateMsgPort(); + if (st->st_Reply) + { + st->st_Data = data; + + st->st_Task = (struct Task *)CreateNewProcTags(NP_Entry,(unsigned long)func,NP_Name,(unsigned long)name,TAG_DONE); + if (st->st_Task) + { + if (SendSubTaskMsg(st,STC_STARTUP,st)) + { + return(st); + } + } + DeleteMsgPort(st->st_Reply); + } + FreeVec(st); + } + return(NULL); +} + +VOID KillSubTask(struct SubTask *st) +{ + SendSubTaskMsg(st,STC_SHUTDOWN,st); + DeleteMsgPort(st->st_Reply); + FreeVec(st); +} + +/* the following functions are called from the sub task */ + +VOID ExitSubTask(struct SubTask *st,struct SubTaskMsg *stm) +{ + /* + ** We reply after a Forbid() to make sure we're really gone + ** when the main task continues. + */ + + if (st->st_Port) + DeleteMsgPort(st->st_Port); + + Forbid(); + stm->stm_Result = FALSE; + ReplyMsg((struct Message *)stm); +} + +struct SubTask *InitSubTask(void) +{ + struct Task *me = FindTask(NULL); + struct SubTask *st; + struct SubTaskMsg *stm; + + /* + ** Wait for our startup message from the SpawnSubTask() function. + */ + + WaitPort(&((struct Process *)me)->pr_MsgPort); + stm = (struct SubTaskMsg *)GetMsg(&((struct Process *)me)->pr_MsgPort); + st = (struct SubTask *)stm->stm_Parameter; + + if ((st->st_Port = CreateMsgPort())) + { + /* + ** Reply startup message, everything ok. + ** Note that if the initialization fails, the code falls + ** through and replies the startup message with a stm_Result + ** of 0 after a Forbid(). This tells SpawnSubTask() that the + ** sub task failed to run. + */ + + stm->stm_Result = TRUE; + ReplyMsg((struct Message *)stm); + return(st); + } + else + { + ExitSubTask(st,stm); + return(NULL); + } +} + + diff --git a/src/amiga/portaudio/subtask_support.h b/src/amiga/portaudio/subtask_support.h new file mode 100644 index 0000000..9727756 --- /dev/null +++ b/src/amiga/portaudio/subtask_support.h @@ -0,0 +1,47 @@ +#ifndef __SUBTASK_SUPPORT_H__ + #define __SUBTASK_SUPPORT_H__ + +/**************************************************************/ +/* Functions for easy and secure spawning/killing of subtasks */ +/* taken from MUI subtask example - A.F. March 10th 2004 */ +/**************************************************************/ + + +#include + +struct SubTaskMsg +{ + struct Message stm_Message; + WORD stm_Command; + APTR stm_Parameter; + LONG stm_Result; +}; + +struct SubTask +{ + struct Task *st_Task; /* sub task pointer */ + struct MsgPort *st_Port; /* allocated by sub task */ + struct MsgPort *st_Reply; /* allocated by main task */ + APTR st_Data; /* more initial data to pass to the sub task */ + struct SubTaskMsg st_Message; /* Message buffer */ +}; + + +#define STC_START 0 +#define STC_STOP 1 +#define STC_STARTUP -2 +#define STC_SHUTDOWN -1 + + + +LONG SendSubTaskMsg(struct SubTask *st,WORD command,APTR params); +struct SubTask *SpawnSubTask(char *name,VOID (*func)(VOID),APTR data); +VOID KillSubTask(struct SubTask *st); + +/* the following functions are called from the sub task */ +VOID ExitSubTask(struct SubTask *st,struct SubTaskMsg *stm); +struct SubTask *InitSubTask(void); + + + +#endif diff --git a/src/amiga/portaudio18.h b/src/amiga/portaudio18.h new file mode 100644 index 0000000..2ab8e02 --- /dev/null +++ b/src/amiga/portaudio18.h @@ -0,0 +1,466 @@ +// NOTE: Copy this file to portaudio.h in order to compile with V18 portaudio + + +#ifndef PORT_AUDIO_H +#define PORT_AUDIO_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* + * $Id: portaudio.h,v 1.5 2002/03/26 18:04:22 philburk Exp $ + * PortAudio Portable Real-Time Audio Library + * PortAudio API Header File + * Latest version available at: http://www.audiomulch.com/portaudio/ + * + * Copyright (c) 1999-2000 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. + * + * 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. + * + * 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. + * + */ + +typedef int PaError; +typedef enum { + paNoError = 0, + + paHostError = -10000, + paInvalidChannelCount, + paInvalidSampleRate, + paInvalidDeviceId, + paInvalidFlag, + paSampleFormatNotSupported, + paBadIODeviceCombination, + paInsufficientMemory, + paBufferTooBig, + paBufferTooSmall, + paNullCallback, + paBadStreamPtr, + paTimedOut, + paInternalError, + paDeviceUnavailable +} PaErrorNum; + +/* + Pa_Initialize() is the library initialisation function - call this before + using the library. + +*/ + +PaError Pa_Initialize( void ); + +/* + Pa_Terminate() is the library termination function - call this after + using the library. + +*/ + +PaError Pa_Terminate( void ); + +/* + Pa_GetHostError() returns a host specific error code. + This can be called after receiving a PortAudio error code of paHostError. + +*/ + +long Pa_GetHostError( void ); + +/* + Pa_GetErrorText() translates the supplied PortAudio error number + into a human readable message. + +*/ + +const char *Pa_GetErrorText( PaError errnum ); + +/* + Sample formats + + These are formats used to pass sound data between the callback and the + stream. Each device has a "native" format which may be used when optimum + efficiency or control over conversion is required. + + Formats marked "always available" are supported (emulated) by all + PortAudio implementations. + + The floating point representation (paFloat32) uses +1.0 and -1.0 as the + maximum and minimum respectively. + + paUInt8 is an unsigned 8 bit format where 128 is considered "ground" + +*/ + +typedef unsigned long PaSampleFormat; +#define paFloat32 ((PaSampleFormat) (1<<0)) /*always available*/ +#define paInt16 ((PaSampleFormat) (1<<1)) /*always available*/ +#define paInt32 ((PaSampleFormat) (1<<2)) /*always available*/ +#define paInt24 ((PaSampleFormat) (1<<3)) +#define paPackedInt24 ((PaSampleFormat) (1<<4)) +#define paInt8 ((PaSampleFormat) (1<<5)) +#define paUInt8 ((PaSampleFormat) (1<<6)) +#define paCustomFormat ((PaSampleFormat) (1<<16)) + +/* + Device enumeration mechanism. + + Device ids range from 0 to Pa_CountDevices()-1. + + Devices may support input, output or both. + +*/ + +typedef int PaDeviceID; +#define paNoDevice -1 + +int Pa_CountDevices( void ); + +typedef struct +{ + int structVersion; + const char *name; + int maxInputChannels; + int maxOutputChannels; + /* Number of discrete rates, or -1 if range supported. */ + int numSampleRates; + /* Array of supported sample rates, or {min,max} if range supported. */ + const double *sampleRates; + PaSampleFormat nativeSampleFormats; +} +PaDeviceInfo; + +/* + Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID() return the + default device ids for input and output respectively, or paNoDevice if + no device is available. + The result can be passed to Pa_OpenStream(). + + On the PC, the user can specify a default device by + setting an environment variable. For example, to use device #1. + + set PA_RECOMMENDED_OUTPUT_DEVICE=1 + + The user should first determine the available device ids by using + the supplied application "pa_devs". + +*/ + +PaDeviceID Pa_GetDefaultInputDeviceID( void ); +PaDeviceID Pa_GetDefaultOutputDeviceID( void ); + + + +/* + Pa_GetDeviceInfo() returns a pointer to an immutable PaDeviceInfo structure + for the device specified. + If the device parameter is out of range the function returns NULL. + + PortAudio manages the memory referenced by the returned pointer, the client + must not manipulate or free the memory. The pointer is only guaranteed to be + valid between calls to Pa_Initialize() and Pa_Terminate(). + +*/ + +const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID device ); + +/* + PaTimestamp is used to represent a continuous sample clock with arbitrary + start time that can be used for syncronization. The type is used for the + outTime argument to the PortAudioCallback and as the result of Pa_StreamTime() + +*/ + +typedef double PaTimestamp; + +/* + PortAudioCallback is implemented by PortAudio clients. + + inputBuffer and outputBuffer are arrays of interleaved samples, + the format, packing and number of channels used by the buffers are + determined by parameters to Pa_OpenStream() (see below). + + framesPerBuffer is the number of sample frames to be processed by the callback. + + outTime is the time in samples when the buffer(s) processed by + this callback will begin being played at the audio output. + See also Pa_StreamTime() + + userData is the value of a user supplied pointer passed to Pa_OpenStream() + intended for storing synthesis data etc. + + return value: + The callback can return a non-zero value to stop the stream. This may be + useful in applications such as soundfile players where a specific duration + of output is required. However, it is not necessary to utilise this mechanism + as StopStream() will also terminate the stream. A callback returning a + non-zero value must fill the entire outputBuffer. + + NOTE: None of the other stream functions may be called from within the + callback function except for Pa_GetCPULoad(). + +*/ + +typedef int (PortAudioCallback)( + void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ); + + +/* + Stream flags + + These flags may be supplied (ored together) in the streamFlags argument to + the Pa_OpenStream() function. + +*/ + +#define paNoFlag (0) +#define paClipOff (1<<0) /* disable default clipping of out of range samples */ +#define paDitherOff (1<<1) /* disable default dithering */ +#define paPlatformSpecificFlags (0x00010000) +typedef unsigned long PaStreamFlags; + +/* + A single PortAudioStream provides multiple channels of real-time + input and output audio streaming to a client application. + Pointers to PortAudioStream objects are passed between PortAudio functions. +*/ + +typedef void PortAudioStream; +#define PaStream PortAudioStream + +/* + Pa_OpenStream() opens a stream for either input, output or both. + + stream is the address of a PortAudioStream pointer which will receive + a pointer to the newly opened stream. + + inputDevice is the id of the device used for input (see PaDeviceID above.) + inputDevice may be paNoDevice to indicate that an input device is not required. + + numInputChannels is the number of channels of sound to be delivered to the + callback. It can range from 1 to the value of maxInputChannels in the + PaDeviceInfo record for the device specified by the inputDevice parameter. + If inputDevice is paNoDevice numInputChannels is ignored. + + inputSampleFormat is the sample format of inputBuffer provided to the callback + function. inputSampleFormat may be any of the formats described by the + PaSampleFormat enumeration (see above). PortAudio guarantees support for + the device's native formats (nativeSampleFormats in the device info record) + and additionally 16 and 32 bit integer and 32 bit floating point formats. + Support for other formats is implementation defined. + + inputDriverInfo is a pointer to an optional driver specific data structure + containing additional information for device setup or stream processing. + inputDriverInfo is never required for correct operation. If not used + inputDriverInfo should be NULL. + + outputDevice is the id of the device used for output (see PaDeviceID above.) + outputDevice may be paNoDevice to indicate that an output device is not required. + + numOutputChannels is the number of channels of sound to be supplied by the + callback. See the definition of numInputChannels above for more details. + + outputSampleFormat is the sample format of the outputBuffer filled by the + callback function. See the definition of inputSampleFormat above for more + details. + + outputDriverInfo is a pointer to an optional driver specific data structure + containing additional information for device setup or stream processing. + outputDriverInfo is never required for correct operation. If not used + outputDriverInfo should be NULL. + + sampleRate is the desired sampleRate. For full-duplex streams it is the + sample rate for both input and output + + framesPerBuffer is the length in sample frames of all internal sample buffers + used for communication with platform specific audio routines. Wherever + possible this corresponds to the framesPerBuffer parameter passed to the + callback function. + + numberOfBuffers is the number of buffers used for multibuffered communication + with the platform specific audio routines. If you pass zero, then an optimum + value will be chosen for you internally. This parameter is provided only + as a guide - and does not imply that an implementation must use multibuffered + i/o when reliable double buffering is available (such as SndPlayDoubleBuffer() + on the Macintosh.) + + streamFlags may contain a combination of flags ORed together. + These flags modify the behaviour of the streaming process. Some flags may only + be relevant to certain buffer formats. + + callback is a pointer to a client supplied function that is responsible + for processing and filling input and output buffers (see above for details.) + + userData is a client supplied pointer which is passed to the callback + function. It could for example, contain a pointer to instance data necessary + for processing the audio buffers. + + return value: + Upon success Pa_OpenStream() returns PaNoError and places a pointer to a + valid PortAudioStream in the stream argument. The stream is inactive (stopped). + If a call to Pa_OpenStream() fails a non-zero error code is returned (see + PaError above) and the value of stream is invalid. + +*/ + +PaError Pa_OpenStream( PortAudioStream** stream, + PaDeviceID inputDevice, + int numInputChannels, + PaSampleFormat inputSampleFormat, + void *inputDriverInfo, + PaDeviceID outputDevice, + int numOutputChannels, + PaSampleFormat outputSampleFormat, + void *outputDriverInfo, + double sampleRate, + unsigned long framesPerBuffer, + unsigned long numberOfBuffers, + PaStreamFlags streamFlags, + PortAudioCallback *callback, + void *userData ); + + +/* + Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that opens + the default input and/or output devices. Most parameters have identical meaning + to their Pa_OpenStream() counterparts, with the following exceptions: + + If either numInputChannels or numOutputChannels is 0 the respective device + is not opened. This has the same effect as passing paNoDevice in the device + arguments to Pa_OpenStream(). + + sampleFormat applies to both the input and output buffers. + +*/ + +PaError Pa_OpenDefaultStream( PortAudioStream** stream, + int numInputChannels, + int numOutputChannels, + PaSampleFormat sampleFormat, + double sampleRate, + unsigned long framesPerBuffer, + unsigned long numberOfBuffers, + PortAudioCallback *callback, + void *userData ); + +/* + Pa_CloseStream() closes an audio stream, flushing any pending buffers. + +*/ + +PaError Pa_CloseStream( PortAudioStream* ); + +/* + Pa_StartStream() and Pa_StopStream() begin and terminate audio processing. + Pa_StopStream() waits until all pending audio buffers have been played. + Pa_AbortStream() stops playing immediately without waiting for pending + buffers to complete. + +*/ + +PaError Pa_StartStream( PortAudioStream *stream ); + +PaError Pa_StopStream( PortAudioStream *stream ); + +PaError Pa_AbortStream( PortAudioStream *stream ); + +/* + Pa_StreamActive() returns one (1) when the stream is active (ie playing + or recording audio), zero (0) when not playing, or a negative error number + if the stream is invalid. + The stream is active between calls to Pa_StartStream() and Pa_StopStream(), + but may also become inactive if the callback returns a non-zero value. + In the latter case, the stream is considered inactive after the last + buffer has finished playing. + +*/ + +PaError Pa_StreamActive( PortAudioStream *stream ); + +/* + Pa_StreamTime() returns the current output time in samples for the stream. + This time may be used as a time reference (for example synchronizing audio to + MIDI). + +*/ + +PaTimestamp Pa_StreamTime( PortAudioStream *stream ); + +/* + Pa_GetCPULoad() returns the CPU Load for the stream. + The "CPU Load" is a fraction of total CPU time consumed by the stream's + audio processing routines including, but not limited to the client supplied + callback. + A value of 0.5 would imply that PortAudio and the sound generating + callback was consuming roughly 50% of the available CPU time. + This function may be called from the callback function or the application. + +*/ + +double Pa_GetCPULoad( PortAudioStream* stream ); + +/* + Pa_GetMinNumBuffers() returns the minimum number of buffers required by + the current host based on minimum latency. + On the PC, for the DirectSound implementation, latency can be optionally set + by user by setting an environment variable. + For example, to set latency to 200 msec, put: + + set PA_MIN_LATENCY_MSEC=200 + + in the AUTOEXEC.BAT file and reboot. + If the environment variable is not set, then the latency will be determined + based on the OS. Windows NT has higher latency than Win95. + +*/ + +int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate ); + +/* + Pa_Sleep() puts the caller to sleep for at least 'msec' milliseconds. + You may sleep longer than the requested time so don't rely on this for + accurate musical timing. + + Pa_Sleep() is provided as a convenience for authors of portable code (such as + the tests and examples in the PortAudio distribution.) + +*/ + +void Pa_Sleep( long msec ); + +/* + Pa_GetSampleSize() returns the size in bytes of a single sample in the + supplied PaSampleFormat, or paSampleFormatNotSupported if the format is + no supported. + +*/ + +PaError Pa_GetSampleSize( PaSampleFormat format ); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PORT_AUDIO_H */ diff --git a/src/amiga/sdlwrapper.c b/src/amiga/sdlwrapper.c new file mode 100644 index 0000000..b60e94e --- /dev/null +++ b/src/amiga/sdlwrapper.c @@ -0,0 +1,142 @@ +/* AF, GWD, Nov,21 2018 */ +/* wraps certain SDL-Calls to my portaudio implementation */ + +/* leftovers from portaudio... */ +unsigned int global_benchmark_flag=0; +char *global_ProgramName="sam_globaler_name"; +unsigned int global_bufsize_factor=1; + +/************************************************************** */ +#include +#include + +#include "portaudio18.h" + +static PortAudioStream *pa_stream=NULL; + + +/************************************************************** */ + + +void SDL_CloseAudio(void) +{ + KPrintF("%s()\n",__FUNCTION__); + Pa_CloseStream(pa_stream); +} +/************************************************************** */ + +void SDL_Delay(Uint32 ms) +{ + KPrintF("%s(%ld)\n",__FUNCTION__,ms); + usleep(ms*1000); +} +/************************************************************** */ + + +char *SDL_Error_String="SDL Dummy_Error"; + +DECLSPEC char * SDL_GetError(void) +{ + KPrintF("%s()\n",__FUNCTION__); + getchar(); + return SDL_Error_String; +} +/************************************************************** */ + +//flags=SDL_INIT_AUDIO The file I/O and threading subsystems are initialized +int SDL_Init(Uint32 flags) +{ + KPrintF("%s(0x%lx)\n",__FUNCTION__,flags); + if(flags & SDL_INIT_AUDIO) + { + return Pa_Initialize(); + } + else + { + return paNoError; + } +} +/************************************************************** */ + +void (SDLCALL *SDL_CallbackFunction)(void *userdata, Uint8 *stream, int len); + +int PortAudioCallbackFunction( + void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ +KPrintF("*****************%s(%ld)*********************\n",__FUNCTION__,framesPerBuffer); + SDL_CallbackFunction(userData, outputBuffer,framesPerBuffer); + return 0; /* continue until somebody Aborts the stream */ +} + + +int SDL_OpenAudio(SDL_AudioSpec* desired, SDL_AudioSpec* obtained) +{ + PaError Error; + PaSampleFormat SampleFormat; + + KPrintF("%s()\n",__FUNCTION__); + KPrintF("channels %ld\n",desired->channels); + KPrintF("format %ld\n",desired->format); + KPrintF("freq %ld\n",desired->freq); + KPrintF("Padding %ld\n",desired->padding); + KPrintF("Samples %ld\n",desired->samples); + KPrintF("Silence %ld\n",desired->silence); + KPrintF("Size %ld\n",desired->size); + + if(desired->format!=AUDIO_U8) + { + printf("Error: only SDL-Format AUDIO_U8 supported\n"); + return paSampleFormatNotSupported; // < 0 means error + } + else + { + SampleFormat=paUInt8; + } + + SDL_CallbackFunction=desired->callback; + + + Error=Pa_OpenDefaultStream( &pa_stream, + 0, /*int numInputChannels*/ + desired->channels, + SampleFormat, + desired->freq, + desired->samples, /* unsigned long framesPerBuffer*/ + 2, /*unsigned long numberOfBuffers*/ + PortAudioCallbackFunction, /* PortAudioCallback *callback */ + desired->userdata /* void *userData*/ ); + + if(obtained) + { + *obtained=*desired; + } + + return Error; +} +/************************************************************** */ + +// 1=audio callback is stopped when this returns. 0=start ausio callback +void SDL_PauseAudio(int pause_on) +{ + KPrintF("%s(%ld)\n",__FUNCTION__,pause_on); + + if(0==pause_on) + { + Pa_StartStream(pa_stream); + } + else + { + Pa_AbortStream(pa_stream); + } + +} +/************************************************************** */ + +void SDL_Quit(void) // useful with atexit() +{ + KPrintF("%s()\n",__FUNCTION__); + + Pa_CloseStream(pa_stream); +} diff --git a/src/main.c b/src/main.c index 06fe18a..75bdf33 100644 --- a/src/main.c +++ b/src/main.c @@ -104,6 +104,9 @@ void MixAudio(void *unused, Uint8 *stream, int len) int bufferpos = GetBufferLength(); char *buffer = GetBuffer(); int i; + + KPrintF("%s(%ld) bufferpos=%ld\n",__FUNCTION__,len,bufferpos); + if (pos >= bufferpos) return; if ((bufferpos-pos) < len) len = (bufferpos-pos); for(i=0; i Date: Thu, 22 Nov 2018 14:36:26 +0100 Subject: [PATCH 04/62] added -ahi to main menu. Does not work yet. --- src/main.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 75bdf33..913e383 100644 --- a/src/main.c +++ b/src/main.c @@ -14,6 +14,13 @@ #include "endian.h" // AF, Endian +#ifdef __AMIGA__ // AF, use ahi.device instead pf audio.device + void set_ahi_devide(unsigned int unit); +#endif + +#define DBG(x) +//#define DBG(x) x + void WriteWav(char* filename, char* buffer, int bufferlength) { FILE *file = fopen(filename, "wb"); @@ -62,6 +69,9 @@ void PrintUsage() printf(" -wav filename output to wav instead of libsdl\n"); printf(" -sing special treatment of pitch\n"); printf(" -debug print additional debug messages\n"); +#ifdef __AMIGA__ + printf(" -ahi unit use Amiga AHI-device\n"); +#endif printf("\n"); @@ -105,7 +115,7 @@ void MixAudio(void *unused, Uint8 *stream, int len) char *buffer = GetBuffer(); int i; - KPrintF("%s(%ld) bufferpos=%ld\n",__FUNCTION__,len,bufferpos); + DBG(KPrintF("%s(%ld) bufferpos=%ld\n",__FUNCTION__,len,bufferpos)); if (pos >= bufferpos) return; if ((bufferpos-pos) < len) len = (bufferpos-pos); @@ -141,7 +151,6 @@ void OutputSound() while (pos < bufferpos) { - KPrintF("%s() pos=%ld bufferpos=%ld\n",__FUNCTION__,pos,bufferpos); SDL_Delay(100); } @@ -165,8 +174,10 @@ int main(int argc, char **argv) char input[256]; #ifdef USESDL +#ifndef __AMIGA__ freopen("CON", "w", stdout); freopen("CON", "w", stderr); +#endif #endif for(i=0; i<256; i++) input[i] = 0; @@ -223,6 +234,39 @@ int main(int argc, char **argv) SetThroat(atoi(argv[i+1])); i++; } else +#ifdef __AMIGA__ + if (strcmp(&argv[i][1], "ahi")==0) + { + unsigned int unit; + if(argc>i+1) + { + if(argv[i+1]) + { + unit=strtoul(argv[i+1],NULL,10); + if(unit<4) + { + set_ahi_devide(strtol(argv[i+1],NULL,10)); + } + else + { + printf("AHI-unit %d out of range (0...3)\n",unit); + return 1; + } + } + else + { + printf("AHI-unit is NULL-Ptr!\n"); + return 1; + } + } + else + { + printf("missing AHI unit\n"); + return 1; + } + i++; + } else +#endif { PrintUsage(); return 1; From 62066aa5fde397a6d91bbd9a653f70662fdd1a44 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Thu, 22 Nov 2018 16:51:44 +0100 Subject: [PATCH 05/62] renamed ahi-Audio task --- src/amiga/portaudio/portaudio_ahidev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/amiga/portaudio/portaudio_ahidev.c b/src/amiga/portaudio/portaudio_ahidev.c index b62034f..eea97b1 100644 --- a/src/amiga/portaudio/portaudio_ahidev.c +++ b/src/amiga/portaudio/portaudio_ahidev.c @@ -123,7 +123,7 @@ struct MsgPort *AHImp = NULL; extern struct Device* TimerBase; // nur zum Benchmarking static struct IORequest timereq; // nur zum Benchmarking -VOID /*__asm __saveds*/ EspeakAudioTask_AHI(VOID) +VOID /*__asm __saveds*/ SamAudioTask_AHI(VOID) { // KPrintF("%s() called\n",__FUNCTION__); @@ -639,7 +639,7 @@ PaError Pa_OpenDefaultStream_ahidev( PortAudioStream** stream, { //KPrintF("Zeile %ld\n",__LINE__); - StreamStruct->st = SpawnSubTask("EspeakAudioTask_AHI",EspeakAudioTask_AHI,StreamStruct); + StreamStruct->st = SpawnSubTask("EspeakAudioTask_AHI",SamAudioTask_AHI,StreamStruct); if (StreamStruct->st) { //KPrintF("Zeile %ld\n",__LINE__); From 72f54c0e1d2960adf23e899c96dd807f7a7cf431 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Thu, 22 Nov 2018 17:56:33 +0100 Subject: [PATCH 06/62] added a few statics to arryays to save stack. It needs arounf 1000Bytes now, so nicely fits into our default 4096 Bytes Stack --- src/main.c | 11 ++++++++--- src/render.c | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main.c b/src/main.c index 913e383..18f724f 100644 --- a/src/main.c +++ b/src/main.c @@ -14,12 +14,16 @@ #include "endian.h" // AF, Endian +#ifdef __AMIGA__ // AF, use ahi.device instead pf audio.device + #define DBG(x) x +#else + #define DBG(x) +#endif + #ifdef __AMIGA__ // AF, use ahi.device instead pf audio.device void set_ahi_devide(unsigned int unit); #endif -#define DBG(x) -//#define DBG(x) x void WriteWav(char* filename, char* buffer, int bufferlength) { @@ -171,7 +175,8 @@ int main(int argc, char **argv) int phonetic = 0; char* wavfilename = NULL; - char input[256]; + static char input[256]; // AF, save some stack + #ifdef USESDL #ifndef __AMIGA__ diff --git a/src/render.c b/src/render.c index 5d4e79d..102d4b9 100755 --- a/src/render.c +++ b/src/render.c @@ -1004,13 +1004,13 @@ void SetMouthThroat(unsigned char mouth, unsigned char throat) //unsigned char throat; //mem38881 // mouth formants (F1) 5..29 - unsigned char mouthFormants5_29[30] = { + static unsigned char mouthFormants5_29[30] = { // AF, save some stack 0, 0, 0, 0, 0, 10, 14, 19, 24, 27, 23, 21, 16, 20, 14, 18, 14, 18, 18, 16, 13, 15, 11, 18, 14, 11, 9, 6, 6, 6}; // throat formants (F2) 5..29 - unsigned char throatFormants5_29[30] = { + static unsigned char throatFormants5_29[30] = { // AF, save some stack 255, 255, 255, 255, 255, 84, 73, 67, 63, 40, 44, 31, 37, 45, 73, 49, 36, 30, 51, 37, 29, 69, 24, 50, 30, 24, 83, 46, 54, 86}; From a7ba6f841c19ecf5ad689f264b2083197337a9e8 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Fri, 23 Nov 2018 15:08:43 +0100 Subject: [PATCH 07/62] turn LP-Filter off for audio.device, convert U8-Samples for ahi.device --- src/amiga/portaudio/portaudio_ahidev.c | 19 +++++++++- src/amiga/portaudio/portaudio_audev.c | 52 +++++++++++++++++++++----- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/amiga/portaudio/portaudio_ahidev.c b/src/amiga/portaudio/portaudio_ahidev.c index eea97b1..2118381 100644 --- a/src/amiga/portaudio/portaudio_ahidev.c +++ b/src/amiga/portaudio/portaudio_ahidev.c @@ -117,6 +117,16 @@ typedef struct STATIC_FUNC ULONG getAHISampleType(PaSampleFormat format ); +void ConvertU8Samples(UBYTE *data, unsigned int SampleCount) // AHI does not support UINT8-Samples !??? +{ + unsigned long i; + for(i=0;icallback(NULL,p1,PortAudioStreamData->framesPerBuffer,0,NULL)) /* Last Buffer */ { + ConvertU8Samples(p1,PortAudioStreamData->framesPerBuffer); // AHI does not support UINT8-Samples !??? PortAudioStreamData->StreamActive=0; worktodo=FALSE; LastBuf=TRUE; @@ -336,6 +347,11 @@ VOID /*__asm __saveds*/ SamAudioTask_AHI(VOID) AHIio->ahir_Link = link; SendIO((struct IORequest *) AHIio); + if(((struct IORequest *) AHIio)->io_Error!=0) + { + printf("io_Error=%lx\n",((struct IORequest *) AHIio)->io_Error); + } + if(link) { // Wait until the last buffer is finished (== the new buffer is started) @@ -885,7 +901,8 @@ STATIC_FUNC ULONG getAHISampleType(PaSampleFormat format ) // case paInt24 : return ; // case paPackedInt24 : return ; case paInt8 : return AHIST_M8S; /* Mono, 8 bit signed (BYTE) */ - case paUInt8 : return AHIST_M8U; /* OBSOLETE! */ /* unsigned 8 bit, 128 is "ground" */ + //case paUInt8 : return AHIST_M8U; /* OBSOLETE! */ /* unsigned 8 bit, 128 is "ground" Is not supported by AHI !?*/ + case paUInt8 : return AHIST_M8S; /* set tp SIGNED 8 bit instead and convert buffer later */ default : return AHIE_BADSAMPLETYPE; /* Unknown/unsupported sample type */; } diff --git a/src/amiga/portaudio/portaudio_audev.c b/src/amiga/portaudio/portaudio_audev.c index e5e450c..258b29c 100644 --- a/src/amiga/portaudio/portaudio_audev.c +++ b/src/amiga/portaudio/portaudio_audev.c @@ -62,6 +62,33 @@ /*extern "C"*/ LONG KPrintF(STRPTR format, ...); + +#include +#define CIAA 0xBFE001 /* Address of CIAA chip */ + +// 0==bright LED, Filter=0n +// return 1 if bit is NOT set, i.e. Filter is on +unsigned int getAudioFilterState(void) +{ + struct CIA *cia = (struct CIA *) CIAA; + unsigned int Result= ((cia->ciapra ^ CIAF_LED) & CIAF_LED) ? 1: 0; +// KPrintF("Filter is %s\n",Result ? "On":"Off"); + return Result; +} + +void setAudioFilterState(unsigned int val) +{ + struct CIA *cia = (struct CIA *) CIAA; + unsigned char cia_value=cia->ciapra; + + cia_value &= ~CIAF_LED; + cia_value |= val ? 0: CIAF_LED; + cia->ciapra=cia_value; + +// KPrintF("%s(%ld) -> ",__FUNCTION__,val); + getAudioFilterState(); +} + #include static struct timeval startTime; @@ -128,7 +155,7 @@ typedef struct SHORT *FastMemBuf2; // Espeak-AudioBuffer used in Callback unsigned int LeftChannel; // left Audiochannel we got allocated in OpenDevice() or 0 unsigned int RightChannel; // right Audiochannel we got allocated in OpenDevice() or 0 - + unsigned int LP_FilterSate; // stores old state of audop LP-Filter }PortAudioStreamStruct; @@ -149,7 +176,7 @@ void SetAudioUnit(struct IOAudio *AIOptr,unsigned int Channel) } -STATIC_FUNC UWORD Convert16SSamples(SHORT *Source16S, BYTE *Dest8S, ULONG SampleCount); /* reads 16Bit Signed Samples from Source and writes 8Bit Signed Samples to Dest. DestLen Samples will be read */ +STATIC_FUNC UWORD Convert8USamples(UBYTE *Source8U, BYTE *Dest8S, ULONG SampleCount); /* reads 16Bit Signed Samples from Source and writes 8Bit Signed Samples to Dest. DestLen Samples will be read */ struct Device* TimerBase; // nur zum Benchmarking @@ -341,7 +368,7 @@ VOID /*__asm __saveds*/ SamAudioTask(VOID) /* read two buffers. cannot fail. (just end of data but that does not matter here) */ PortAudioStreamData->callback(NULL,PortAudioStreamData->FastMemBuf1,PortAudioStreamData->framesPerBuffer,0,NULL); - Convert16SSamples(PortAudioStreamData->FastMemBuf1, PortAudioStreamData->ChipMemBuf1 ,PortAudioStreamData->framesPerBuffer); + Convert8USamples(PortAudioStreamData->FastMemBuf1, PortAudioStreamData->ChipMemBuf1 ,PortAudioStreamData->framesPerBuffer); PortAudioStreamData->AIOptr1->ioa_Length=PortAudioStreamData->framesPerBuffer; PortAudioStreamData->AIOptr1->ioa_Data=(UBYTE*)PortAudioStreamData->ChipMemBuf1; @@ -351,7 +378,7 @@ VOID /*__asm __saveds*/ SamAudioTask(VOID) PortAudioStreamData->callback(NULL,PortAudioStreamData->FastMemBuf2,PortAudioStreamData->framesPerBuffer,0,NULL); - Convert16SSamples(PortAudioStreamData->FastMemBuf2, PortAudioStreamData->ChipMemBuf2 ,PortAudioStreamData->framesPerBuffer); + Convert8USamples(PortAudioStreamData->FastMemBuf2, PortAudioStreamData->ChipMemBuf2 ,PortAudioStreamData->framesPerBuffer); PortAudioStreamData->AIOptr2->ioa_Length=PortAudioStreamData->framesPerBuffer; PortAudioStreamData->AIOptr2->ioa_Data=(UBYTE*)PortAudioStreamData->ChipMemBuf2; @@ -440,7 +467,7 @@ VOID /*__asm __saveds*/ SamAudioTask(VOID) // printf("Callback() called %u, return != paContinue. End of stream.\n",count); PortAudioStreamData->StreamActive=0; worktodo=FALSE; - Convert16SSamples(FastMemBuf, ChipMemBuf ,PortAudioStreamData->framesPerBuffer); + Convert8USamples(FastMemBuf, ChipMemBuf ,PortAudioStreamData->framesPerBuffer); BeginIO((struct IORequest*)Aptr); BeginIO((Aptr==PortAudioStreamData->AIOptr1)?(struct IORequest*)PortAudioStreamData->AIOptr1_2:(struct IORequest*)PortAudioStreamData->AIOptr2_2); /* also corresponding 2. stereo-channel */ /* Wait for the last two buffers to finish */ @@ -491,7 +518,7 @@ VOID /*__asm __saveds*/ SamAudioTask(VOID) //KPrintF("Convert16SSamples($%08lx,$%08lx)\n",(ULONG)PortAudioStreamData->FastMemBuf1, (ULONG)PortAudioStreamData->ChipMemBuf1); //fwrite(PortAudioStreamData->FastMemBuf1,PortAudioStreamData->framesPerBuffer,1,File); - Convert16SSamples(FastMemBuf, ChipMemBuf ,PortAudioStreamData->framesPerBuffer); + Convert8USamples(FastMemBuf, ChipMemBuf ,PortAudioStreamData->framesPerBuffer); // fwrite(PortAudioStreamData->ChipMemBuf1,PortAudioStreamData->framesPerBuffer,1,File); BeginIO((struct IORequest*)Aptr); BeginIO((Aptr==PortAudioStreamData->AIOptr1)?(struct IORequest*)PortAudioStreamData->AIOptr1_2:(struct IORequest*)PortAudioStreamData->AIOptr2_2); /* also corresponding 2. stereo-channel */ @@ -837,6 +864,10 @@ PaError Pa_OpenDefaultStream_audev( PortAudioStream** stream, if(StreamStruct->AIOptrStartStop) { + StreamStruct->LP_FilterSate=getAudioFilterState(); // read current state of LP-Filter + setAudioFilterState(0); // turn Filter off + + StreamStruct->st = SpawnSubTask("SamAudioTask",SamAudioTask,StreamStruct); if (StreamStruct->st) { @@ -1054,6 +1085,8 @@ PaError __attribute__((no_instrument_function)) Pa_CloseStream_audev( PortAudioS StreamStruct->ChipMemBuf1=NULL; } + setAudioFilterState(StreamStruct->LP_FilterSate); // set last state of LP-Filter again + free(StreamStruct); GlobalPaStreamPtr=NULL; /* in case of CTRL-C atexit()-Functions are void so a global pointer is needed */ @@ -1134,7 +1167,7 @@ PaError Pa_GetSampleSize_audev( PaSampleFormat format ) /* AF, 15.76.2017 */ #ifdef HFHFHFHF -STATIC_FUNC UWORD Convert16SSamples(SHORT *Source16S, BYTE *Dest8S, ULONG SampleCount) +STATIC_FUNC UWORD Convert8USamples(SHORT *Source16S, BYTE *Dest8S, ULONG SampleCount) { UWORD i=0; ULONG *SourcePtr=(ULONG*)Source16S; /* we read 2 16Bit-Samples at once */ @@ -1159,13 +1192,12 @@ STATIC_FUNC UWORD Convert16SSamples(SHORT *Source16S, BYTE *Dest8S, ULONG Sample return i*2; } #else -STATIC_FUNC UWORD Convert16SSamples(SHORT *Source16S, BYTE *Dest8S, ULONG SampleCount) +STATIC_FUNC UWORD Convert8USamples(UBYTE *Source8U, BYTE *Dest8S, ULONG SampleCount) { - char *Src=(char*)Source16S; unsigned long i; for(i=0;i Date: Fri, 23 Nov 2018 16:07:11 +0100 Subject: [PATCH 08/62] avoid hiss at the end of sound playback by clearing buffer --- src/sam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sam.c b/src/sam.c index 2334bdd..a2e3001 100644 --- a/src/sam.c +++ b/src/sam.c @@ -93,7 +93,7 @@ void Init() bufferpos = 0; // TODO, check for free the memory, 10 seconds of output should be more than enough buffer = malloc(22050*10); - + memset(buffer,128,22050*10); //AF: avoid "hiss" at the end of sound playback /* freq2data = &mem[45136]; freq1data = &mem[45056]; From 3785767e1e5a61996a7d224a8eac569b59cdbd51 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Fri, 23 Nov 2018 16:21:18 +0100 Subject: [PATCH 09/62] fixed u8 to i8 sample conversion for AHI --- src/amiga/portaudio/portaudio_ahidev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/amiga/portaudio/portaudio_ahidev.c b/src/amiga/portaudio/portaudio_ahidev.c index 2118381..71a048d 100644 --- a/src/amiga/portaudio/portaudio_ahidev.c +++ b/src/amiga/portaudio/portaudio_ahidev.c @@ -122,7 +122,8 @@ void ConvertU8Samples(UBYTE *data, unsigned int SampleCount) // AHI does not sup unsigned long i; for(i=0;iframesPerBuffer); // AHI does not support UINT8-Samples !??? LastBuf=FALSE; } From 8d321f44bcf9fc772735806014782f3e445b21dd Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Fri, 23 Nov 2018 18:26:12 +0100 Subject: [PATCH 10/62] commented debug-prints to the serial console --- Makefile.amiga | 4 ++-- src/amiga/portaudio/portaudio_audev.c | 2 +- src/amiga/sdlwrapper.c | 30 +++++++++++++-------------- src/main.c | 10 +-------- 4 files changed, 19 insertions(+), 27 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index f5e01b2..9488cc3 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -3,8 +3,8 @@ OBJS = reciter.o sam.o render.o main.o debug.o endian.o sdlwrapper.o portaudio_a CC = ~/opt/m68k-amigaos_14Nov18/bin/m68k-amigaos-gcc #gcc -CFLAGS = -DPLATFORM_IS_BIG_ENDIAN -DSTATIC_FUNC= -Iamiga/ -Iamiga/portaudio/ -I. -Wall -Os -noixemul -g -DUSESDL -I/home/osboxes/opt/m68k-amigaos_14Nov18/include/SDL #`sdl-config --cflags` -LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace -ldebug #-lSDL #`sdl-config --libs` +CFLAGS = -DPLATFORM_IS_BIG_ENDIAN -DSTATIC_FUNC= -Iamiga/ -Iamiga/portaudio/ -I. -Wall -Os -fomit-frame-pointer -noixemul -g -DUSESDL -I/home/osboxes/opt/m68k-amigaos_14Nov18/include/SDL #`sdl-config --cflags` +LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace # -ldebug #-lSDL #`sdl-config --libs` # no libsdl present #CFLAGS = -DPLATFORM_IS_BIG_ENDIAN -DSTATIC_FUNC= -Iamiga/ -Iamiga/portaudio/ -I. -Wall -Os -noixemul -g diff --git a/src/amiga/portaudio/portaudio_audev.c b/src/amiga/portaudio/portaudio_audev.c index 258b29c..d90cf14 100644 --- a/src/amiga/portaudio/portaudio_audev.c +++ b/src/amiga/portaudio/portaudio_audev.c @@ -761,7 +761,7 @@ PaError Pa_OpenDefaultStream_audev( PortAudioStream** stream, void *userData ) { - KPrintF("%s() called\n",__FUNCTION__); +// KPrintF("%s() called\n",__FUNCTION__); // KPrintF("%s() called\n",__FUNCTION__); /* File=fopen("Samples","w"); diff --git a/src/amiga/sdlwrapper.c b/src/amiga/sdlwrapper.c index b60e94e..d9dde3c 100644 --- a/src/amiga/sdlwrapper.c +++ b/src/amiga/sdlwrapper.c @@ -20,14 +20,14 @@ static PortAudioStream *pa_stream=NULL; void SDL_CloseAudio(void) { - KPrintF("%s()\n",__FUNCTION__); +// KPrintF("%s()\n",__FUNCTION__); Pa_CloseStream(pa_stream); } /************************************************************** */ void SDL_Delay(Uint32 ms) { - KPrintF("%s(%ld)\n",__FUNCTION__,ms); +// KPrintF("%s(%ld)\n",__FUNCTION__,ms); usleep(ms*1000); } /************************************************************** */ @@ -37,7 +37,7 @@ char *SDL_Error_String="SDL Dummy_Error"; DECLSPEC char * SDL_GetError(void) { - KPrintF("%s()\n",__FUNCTION__); +// KPrintF("%s()\n",__FUNCTION__); getchar(); return SDL_Error_String; } @@ -46,7 +46,7 @@ DECLSPEC char * SDL_GetError(void) //flags=SDL_INIT_AUDIO The file I/O and threading subsystems are initialized int SDL_Init(Uint32 flags) { - KPrintF("%s(0x%lx)\n",__FUNCTION__,flags); +// KPrintF("%s(0x%lx)\n",__FUNCTION__,flags); if(flags & SDL_INIT_AUDIO) { return Pa_Initialize(); @@ -65,7 +65,7 @@ int PortAudioCallbackFunction( unsigned long framesPerBuffer, PaTimestamp outTime, void *userData ) { -KPrintF("*****************%s(%ld)*********************\n",__FUNCTION__,framesPerBuffer); +//KPrintF("*****************%s(%ld)*********************\n",__FUNCTION__,framesPerBuffer); SDL_CallbackFunction(userData, outputBuffer,framesPerBuffer); return 0; /* continue until somebody Aborts the stream */ } @@ -76,14 +76,14 @@ int SDL_OpenAudio(SDL_AudioSpec* desired, SDL_AudioSpec* obtained) PaError Error; PaSampleFormat SampleFormat; - KPrintF("%s()\n",__FUNCTION__); - KPrintF("channels %ld\n",desired->channels); - KPrintF("format %ld\n",desired->format); - KPrintF("freq %ld\n",desired->freq); - KPrintF("Padding %ld\n",desired->padding); - KPrintF("Samples %ld\n",desired->samples); - KPrintF("Silence %ld\n",desired->silence); - KPrintF("Size %ld\n",desired->size); +// KPrintF("%s()\n",__FUNCTION__); +// KPrintF("channels %ld\n",desired->channels); +// KPrintF("format %ld\n",desired->format); +// KPrintF("freq %ld\n",desired->freq); +// KPrintF("Padding %ld\n",desired->padding); +// KPrintF("Samples %ld\n",desired->samples); +// KPrintF("Silence %ld\n",desired->silence); +// KPrintF("Size %ld\n",desired->size); if(desired->format!=AUDIO_U8) { @@ -120,7 +120,7 @@ int SDL_OpenAudio(SDL_AudioSpec* desired, SDL_AudioSpec* obtained) // 1=audio callback is stopped when this returns. 0=start ausio callback void SDL_PauseAudio(int pause_on) { - KPrintF("%s(%ld)\n",__FUNCTION__,pause_on); +// KPrintF("%s(%ld)\n",__FUNCTION__,pause_on); if(0==pause_on) { @@ -136,7 +136,7 @@ void SDL_PauseAudio(int pause_on) void SDL_Quit(void) // useful with atexit() { - KPrintF("%s()\n",__FUNCTION__); +// KPrintF("%s()\n",__FUNCTION__); Pa_CloseStream(pa_stream); } diff --git a/src/main.c b/src/main.c index 18f724f..46db450 100644 --- a/src/main.c +++ b/src/main.c @@ -14,13 +14,7 @@ #include "endian.h" // AF, Endian -#ifdef __AMIGA__ // AF, use ahi.device instead pf audio.device - #define DBG(x) x -#else - #define DBG(x) -#endif - -#ifdef __AMIGA__ // AF, use ahi.device instead pf audio.device +#ifdef __AMIGA__ // AF, use ahi.device instead of audio.device void set_ahi_devide(unsigned int unit); #endif @@ -119,8 +113,6 @@ void MixAudio(void *unused, Uint8 *stream, int len) char *buffer = GetBuffer(); int i; - DBG(KPrintF("%s(%ld) bufferpos=%ld\n",__FUNCTION__,len,bufferpos)); - if (pos >= bufferpos) return; if ((bufferpos-pos) < len) len = (bufferpos-pos); for(i=0; i Date: Sat, 24 Nov 2018 00:02:26 +0100 Subject: [PATCH 11/62] added toolchain version info to executable --- Makefile.amiga | 19 ++++++++++++------- src/main.c | 5 +++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index 9488cc3..5ac6c9d 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -1,14 +1,18 @@ -OBJS = reciter.o sam.o render.o main.o debug.o endian.o sdlwrapper.o portaudio_ahidev.o portaudio_audev.o portaudio.o subtask_support.o +OBJS = reciter.o sam.o render.o main.o debug.o endian.o sdlwrapper.o portaudio_ahidev.o portaudio_audev.o portaudio.o subtask_support.o amiga_version.o -CC = ~/opt/m68k-amigaos_14Nov18/bin/m68k-amigaos-gcc #gcc +COMPILER_DIR = ~/opt/m68k-amigaos_14Nov18/bin +CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc +TOOLCHAIN_VER=$(shell cat $(COMPILER_DIR)/toolchain_commit.txt) -CFLAGS = -DPLATFORM_IS_BIG_ENDIAN -DSTATIC_FUNC= -Iamiga/ -Iamiga/portaudio/ -I. -Wall -Os -fomit-frame-pointer -noixemul -g -DUSESDL -I/home/osboxes/opt/m68k-amigaos_14Nov18/include/SDL #`sdl-config --cflags` -LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace # -ldebug #-lSDL #`sdl-config --libs` -# no libsdl present -#CFLAGS = -DPLATFORM_IS_BIG_ENDIAN -DSTATIC_FUNC= -Iamiga/ -Iamiga/portaudio/ -I. -Wall -Os -noixemul -g -#LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace +CFLAGS = -DDATE="\"$(shell /bin/date +'%d.%m.%Y')\"" +CFLAGS += -DPLATFORM_IS_BIG_ENDIAN -DSTATIC_FUNC= -DUSESDL +CFLAGS += -DTOOLCHAIN_VER="\"$(TOOLCHAIN_VER)\"" +CFLAGS += -Iamiga/ -Iamiga/portaudio/ -I. -I/home/osboxes/opt/m68k-amigaos_14Nov18/include/SDL +CFLAGS += -Wall -Os -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` + +LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace # -ldebug #-lSDL #`sdl-config --libs` vpath sdlwrapper.c src/amiga/ vpath portaudio.c src/amiga/portaudio/ @@ -16,6 +20,7 @@ vpath portaudio_ahidev.c src/amiga/portaudio/ vpath portaudio_audev.c src/amiga/portaudio/ vpath portaudio.c src/amiga/portaudio/ vpath subtask_support.c src/amiga/portaudio/ +vpath amiga_version.c src/amiga/version/ sam: $(OBJS) diff --git a/src/main.c b/src/main.c index 46db450..6e9cf43 100644 --- a/src/main.c +++ b/src/main.c @@ -239,10 +239,11 @@ int main(int argc, char **argv) { if(argv[i+1]) { - unit=strtoul(argv[i+1],NULL,10); + //unit=strtoul(argv[i+1],NULL,10); + unit=atoi(argv[i+1]); if(unit<4) { - set_ahi_devide(strtol(argv[i+1],NULL,10)); + set_ahi_devide(unit); } else { From 3384b9fcc998cc0ea176bd95c60f3d0cfd1c26b3 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Sat, 24 Nov 2018 00:04:14 +0100 Subject: [PATCH 12/62] fixed enforcerhit (double close of sound task), removed debug-getchar() --- src/amiga/sdlwrapper.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/amiga/sdlwrapper.c b/src/amiga/sdlwrapper.c index d9dde3c..0206516 100644 --- a/src/amiga/sdlwrapper.c +++ b/src/amiga/sdlwrapper.c @@ -38,7 +38,6 @@ char *SDL_Error_String="SDL Dummy_Error"; DECLSPEC char * SDL_GetError(void) { // KPrintF("%s()\n",__FUNCTION__); - getchar(); return SDL_Error_String; } /************************************************************** */ @@ -137,6 +136,4 @@ void SDL_PauseAudio(int pause_on) void SDL_Quit(void) // useful with atexit() { // KPrintF("%s()\n",__FUNCTION__); - - Pa_CloseStream(pa_stream); } From 4a785c89d39c5c9d7bad5ee16411f5f987492726 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Sun, 25 Nov 2018 13:22:47 +0100 Subject: [PATCH 13/62] speed results --- AF_readme | 17 +++++++++++++++++ Makefile.amiga | 11 ++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/AF_readme b/AF_readme index 3b955e3..e17a078 100644 --- a/AF_readme +++ b/AF_readme @@ -41,3 +41,20 @@ ohne SDL (gestripped) 44 kBytes mit SDL (gestripped) 256 kBytes ! Der linkt alles moegliche ran, z.B. sind Youstick-Meldungen im Executable... + +24.11.2018 +---------- +Inzwischen geht alles mit eigenem SDL->Portaudio-Wrapper. +CTRL-C Behandlung feht noch. + +gcovr --object-directory=. -r . --html --html-details -o coverage.html + +25.11.2018 +---------- +Auf nackten Amigas is SAM sehr langsam! + +sam Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0 +A2000, 7MHz, 68000 -> 49Sekunden bis Ton kommt +A1200, 14MHz, 68020 -> 16 Sekunden bis Ton kommt +A1200, 14MHz, 68020, compiliert fuer 68020 -> 13 Sekunden bis Ton kommt + diff --git a/Makefile.amiga b/Makefile.amiga index 5ac6c9d..efe3491 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -5,15 +5,24 @@ CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc TOOLCHAIN_VER=$(shell cat $(COMPILER_DIR)/toolchain_commit.txt) +CPUFLAGS=-m68000 CFLAGS = -DDATE="\"$(shell /bin/date +'%d.%m.%Y')\"" CFLAGS += -DPLATFORM_IS_BIG_ENDIAN -DSTATIC_FUNC= -DUSESDL CFLAGS += -DTOOLCHAIN_VER="\"$(TOOLCHAIN_VER)\"" CFLAGS += -Iamiga/ -Iamiga/portaudio/ -I. -I/home/osboxes/opt/m68k-amigaos_14Nov18/include/SDL -CFLAGS += -Wall -Os -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` +CFLAGS += $(CPUFLAGS) +CFLAGS += -Wall -O2 -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace # -ldebug #-lSDL #`sdl-config --libs` +#coverage +#CFLAGS += -fprofile-generate=VBox:$(shell pwd | cut -c2-) # remove first "/" from pwd -> VBox:home/... +#CFLAGS += -ftest-coverage +#CFLAGS += -fprofile-arcs #-pg # Profiler +#LFLAGS += -lgcov + + vpath sdlwrapper.c src/amiga/ vpath portaudio.c src/amiga/portaudio/ vpath portaudio_ahidev.c src/amiga/portaudio/ From c1b22bad8a7698a0aa7d11a374a98a55ee643028 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Sun, 25 Nov 2018 13:49:09 +0100 Subject: [PATCH 14/62] added amiga_version.c, extended .gitignore --- .gitignore | 6 ++++ src/amiga/version/amiga_version.c | 54 +++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 src/amiga/version/amiga_version.c diff --git a/.gitignore b/.gitignore index 268104a..12b3b75 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,9 @@ .DS_Store *.o /sam +*.gcno +*.gcda +*.wav +*.html +*.lha +*.map diff --git a/src/amiga/version/amiga_version.c b/src/amiga/version/amiga_version.c new file mode 100644 index 0000000..f8d843a --- /dev/null +++ b/src/amiga/version/amiga_version.c @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2018 by Alexander Fritsch * + * email: selco@t-online.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write see: * + * . * + ***************************************************************************/ + +#ifdef mc68060 +#define __CPU__ "mc68060" +#elif defined mc68040 +#define __CPU__ "mc68040" +#elif defined mc68030 +#define __CPU__ "mc68030" +#elif defined mc68020 +#define __CPU__ "mc68020" +#elif defined mc68000 +#define __CPU__ "mc68000" +#else +#define __CPU__ "???????" +#endif + +#ifdef __HAVE_68881__ +#define __FPU__ "+mc68881" +#else +#define __FPU__ "" +#endif + + + +#define VERSION "1" +#define REVISION "1" /* Revision always starts with 1 ! */ +//#define DATE "15.07.2017" /* comes from make-command line as CXXFLAGS+=-DDATE=\\\"$(date +'%d.%m.%Y')\\\" */ +#define PROGNAME "sam" +#define COMMENT "BETA-Version, Alexander Fritsch, selco, based on SAM C-conversion by Sebastian Macke" +//#define COMMENT "Alexander Fritsch, selco, based on SAM C-conversion by Sebastian Macke" + +#define VERS PROGNAME" " VERSION "." REVISION +#define VERSTAG "\0$VER: " PROGNAME " " VERSION "." REVISION " (" DATE ") " COMMENT ", compiled for " __CPU__ __FPU__ + +char versiontag[] = VERSTAG; + +char toolchain_ver[] = "\0$TOOLCHAIN_VER: " TOOLCHAIN_VER; /* This macro comes from Makefile.amiga and contains git hash */ From c00920543a53632e3afb51f97a3c3474d2664f6c Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Sun, 25 Nov 2018 17:36:13 +0100 Subject: [PATCH 15/62] benchmarking Results with different optimizations and with and without old render.c --- AF_readme | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/AF_readme b/AF_readme index e17a078..e2d706d 100644 --- a/AF_readme +++ b/AF_readme @@ -53,8 +53,33 @@ gcovr --object-directory=. -r . --html --html-details -o coverage.html ---------- Auf nackten Amigas is SAM sehr langsam! -sam Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0 -A2000, 7MHz, 68000 -> 49Sekunden bis Ton kommt -A1200, 14MHz, 68020 -> 16 Sekunden bis Ton kommt -A1200, 14MHz, 68020, compiliert fuer 68020 -> 13 Sekunden bis Ton kommt +sam_old_render_O2 67564 ----rwed Heute 17:30:44 +sam_Os 57576 ----rwed Heute 17:30:41 +sam_O3 73528 ----rwed Heute 17:30:38 +sam_old_render_Os 57760 ----rwed Heute 17:30:36 +sam_O2 66800 ----rwed Heute 17:30:34 + +A2000 +8.Ram Disk:> ; sam_Os 49 +8.Ram Disk:> ; sam_O2 44 +8.Ram Disk:> ; sam_O3 41 +8.Ram Disk:> ; sam_old_render_Os 32 +8.Ram Disk:> ; sam_old_render_O2 30 +8.Ram Disk:> ; sam_old_render_O3 28 +8.Ram Disk:> ; +8.Ram Disk:> ; sam_O2 Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0 +8.Ram Disk:> +8.Ram Disk:> + +A1200, no FastMem +sam_Os 15s +sam_O2 14s +sam_O3 14s +sam_old_render_Os 10s +sam_old_render_O2 8s +sam_old_render_O3 8s + +Die alte Renderfunktion mit multable und 4 Bit bekomme ich mit +git checkout 760786f13b79ddf5b519131925863181d224b839 src/RenderTabs.h +git checkout 760786f13b79ddf5b519131925863181d224b839 src/render.c From 438c69a9652ebb9234f16016bc77923b94c927b7 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Mon, 26 Nov 2018 18:33:05 +0100 Subject: [PATCH 16/62] profiling tests --- AF_readme | 6 ++++++ Makefile.amiga | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/AF_readme b/AF_readme index e2d706d..32d5de1 100644 --- a/AF_readme +++ b/AF_readme @@ -83,3 +83,9 @@ Die alte Renderfunktion mit multable und 4 Bit bekomme ich mit git checkout 760786f13b79ddf5b519131925863181d224b839 src/RenderTabs.h git checkout 760786f13b79ddf5b519131925863181d224b839 src/render.c + +Profiling +,it -pg linken und uebersetzen +/home/osboxes/opt/m68k-amigaos_14Nov18/bin/m68k-amigaos-gprof sam | gprof2dot -n0 -e0 | dot -Tsvg -o output.svg +mirage output.svg & + diff --git a/Makefile.amiga b/Makefile.amiga index efe3491..0171ac9 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -12,7 +12,7 @@ CFLAGS += -DPLATFORM_IS_BIG_ENDIAN -DSTATIC_FUNC= -DUSESDL CFLAGS += -DTOOLCHAIN_VER="\"$(TOOLCHAIN_VER)\"" CFLAGS += -Iamiga/ -Iamiga/portaudio/ -I. -I/home/osboxes/opt/m68k-amigaos_14Nov18/include/SDL CFLAGS += $(CPUFLAGS) -CFLAGS += -Wall -O2 -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` +CFLAGS += -Wall -O3 -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace # -ldebug #-lSDL #`sdl-config --libs` @@ -21,6 +21,8 @@ LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace # -ldebug #-lSDL #`sdl-config -- #CFLAGS += -ftest-coverage #CFLAGS += -fprofile-arcs #-pg # Profiler #LFLAGS += -lgcov +CFLAGS += -pg -fno-omit-frame-pointer +LFLAGS += -pg vpath sdlwrapper.c src/amiga/ From 8bfe42d24b24b53a5b7fca9974e5df83c40977fa Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Tue, 4 Dec 2018 21:49:28 +0100 Subject: [PATCH 17/62] playing with the profiler --- Makefile.amiga | 9 +++++---- src/main.c | 4 +++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index 0171ac9..9327c99 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -1,7 +1,8 @@ OBJS = reciter.o sam.o render.o main.o debug.o endian.o sdlwrapper.o portaudio_ahidev.o portaudio_audev.o portaudio.o subtask_support.o amiga_version.o -COMPILER_DIR = ~/opt/m68k-amigaos_14Nov18/bin -CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc +COMPILER_INSTALL_DIR = /home/osboxes/opt/m68k-amigaos_30Nov18 +COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin +CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc TOOLCHAIN_VER=$(shell cat $(COMPILER_DIR)/toolchain_commit.txt) @@ -10,9 +11,9 @@ CPUFLAGS=-m68000 CFLAGS = -DDATE="\"$(shell /bin/date +'%d.%m.%Y')\"" CFLAGS += -DPLATFORM_IS_BIG_ENDIAN -DSTATIC_FUNC= -DUSESDL CFLAGS += -DTOOLCHAIN_VER="\"$(TOOLCHAIN_VER)\"" -CFLAGS += -Iamiga/ -Iamiga/portaudio/ -I. -I/home/osboxes/opt/m68k-amigaos_14Nov18/include/SDL +CFLAGS += -Iamiga/ -Iamiga/portaudio/ -I. -I$(COMPILER_INSTALL_DIR)/include/SDL CFLAGS += $(CPUFLAGS) -CFLAGS += -Wall -O3 -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` +CFLAGS += -Wall -O2 -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace # -ldebug #-lSDL #`sdl-config --libs` diff --git a/src/main.c b/src/main.c index 6e9cf43..485a9ca 100644 --- a/src/main.c +++ b/src/main.c @@ -14,6 +14,7 @@ #include "endian.h" // AF, Endian +#include // AF, Test #ifdef __AMIGA__ // AF, use ahi.device instead of audio.device void set_ahi_devide(unsigned int unit); #endif @@ -169,6 +170,7 @@ int main(int argc, char **argv) char* wavfilename = NULL; static char input[256]; // AF, save some stack + time_t StartZeit=time(NULL); #ifdef USESDL #ifndef __AMIGA__ @@ -306,7 +308,7 @@ int main(int argc, char **argv) PrintUsage(); return 1; } - +printf("Sound berechnung nach %lld Sekunden\n",time(NULL)-StartZeit); if (wavfilename != NULL) WriteWav(wavfilename, GetBuffer(), GetBufferLength()/50); else From 8b6f7feeef84bffc2ef638ddf1e37a9d313032e3 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Tue, 4 Dec 2018 22:26:50 +0100 Subject: [PATCH 18/62] use old RenderTabs.h and render.c again because they are much faster --- AF_readme | 12 + src/RenderTabs.h | 749 +++++++++++++++-------------- src/render.c | 1174 +++++++++++++++++++++++----------------------- 3 files changed, 999 insertions(+), 936 deletions(-) diff --git a/AF_readme b/AF_readme index 32d5de1..1a0455c 100644 --- a/AF_readme +++ b/AF_readme @@ -89,3 +89,15 @@ Profiling /home/osboxes/opt/m68k-amigaos_14Nov18/bin/m68k-amigaos-gprof sam | gprof2dot -n0 -e0 | dot -Tsvg -o output.svg mirage output.svg & +4.Dec.2018 +---------- +Die alten Versionen von RenderTabs.h und render.c jetzt wieder hergestellt wie am 25.11. getestet. +Damit steigt die Geschwindigkeit deutlich an. + +Neue Funktionen : 46 Sekunden +alte Funktionen : 30 Sekunden + +Fuer +gprof test | gprof2dot -n0 -e0 | dot -Tpng -o output2.png && mirage output2.png +(gemessen ohne Soundausgabe oder Wave-File-schreiben, compiliert mit -O2, -pg und auf WinUAE Cycleexact A500 getestet) + diff --git a/src/RenderTabs.h b/src/RenderTabs.h index 1dda228..4989a86 100755 --- a/src/RenderTabs.h +++ b/src/RenderTabs.h @@ -1,69 +1,69 @@ #ifndef RENDERTABS_H #define RENDERTABS_H -const unsigned char tab48426[5] = { 0x18, 0x1A, 0x17, 0x17, 0x17 }; +unsigned char tab48426[5] = { 0x18, 0x1A, 0x17, 0x17, 0x17 }; -const unsigned char tab47492[] = +unsigned char tab47492[] = { - 0 , 0 , 0xE0 , 0xE6 , 0xEC , 0xF3 , 0xF9 , 0 , - 6 , 0xC , 6 + 0 , 0 , 0xE0 , 0xE6 , 0xEC , 0xF3 , 0xF9 , 0 , + 6 , 0xC , 6 }; -const unsigned char amplitudeRescale[] = +unsigned char amplitudeRescale[] = { - 0 , 1 , 2 , 2 , 2 , 3 , 3 , 4 , - 4 , 5 , 6 , 8 , 9 ,0xB ,0xD ,0xF, 0 //17 elements? + 0 , 1 , 2 , 2 , 2 , 3 , 3 , 4 , + 4 , 5 , 6 , 8 , 9 ,0xB ,0xD ,0xF, 0 //17 elements? }; // Used to decide which phoneme's blend lengths. The candidate with the lower score is selected. // tab45856 -const unsigned char blendRank[] = +unsigned char blendRank[] = { - 0 , 0x1F , 0x1F , 0x1F , 0x1F , 2 , 2 , 2 , - 2 , 2 , 2 , 2 , 2 , 2 , 5 , 5 , - 2 ,0xA , 2 , 8 , 5 , 5 ,0xB ,0xA , - 9 , 8 , 8 , 0xA0 , 8 , 8 , 0x17 , 0x1F , - 0x12 , 0x12 , 0x12 , 0x12 , 0x1E , 0x1E , 0x14 , 0x14 , - 0x14 , 0x14 , 0x17 , 0x17 , 0x1A , 0x1A , 0x1D , 0x1D , - 2 , 2 , 2 , 2 , 2 , 2 , 0x1A , 0x1D , - 0x1B , 0x1A , 0x1D , 0x1B , 0x1A , 0x1D , 0x1B , 0x1A , - 0x1D , 0x1B , 0x17 , 0x1D , 0x17 , 0x17 , 0x1D , 0x17 , - 0x17 , 0x1D , 0x17 , 0x17 , 0x1D , 0x17 , 0x17 , 0x17 + 0 , 0x1F , 0x1F , 0x1F , 0x1F , 2 , 2 , 2 , + 2 , 2 , 2 , 2 , 2 , 2 , 5 , 5 , + 2 ,0xA , 2 , 8 , 5 , 5 ,0xB ,0xA , + 9 , 8 , 8 , 0xA0 , 8 , 8 , 0x17 , 0x1F , + 0x12 , 0x12 , 0x12 , 0x12 , 0x1E , 0x1E , 0x14 , 0x14 , + 0x14 , 0x14 , 0x17 , 0x17 , 0x1A , 0x1A , 0x1D , 0x1D , + 2 , 2 , 2 , 2 , 2 , 2 , 0x1A , 0x1D , + 0x1B , 0x1A , 0x1D , 0x1B , 0x1A , 0x1D , 0x1B , 0x1A , + 0x1D , 0x1B , 0x17 , 0x1D , 0x17 , 0x17 , 0x1D , 0x17 , + 0x17 , 0x1D , 0x17 , 0x17 , 0x1D , 0x17 , 0x17 , 0x17 }; // Number of frames at the end of a phoneme devoted to interpolating to next phoneme's final value //tab45696 -const unsigned char outBlendLength[] = +unsigned char outBlendLength[] = { - 0 , 2 , 2 , 2 , 2 , 4 , 4 , 4 , - 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , - 4 , 4 , 3 , 2 , 4 , 4 , 2 , 2 , - 2 , 2 , 2 , 1 , 1 , 1 , 1 , 1 , - 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 , - 2 , 1 , 0 , 1 , 0 , 1 , 0 , 5 , - 5 , 5 , 5 , 5 , 4 , 4 , 2 , 0 , - 1 , 2 , 0 , 1 , 2 , 0 , 1 , 2 , - 0 , 1 , 2 , 0 , 2 , 2 , 0 , 1 , - 3 , 0 , 2 , 3 , 0 , 2 , 0xA0 , 0xA0 + 0 , 2 , 2 , 2 , 2 , 4 , 4 , 4 , + 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , + 4 , 4 , 3 , 2 , 4 , 4 , 2 , 2 , + 2 , 2 , 2 , 1 , 1 , 1 , 1 , 1 , + 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 , + 2 , 1 , 0 , 1 , 0 , 1 , 0 , 5 , + 5 , 5 , 5 , 5 , 4 , 4 , 2 , 0 , + 1 , 2 , 0 , 1 , 2 , 0 , 1 , 2 , + 0 , 1 , 2 , 0 , 2 , 2 , 0 , 1 , + 3 , 0 , 2 , 3 , 0 , 2 , 0xA0 , 0xA0 }; // Number of frames at beginning of a phoneme devoted to interpolating to phoneme's final value // tab45776 -const unsigned char inBlendLength[] = +unsigned char inBlendLength[] = { - 0 , 2 , 2 , 2 , 2 , 4 , 4 , 4 , - 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , - 4 , 4 , 3 , 3 , 4 , 4 , 3 , 3 , - 3 , 3 , 3 , 1 , 2 , 3 , 2 , 1 , - 3 , 3 , 3 , 3 , 1 , 1 , 3 , 3 , - 3 , 2 , 2 , 3 , 2 , 3 , 0 , 0 , - 5 , 5 , 5 , 5 , 4 , 4 , 2 , 0 , - 2 , 2 , 0 , 3 , 2 , 0 , 4 , 2 , - 0 , 3 , 2 , 0 , 2 , 2 , 0 , 2 , - 3 , 0 , 3 , 3 , 0 , 3 , 0xB0 , 0xA0 + 0 , 2 , 2 , 2 , 2 , 4 , 4 , 4 , + 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , + 4 , 4 , 3 , 3 , 4 , 4 , 3 , 3 , + 3 , 3 , 3 , 1 , 2 , 3 , 2 , 1 , + 3 , 3 , 3 , 3 , 1 , 1 , 3 , 3 , + 3 , 2 , 2 , 3 , 2 , 3 , 0 , 0 , + 5 , 5 , 5 , 5 , 4 , 4 , 2 , 0 , + 2 , 2 , 0 , 3 , 2 , 0 , 4 , 2 , + 0 , 3 , 2 , 0 , 2 , 2 , 0 , 2 , + 3 , 0 , 3 , 3 , 0 , 3 , 0xB0 , 0xA0 }; @@ -85,7 +85,7 @@ const unsigned char inBlendLength[] = // 67: ** 27 00011011 // 70: ** 25 00011001 // tab45936 -const unsigned char sampledConsonantFlags[] = +unsigned char sampledConsonantFlags[] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , @@ -103,338 +103,407 @@ const unsigned char sampledConsonantFlags[] = //tab45056 unsigned char freq1data[]= { - 0x00 ,0x13 ,0x13 ,0x13 ,0x13 , 0xA , 0xE ,0x12 - , 0x18 ,0x1A ,0x16 ,0x14 ,0x10 ,0x14 , 0xE ,0x12 - , 0xE ,0x12 ,0x12 ,0x10 , 0xC , 0xE , 0xA ,0x12 - , 0xE ,0xA , 8 , 6 , 6 , 6 , 6 ,0x11 - , 6 , 6 , 6 , 6 ,0xE , 0x10 , 9 ,0xA - , 8 ,0xA , 6 , 6 , 6 , 5 , 6 , 0 - , 0x12 , 0x1A , 0x14 , 0x1A , 0x12 ,0xC , 6 , 6 - , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 - , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 - , 6 ,0xA ,0xA , 6 , 6 , 6 , 0x2C , 0x13 + 0x00 ,0x13 ,0x13 ,0x13 ,0x13 , 0xA , 0xE ,0x12 + , 0x18 ,0x1A ,0x16 ,0x14 ,0x10 ,0x14 , 0xE ,0x12 + , 0xE ,0x12 ,0x12 ,0x10 , 0xC , 0xE , 0xA ,0x12 + , 0xE ,0xA , 8 , 6 , 6 , 6 , 6 ,0x11 + , 6 , 6 , 6 , 6 ,0xE , 0x10 , 9 ,0xA + , 8 ,0xA , 6 , 6 , 6 , 5 , 6 , 0 + , 0x12 , 0x1A , 0x14 , 0x1A , 0x12 ,0xC , 6 , 6 + , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 + , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 + , 6 ,0xA ,0xA , 6 , 6 , 6 , 0x2C , 0x13 }; //tab451356 unsigned char freq2data[]= { - 0x00 , 0x43 , 0x43 , 0x43 , 0x43 , 0x54 , 0x48 , 0x42 , - 0x3E , 0x28 , 0x2C , 0x1E , 0x24 , 0x2C , 0x48 , 0x30 , - 0x24 , 0x1E , 0x32 , 0x24 , 0x1C , 0x44 , 0x18 , 0x32 , - 0x1E , 0x18 , 0x52 , 0x2E , 0x36 , 0x56 , 0x36 , 0x43 , - 0x49 , 0x4F , 0x1A , 0x42 , 0x49 , 0x25 , 0x33 , 0x42 , - 0x28 , 0x2F , 0x4F , 0x4F , 0x42 , 0x4F , 0x6E , 0x00 , - 0x48 , 0x26 , 0x1E , 0x2A , 0x1E , 0x22 , 0x1A , 0x1A , - 0x1A , 0x42 , 0x42 , 0x42 , 0x6E , 0x6E , 0x6E , 0x54 , - 0x54 , 0x54 , 0x1A , 0x1A , 0x1A , 0x42 , 0x42 , 0x42 , - 0x6D , 0x56 , 0x6D , 0x54 , 0x54 , 0x54 , 0x7F , 0x7F + 0x00 , 0x43 , 0x43 , 0x43 , 0x43 , 0x54 , 0x48 , 0x42 , + 0x3E , 0x28 , 0x2C , 0x1E , 0x24 , 0x2C , 0x48 , 0x30 , + 0x24 , 0x1E , 0x32 , 0x24 , 0x1C , 0x44 , 0x18 , 0x32 , + 0x1E , 0x18 , 0x52 , 0x2E , 0x36 , 0x56 , 0x36 , 0x43 , + 0x49 , 0x4F , 0x1A , 0x42 , 0x49 , 0x25 , 0x33 , 0x42 , + 0x28 , 0x2F , 0x4F , 0x4F , 0x42 , 0x4F , 0x6E , 0x00 , + 0x48 , 0x26 , 0x1E , 0x2A , 0x1E , 0x22 , 0x1A , 0x1A , + 0x1A , 0x42 , 0x42 , 0x42 , 0x6E , 0x6E , 0x6E , 0x54 , + 0x54 , 0x54 , 0x1A , 0x1A , 0x1A , 0x42 , 0x42 , 0x42 , + 0x6D , 0x56 , 0x6D , 0x54 , 0x54 , 0x54 , 0x7F , 0x7F }; //tab45216 unsigned char freq3data[]= { - 0x00 , 0x5B , 0x5B , 0x5B , 0x5B , 0x6E , 0x5D , 0x5B , - 0x58 , 0x59 , 0x57 , 0x58 , 0x52 , 0x59 , 0x5D , 0x3E , - 0x52 , 0x58 , 0x3E , 0x6E , 0x50 , 0x5D , 0x5A , 0x3C , - 0x6E , 0x5A , 0x6E , 0x51 , 0x79 , 0x65 , 0x79 , 0x5B , - 0x63 , 0x6A , 0x51 , 0x79 , 0x5D , 0x52 , 0x5D , 0x67 , - 0x4C , 0x5D , 0x65 , 0x65 , 0x79 , 0x65 , 0x79 , 0x00 , - 0x5A , 0x58 , 0x58 , 0x58 , 0x58 , 0x52 , 0x51 , 0x51 , - 0x51 , 0x79 , 0x79 , 0x79 , 0x70 , 0x6E , 0x6E , 0x5E , - 0x5E , 0x5E , 0x51 , 0x51 , 0x51 , 0x79 , 0x79 , 0x79 , - 0x65 , 0x65 , 0x70 , 0x5E , 0x5E , 0x5E , 0x08 , 0x01 + 0x00 , 0x5B , 0x5B , 0x5B , 0x5B , 0x6E , 0x5D , 0x5B , + 0x58 , 0x59 , 0x57 , 0x58 , 0x52 , 0x59 , 0x5D , 0x3E , + 0x52 , 0x58 , 0x3E , 0x6E , 0x50 , 0x5D , 0x5A , 0x3C , + 0x6E , 0x5A , 0x6E , 0x51 , 0x79 , 0x65 , 0x79 , 0x5B , + 0x63 , 0x6A , 0x51 , 0x79 , 0x5D , 0x52 , 0x5D , 0x67 , + 0x4C , 0x5D , 0x65 , 0x65 , 0x79 , 0x65 , 0x79 , 0x00 , + 0x5A , 0x58 , 0x58 , 0x58 , 0x58 , 0x52 , 0x51 , 0x51 , + 0x51 , 0x79 , 0x79 , 0x79 , 0x70 , 0x6E , 0x6E , 0x5E , + 0x5E , 0x5E , 0x51 , 0x51 , 0x51 , 0x79 , 0x79 , 0x79 , + 0x65 , 0x65 , 0x70 , 0x5E , 0x5E , 0x5E , 0x08 , 0x01 }; -const unsigned char ampl1data[] = +unsigned char ampl1data[] = { - 0 , 0 , 0 , 0 , 0 ,0xD ,0xD ,0xE , - 0xF ,0xF ,0xF ,0xF ,0xF ,0xC ,0xD ,0xC , - 0xF ,0xF ,0xD ,0xD ,0xD ,0xE ,0xD ,0xC , - 0xD ,0xD ,0xD ,0xC , 9 , 9 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 ,0xB ,0xB , - 0xB ,0xB , 0 , 0 , 1 ,0xB , 0 , 2 , - 0xE ,0xF ,0xF ,0xF ,0xF ,0xD , 2 , 4 , - 0 , 2 , 4 , 0 , 1 , 4 , 0 , 1 , - 4 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 ,0xC , 0 , 0 , 0 , 0 ,0xF ,0xF + 0 , 0 , 0 , 0 , 0 ,0xD ,0xD ,0xE , + 0xF ,0xF ,0xF ,0xF ,0xF ,0xC ,0xD ,0xC , + 0xF ,0xF ,0xD ,0xD ,0xD ,0xE ,0xD ,0xC , + 0xD ,0xD ,0xD ,0xC , 9 , 9 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 ,0xB ,0xB , + 0xB ,0xB , 0 , 0 , 1 ,0xB , 0 , 2 , + 0xE ,0xF ,0xF ,0xF ,0xF ,0xD , 2 , 4 , + 0 , 2 , 4 , 0 , 1 , 4 , 0 , 1 , + 4 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 ,0xC , 0 , 0 , 0 , 0 ,0xF ,0xF }; -const unsigned char ampl2data[] = +unsigned char ampl2data[] = { - 0 , 0 , 0 , 0 , 0 ,0xA ,0xB ,0xD , - 0xE ,0xD ,0xC ,0xC ,0xB , 9 ,0xB ,0xB , - 0xC ,0xC ,0xC , 8 , 8 ,0xC , 8 ,0xA , - 8 , 8 ,0xA , 3 , 9 , 6 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 3 , 5 , - 3 , 4 , 0 , 0 , 0 , 5 ,0xA , 2 , - 0xE ,0xD ,0xC ,0xD ,0xC , 8 , 0 , 1 , - 0 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , - 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 ,0xA , 0 , 0 ,0xA , 0 , 0 , 0 + 0 , 0 , 0 , 0 , 0 ,0xA ,0xB ,0xD , + 0xE ,0xD ,0xC ,0xC ,0xB , 9 ,0xB ,0xB , + 0xC ,0xC ,0xC , 8 , 8 ,0xC , 8 ,0xA , + 8 , 8 ,0xA , 3 , 9 , 6 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 3 , 5 , + 3 , 4 , 0 , 0 , 0 , 5 ,0xA , 2 , + 0xE ,0xD ,0xC ,0xD ,0xC , 8 , 0 , 1 , + 0 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , + 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 ,0xA , 0 , 0 ,0xA , 0 , 0 , 0 }; -const unsigned char ampl3data[] = +unsigned char ampl3data[] = { - 0 , 0 , 0 , 0 , 0 , 8 , 7 , 8 , - 8 , 1 , 1 , 0 , 1 , 0 , 7 , 5 , - 1 , 0 , 6 , 1 , 0 , 7 , 0 , 5 , - 1 , 0 , 8 , 0 , 0 , 3 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , - 0 , 0 , 0 , 0 , 0 , 1 ,0xE , 1 , - 9 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 7 , 0 , 0 , 5 , 0 , 0x13 , 0x10 + 0 , 0 , 0 , 0 , 0 , 8 , 7 , 8 , + 8 , 1 , 1 , 0 , 1 , 0 , 7 , 5 , + 1 , 0 , 6 , 1 , 0 , 7 , 0 , 5 , + 1 , 0 , 8 , 0 , 0 , 3 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , + 0 , 0 , 0 , 0 , 0 , 1 ,0xE , 1 , + 9 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 7 , 0 , 0 , 5 , 0 , 0x13 , 0x10 }; //tab42240 -const signed char sinus[256] = -{0,3,6,9,12,16,19,22,25,28,31,34,37,40,43,46,49,51,54,57,60,63,65,68,71,73,76,78,81,83,85,88,90,92,94,96,98,100,102,104,106,107,109,111,112,113,115,116,117,118,120,121,122,122,123,124,125,125,126,126,126,127,127,127,127,127,127,127,126,126,126,125,125,124,123,122,122,121,120,118,117,116,115,113,112,111,109,107,106,104,102,100,98,96,94,92,90,88,85,83,81,78,76,73,71,68,65,63,60,57,54,51,49,46,43,40,37,34,31,28,25,22,19,16,12,9,6,3,0,-3,-6,-9,-12,-16,-19,-22,-25,-28,-31,-34,-37,-40,-43,-46,-49,-51,-54,-57,-60,-63,-65,-68,-71,-73,-76,-78,-81,-83,-85,-88,-90,-92,-94,-96,-98,-100,-102,-104,-106,-107,-109,-111,-112,-113,-115,-116,-117,-118,-120,-121,-122,-122,-123,-124,-125,-125,-126,-126,-126,-127,-127,-127,-127,-127,-127,-127,-126,-126,-126,-125,-125,-124,-123,-122,-122,-121,-120,-118,-117,-116,-115,-113,-112,-111,-109,-107,-106,-104,-102,-100,-98,-96,-94,-92,-90,-88,-85,-83,-81,-78,-76,-73,-71,-68,-65,-63,-60,-57,-54,-51,-49,-46,-43,-40,-37,-34,-31,-28,-25,-22,-19,-16,-12,-9,-6,-3}; +unsigned char sinus[] = +{ + 0x00 , 0x00 , 0x00 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , + 0x10 , 0x20 , 0x20 , 0x20 , 0x20 , 0x20 , 0x20 , 0x30 , + 0x30 , 0x30 , 0x30 , 0x30 , 0x30 , 0x30 , 0x40 , 0x40 , + 0x40 , 0x40 , 0x40 , 0x40 , 0x40 , 0x50 , 0x50 , 0x50 , + 0x50 , 0x50 , 0x50 , 0x50 , 0x50 , 0x60 , 0x60 , 0x60 , + 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , + 0x60 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , + 0x60 , 0x60 , 0x60 , 0x60 , 0x50 , 0x50 , 0x50 , 0x50 , + 0x50 , 0x50 , 0x50 , 0x50 , 0x40 , 0x40 , 0x40 , 0x40 , + 0x40 , 0x40 , 0x40 , 0x30 , 0x30 , 0x30 , 0x30 , 0x30 , + 0x30 , 0x30 , 0x20 , 0x20 , 0x20 , 0x20 , 0x20 , 0x20 , + 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x00 , 0x00 , + 0x00 , 0x00 , 0x00 , 0xF0 , 0xF0 , 0xF0 , 0xF0 , 0xF0 , + 0xF0 , 0xE0 , 0xE0 , 0xE0 , 0xE0 , 0xE0 , 0xE0 , 0xD0 , + 0xD0 , 0xD0 , 0xD0 , 0xD0 , 0xD0 , 0xD0 , 0xC0 , 0xC0 , + 0xC0 , 0xC0 , 0xC0 , 0xC0 , 0xC0 , 0xB0 , 0xB0 , 0xB0 , + 0xB0 , 0xB0 , 0xB0 , 0xB0 , 0xB0 , 0xA0 , 0xA0 , 0xA0 , + 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , + 0xA0 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , + 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xB0 , 0xB0 , 0xB0 , 0xB0 , + 0xB0 , 0xB0 , 0xB0 , 0xB0 , 0xC0 , 0xC0 , 0xC0 , 0xC0 , + 0xC0 , 0xC0 , 0xC0 , 0xD0 , 0xD0 , 0xD0 , 0xD0 , 0xD0 , + 0xD0 , 0xD0 , 0xE0 , 0xE0 , 0xE0 , 0xE0 , 0xE0 , 0xE0 , + 0xF0 , 0xF0 , 0xF0 , 0xF0 , 0xF0 , 0xF0 , 0x00 , 0x00 }; //tab42496 -const unsigned char rectangle[] = +unsigned char rectangle[] = { - 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , - 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , - 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , - 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , - 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , - 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , - 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , - 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , - 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , - 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , - 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , - 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , - 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , - 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , - 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , - 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , - 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , - 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , - 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , - 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , - 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , - 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , - 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , - 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , - 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , - 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , - 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , - 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , - 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , - 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , - 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , - 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , + 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 }; +//tab42752 +unsigned char multtable[] = +{ + 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , + 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , + 0x00 , 0x00 , 1 , 1 , 2 , 2 , 3 , 3 , + 4 , 4 , 5 , 5 , 6 , 6 , 7 , 7 , + 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , + 8 , 9 ,0xA ,0xB ,0xC ,0xD ,0xE ,0xF , + 0x00 , 1 , 3 , 4 , 6 , 7 , 9 ,0xA , + 0xC ,0xD ,0xF , 0x10 , 0x12 , 0x13 , 0x15 , 0x16 , + 0x00 , 2 , 4 , 6 , 8 ,0xA ,0xC ,0xE , + 0x10 , 0x12 , 0x14 , 0x16 , 0x18 , 0x1A , 0x1C , 0x1E , + 0x00 , 2 , 5 , 7 ,0xA ,0xC ,0xF , 0x11 , + 0x14 , 0x16 , 0x19 , 0x1B , 0x1E , 0x20 , 0x23 , 0x25 , + 0x00 , 3 , 6 , 9 ,0xC ,0xF , 0x12 , 0x15 , + 0x18 , 0x1B , 0x1E , 0x21 , 0x24 , 0x27 , 0x2A , 0x2D , + 0x00 , 0x03 , 0x07 , 0x0A , 0x0E , 0x11 , 0x15 , 0x18 , + 0x1C , 0x1F , 0x23 , 0x26 , 0x2A , 0x2D , 0x31 , 0x34 , + 0x00 , 0xFC , 0xF8 , 0xF4 , 0xF0 , 0xEC , 0xE8 , 0xE4 , + 0xE0 , 0xDC , 0xD8 , 0xD4 , 0xD0 , 0xCC , 0xC8 , 0xC4 , + 0x00 , 0xFC , 0xF9 , 0xF5 , 0xF2 , 0xEE , 0xEB , 0xE7 , + 0xE4 , 0xE0 , 0xDD , 0xD9 , 0xD6 , 0xD2 , 0xCF , 0xCB , + 0x00 , 0xFD , 0xFA , 0xF7 , 0xF4 , 0xF1 , 0xEE , 0xEB , + 0xE8 , 0xE5 , 0xE2 , 0xDF , 0xDC , 0xD9 , 0xD6 , 0xD3 , + 0x00 , 0xFD , 0xFB , 0xF8 , 0xF6 , 0xF3 , 0xF1 , 0xEE , + 0xEC , 0xE9 , 0xE7 , 0xE4 , 0xE2 , 0xDF , 0xDD , 0xDA , + 0x00 , 0xFE , 0xFC , 0xFA , 0xF8 , 0xF6 , 0xF4 , 0xF2 , + 0xF0 , 0xEE , 0xEC , 0xEA , 0xE8 , 0xE6 , 0xE4 , 0xE2 , + 0x00 , 0xFE , 0xFD , 0xFB , 0xFA , 0xF8 , 0xF7 , 0xF5 , + 0xF4 , 0xF2 , 0xF1 , 0xEF , 0xEE , 0xEC , 0xEB , 0xE9 , + 0x00 , 0xFF , 0xFE , 0xFD , 0xFC , 0xFB , 0xFA , 0xF9 , + 0xF8 , 0xF7 , 0xF6 , 0xF5 , 0xF4 , 0xF3 , 0xF2 , 0xF1 , + 0x00 , 0xFF , 0xFF , 0xFE , 0xFE , 0xFD , 0xFD , 0xFC , + 0xFC , 0xFB , 0xFB , 0xFA , 0xFA , 0xF9 , 0xF9 , 0xF8 +}; + //random data ? -const unsigned char sampleTable[0x500] = +unsigned char sampleTable[0x500] = { - //00 + //00 - 0x38 , 0x84 , 0x6B , 0x19 , 0xC6 , 0x63 , 0x18 , 0x86 - , 0x73 , 0x98 , 0xC6 , 0xB1 , 0x1C , 0xCA , 0x31 , 0x8C - , 0xC7 , 0x31 , 0x88 , 0xC2 , 0x30 , 0x98 , 0x46 , 0x31 - , 0x18 , 0xC6 , 0x35 ,0xC , 0xCA , 0x31 ,0xC , 0xC6 - //20 - , 0x21 , 0x10 , 0x24 , 0x69 , 0x12 , 0xC2 , 0x31 , 0x14 - , 0xC4 , 0x71 , 8 , 0x4A , 0x22 , 0x49 , 0xAB , 0x6A - , 0xA8 , 0xAC , 0x49 , 0x51 , 0x32 , 0xD5 , 0x52 , 0x88 - , 0x93 , 0x6C , 0x94 , 0x22 , 0x15 , 0x54 , 0xD2 , 0x25 - //40 - , 0x96 , 0xD4 , 0x50 , 0xA5 , 0x46 , 0x21 , 8 , 0x85 - , 0x6B , 0x18 , 0xC4 , 0x63 , 0x10 , 0xCE , 0x6B , 0x18 - , 0x8C , 0x71 , 0x19 , 0x8C , 0x63 , 0x35 ,0xC , 0xC6 - , 0x33 , 0x99 , 0xCC , 0x6C , 0xB5 , 0x4E , 0xA2 , 0x99 - //60 - , 0x46 , 0x21 , 0x28 , 0x82 , 0x95 , 0x2E , 0xE3 , 0x30 - , 0x9C , 0xC5 , 0x30 , 0x9C , 0xA2 , 0xB1 , 0x9C , 0x67 - , 0x31 , 0x88 , 0x66 , 0x59 , 0x2C , 0x53 , 0x18 , 0x84 - , 0x67 , 0x50 , 0xCA , 0xE3 ,0xA , 0xAC , 0xAB , 0x30 - //80 - , 0xAC , 0x62 , 0x30 , 0x8C , 0x63 , 0x10 , 0x94 , 0x62 - , 0xB1 , 0x8C , 0x82 , 0x28 , 0x96 , 0x33 , 0x98 , 0xD6 - , 0xB5 , 0x4C , 0x62 , 0x29 , 0xA5 , 0x4A , 0xB5 , 0x9C - , 0xC6 , 0x31 , 0x14 , 0xD6 , 0x38 , 0x9C , 0x4B , 0xB4 - //A0 - , 0x86 , 0x65 , 0x18 , 0xAE , 0x67 , 0x1C , 0xA6 , 0x63 - , 0x19 , 0x96 , 0x23 , 0x19 , 0x84 , 0x13 , 8 , 0xA6 - , 0x52 , 0xAC , 0xCA , 0x22 , 0x89 , 0x6E , 0xAB , 0x19 - , 0x8C , 0x62 , 0x34 , 0xC4 , 0x62 , 0x19 , 0x86 , 0x63 - //C0 - , 0x18 , 0xC4 , 0x23 , 0x58 , 0xD6 , 0xA3 , 0x50 , 0x42 - , 0x54 , 0x4A , 0xAD , 0x4A , 0x25 , 0x11 , 0x6B , 0x64 - , 0x89 , 0x4A , 0x63 , 0x39 , 0x8A , 0x23 , 0x31 , 0x2A - , 0xEA , 0xA2 , 0xA9 , 0x44 , 0xC5 , 0x12 , 0xCD , 0x42 - //E0 - , 0x34 , 0x8C , 0x62 , 0x18 , 0x8C , 0x63 , 0x11 , 0x48 - , 0x66 , 0x31 , 0x9D , 0x44 , 0x33 , 0x1D , 0x46 , 0x31 - , 0x9C , 0xC6 , 0xB1 ,0xC , 0xCD , 0x32 , 0x88 , 0xC4 - , 0x73 , 0x18 , 0x86 , 0x73 , 8 , 0xD6 , 0x63 , 0x58 - //100 - , 7 , 0x81 , 0xE0 , 0xF0 , 0x3C , 7 , 0x87 , 0x90 - , 0x3C , 0x7C ,0xF , 0xC7 , 0xC0 , 0xC0 , 0xF0 , 0x7C - , 0x1E , 7 , 0x80 , 0x80 , 0 , 0x1C , 0x78 , 0x70 - , 0xF1 , 0xC7 , 0x1F , 0xC0 ,0xC , 0xFE , 0x1C , 0x1F - //120 - , 0x1F ,0xE ,0xA , 0x7A , 0xC0 , 0x71 , 0xF2 , 0x83 - , 0x8F , 3 ,0xF ,0xF ,0xC , 0 , 0x79 , 0xF8 - , 0x61 , 0xE0 , 0x43 ,0xF , 0x83 , 0xE7 , 0x18 , 0xF9 - , 0xC1 , 0x13 , 0xDA , 0xE9 , 0x63 , 0x8F ,0xF , 0x83 - //140 - , 0x83 , 0x87 , 0xC3 , 0x1F , 0x3C , 0x70 , 0xF0 , 0xE1 - , 0xE1 , 0xE3 , 0x87 , 0xB8 , 0x71 ,0xE , 0x20 , 0xE3 - , 0x8D , 0x48 , 0x78 , 0x1C , 0x93 , 0x87 , 0x30 , 0xE1 - , 0xC1 , 0xC1 , 0xE4 , 0x78 , 0x21 , 0x83 , 0x83 , 0xC3 - //160 - , 0x87 , 6 , 0x39 , 0xE5 , 0xC3 , 0x87 , 7 ,0xE - , 0x1C , 0x1C , 0x70 , 0xF4 , 0x71 , 0x9C , 0x60 , 0x36 - , 0x32 , 0xC3 , 0x1E , 0x3C , 0xF3 , 0x8F ,0xE , 0x3C - , 0x70 , 0xE3 , 0xC7 , 0x8F ,0xF ,0xF ,0xE , 0x3C - //180 - , 0x78 , 0xF0 , 0xE3 , 0x87 , 6 , 0xF0 , 0xE3 , 7 - , 0xC1 , 0x99 , 0x87 ,0xF , 0x18 , 0x78 , 0x70 , 0x70 - , 0xFC , 0xF3 , 0x10 , 0xB1 , 0x8C , 0x8C , 0x31 , 0x7C - , 0x70 , 0xE1 , 0x86 , 0x3C , 0x64 , 0x6C , 0xB0 , 0xE1 - //1A0 - , 0xE3 ,0xF , 0x23 , 0x8F ,0xF , 0x1E , 0x3E , 0x38 - , 0x3C , 0x38 , 0x7B , 0x8F , 7 ,0xE , 0x3C , 0xF4 - , 0x17 , 0x1E , 0x3C , 0x78 , 0xF2 , 0x9E , 0x72 , 0x49 - , 0xE3 , 0x25 , 0x36 , 0x38 , 0x58 , 0x39 , 0xE2 , 0xDE - //1C0 - , 0x3C , 0x78 , 0x78 , 0xE1 , 0xC7 , 0x61 , 0xE1 , 0xE1 - , 0xB0 , 0xF0 , 0xF0 , 0xC3 , 0xC7 ,0xE , 0x38 , 0xC0 - , 0xF0 , 0xCE , 0x73 , 0x73 , 0x18 , 0x34 , 0xB0 , 0xE1 - , 0xC7 , 0x8E , 0x1C , 0x3C , 0xF8 , 0x38 , 0xF0 , 0xE1 - //1E0 - , 0xC1 , 0x8B , 0x86 , 0x8F , 0x1C , 0x78 , 0x70 , 0xF0 - , 0x78 , 0xAC , 0xB1 , 0x8F , 0x39 , 0x31 , 0xDB , 0x38 - , 0x61 , 0xC3 ,0xE ,0xE , 0x38 , 0x78 , 0x73 , 0x17 - , 0x1E , 0x39 , 0x1E , 0x38 , 0x64 , 0xE1 , 0xF1 , 0xC1 - //200 - , 0x4E ,0xF , 0x40 , 0xA2 , 2 , 0xC5 , 0x8F , 0x81 - , 0xA1 , 0xFC , 0x12 , 8 , 0x64 , 0xE0 , 0x3C , 0x22 - , 0xE0 , 0x45 , 7 , 0x8E ,0xC , 0x32 , 0x90 , 0xF0 - , 0x1F , 0x20 , 0x49 , 0xE0 , 0xF8 ,0xC , 0x60 , 0xF0 - //220 - , 0x17 , 0x1A , 0x41 , 0xAA , 0xA4 , 0xD0 , 0x8D , 0x12 - , 0x82 , 0x1E , 0x1E , 3 , 0xF8 , 0x3E , 3 ,0xC - , 0x73 , 0x80 , 0x70 , 0x44 , 0x26 , 3 , 0x24 , 0xE1 - , 0x3E , 4 , 0x4E , 4 , 0x1C , 0xC1 , 9 , 0xCC - //240 - , 0x9E , 0x90 , 0x21 , 7 , 0x90 , 0x43 , 0x64 , 0xC0 - , 0xF , 0xC6 , 0x90 , 0x9C , 0xC1 , 0x5B , 3 , 0xE2 - , 0x1D , 0x81 , 0xE0 , 0x5E , 0x1D , 3 , 0x84 , 0xB8 - , 0x2C ,0xF , 0x80 , 0xB1 , 0x83 , 0xE0 , 0x30 , 0x41 - //260 - , 0x1E , 0x43 , 0x89 , 0x83 , 0x50 , 0xFC , 0x24 , 0x2E - , 0x13 , 0x83 , 0xF1 , 0x7C , 0x4C , 0x2C , 0xC9 ,0xD - , 0x83 , 0xB0 , 0xB5 , 0x82 , 0xE4 , 0xE8 , 6 , 0x9C - , 7 , 0xA0 , 0x99 , 0x1D , 7 , 0x3E , 0x82 , 0x8F - //280 - , 0x70 , 0x30 , 0x74 , 0x40 , 0xCA , 0x10 , 0xE4 , 0xE8 - , 0xF , 0x92 , 0x14 , 0x3F , 6 , 0xF8 , 0x84 , 0x88 - , 0x43 , 0x81 ,0xA , 0x34 , 0x39 , 0x41 , 0xC6 , 0xE3 - , 0x1C , 0x47 , 3 , 0xB0 , 0xB8 , 0x13 ,0xA , 0xC2 - //2A0 - , 0x64 , 0xF8 , 0x18 , 0xF9 , 0x60 , 0xB3 , 0xC0 , 0x65 - , 0x20 , 0x60 , 0xA6 , 0x8C , 0xC3 , 0x81 , 0x20 , 0x30 - , 0x26 , 0x1E , 0x1C , 0x38 , 0xD3 , 1 , 0xB0 , 0x26 - , 0x40 , 0xF4 ,0xB , 0xC3 , 0x42 , 0x1F , 0x85 , 0x32 - //2C0 - , 0x26 , 0x60 , 0x40 , 0xC9 , 0xCB , 1 , 0xEC , 0x11 - , 0x28 , 0x40 , 0xFA , 4 , 0x34 , 0xE0 , 0x70 , 0x4C - , 0x8C , 0x1D , 7 , 0x69 , 3 , 0x16 , 0xC8 , 4 - , 0x23 , 0xE8 , 0xC6 , 0x9A ,0xB , 0x1A , 3 , 0xE0 - //2E0 - , 0x76 , 6 , 5 , 0xCF , 0x1E , 0xBC , 0x58 , 0x31 - , 0x71 , 0x66 , 0 , 0xF8 , 0x3F , 4 , 0xFC ,0xC - , 0x74 , 0x27 , 0x8A , 0x80 , 0x71 , 0xC2 , 0x3A , 0x26 - , 6 , 0xC0 , 0x1F , 5 ,0xF , 0x98 , 0x40 , 0xAE - //300 - , 1 , 0x7F , 0xC0 , 7 , 0xFF , 0 ,0xE , 0xFE - , 0 , 3 , 0xDF , 0x80 , 3 , 0xEF , 0x80 , 0x1B - , 0xF1 , 0xC2 , 0 , 0xE7 , 0xE0 , 0x18 , 0xFC , 0xE0 - , 0x21 , 0xFC , 0x80 , 0x3C , 0xFC , 0x40 ,0xE , 0x7E - //320 - , 0 , 0x3F , 0x3E , 0 ,0xF , 0xFE , 0 , 0x1F - , 0xFF , 0 , 0x3E , 0xF0 , 7 , 0xFC , 0 , 0x7E - , 0x10 , 0x3F , 0xFF , 0 , 0x3F , 0x38 ,0xE , 0x7C - , 1 , 0x87 ,0xC , 0xFC , 0xC7 , 0 , 0x3E , 4 - //340 - , 0xF , 0x3E , 0x1F ,0xF ,0xF , 0x1F ,0xF , 2 - , 0x83 , 0x87 , 0xCF , 3 , 0x87 ,0xF , 0x3F , 0xC0 - , 7 , 0x9E , 0x60 , 0x3F , 0xC0 , 3 , 0xFE , 0 - , 0x3F , 0xE0 , 0x77 , 0xE1 , 0xC0 , 0xFE , 0xE0 , 0xC3 - //360 - , 0xE0 , 1 , 0xDF , 0xF8 , 3 , 7 , 0 , 0x7E - , 0x70 , 0 , 0x7C , 0x38 , 0x18 , 0xFE ,0xC , 0x1E - , 0x78 , 0x1C , 0x7C , 0x3E ,0xE , 0x1F , 0x1E , 0x1E - , 0x3E , 0 , 0x7F , 0x83 , 7 , 0xDB , 0x87 , 0x83 - //380 - , 7 , 0xC7 , 7 , 0x10 , 0x71 , 0xFF , 0 , 0x3F - , 0xE2 , 1 , 0xE0 , 0xC1 , 0xC3 , 0xE1 , 0 , 0x7F - , 0xC0 , 5 , 0xF0 , 0x20 , 0xF8 , 0xF0 , 0x70 , 0xFE - , 0x78 , 0x79 , 0xF8 , 2 , 0x3F ,0xC , 0x8F , 3 - //3a0 - , 0xF , 0x9F , 0xE0 , 0xC1 , 0xC7 , 0x87 , 3 , 0xC3 - , 0xC3 , 0xB0 , 0xE1 , 0xE1 , 0xC1 , 0xE3 , 0xE0 , 0x71 - , 0xF0 , 0 , 0xFC , 0x70 , 0x7C ,0xC , 0x3E , 0x38 - , 0xE , 0x1C , 0x70 , 0xC3 , 0xC7 , 3 , 0x81 , 0xC1 - //3c0 - , 0xC7 , 0xE7 , 0 ,0xF , 0xC7 , 0x87 , 0x19 , 9 - , 0xEF , 0xC4 , 0x33 , 0xE0 , 0xC1 , 0xFC , 0xF8 , 0x70 - , 0xF0 , 0x78 , 0xF8 , 0xF0 , 0x61 , 0xC7 , 0 , 0x1F - , 0xF8 , 1 , 0x7C , 0xF8 , 0xF0 , 0x78 , 0x70 , 0x3C - //3e0 - , 0x7C , 0xCE ,0xE , 0x21 , 0x83 , 0xCF , 8 , 7 - , 0x8F , 8 , 0xC1 , 0x87 , 0x8F , 0x80 , 0xC7 , 0xE3 - , 0 , 7 , 0xF8 , 0xE0 , 0xEF , 0 , 0x39 , 0xF7 - , 0x80 ,0xE , 0xF8 , 0xE1 , 0xE3 , 0xF8 , 0x21 , 0x9F - //400 - , 0xC0 , 0xFF , 3 , 0xF8 , 7 , 0xC0 , 0x1F , 0xF8 - , 0xC4 , 4 , 0xFC , 0xC4 , 0xC1 , 0xBC , 0x87 , 0xF0 - , 0xF , 0xC0 , 0x7F , 5 , 0xE0 , 0x25 , 0xEC , 0xC0 - , 0x3E , 0x84 , 0x47 , 0xF0 , 0x8E , 3 , 0xF8 , 3 - //420 - , 0xFB , 0xC0 , 0x19 , 0xF8 , 7 , 0x9C ,0xC , 0x17 - , 0xF8 , 7 , 0xE0 , 0x1F , 0xA1 , 0xFC ,0xF , 0xFC - , 1 , 0xF0 , 0x3F , 0 , 0xFE , 3 , 0xF0 , 0x1F - , 0 , 0xFD , 0 , 0xFF , 0x88 ,0xD , 0xF9 , 1 - //440 - , 0xFF , 0 , 0x70 , 7 , 0xC0 , 0x3E , 0x42 , 0xF3 - , 0xD , 0xC4 , 0x7F , 0x80 , 0xFC , 7 , 0xF0 , 0x5E - , 0xC0 , 0x3F , 0 , 0x78 , 0x3F , 0x81 , 0xFF , 1 - , 0xF8 , 1 , 0xC3 , 0xE8 ,0xC , 0xE4 , 0x64 , 0x8F - ////460 - , 0xE4 ,0xF , 0xF0 , 7 , 0xF0 , 0xC2 , 0x1F , 0 - , 0x7F , 0xC0 , 0x6F , 0x80 , 0x7E , 3 , 0xF8 , 7 - , 0xF0 , 0x3F , 0xC0 , 0x78 ,0xF , 0x82 , 7 , 0xFE - , 0x22 , 0x77 , 0x70 , 2 , 0x76 , 3 , 0xFE , 0 - //480 - , 0xFE , 0x67 , 0 , 0x7C , 0xC7 , 0xF1 , 0x8E , 0xC6 - , 0x3B , 0xE0 , 0x3F , 0x84 , 0xF3 , 0x19 , 0xD8 , 3 - , 0x99 , 0xFC , 9 , 0xB8 ,0xF , 0xF8 , 0 , 0x9D - , 0x24 , 0x61 , 0xF9 ,0xD , 0 , 0xFD , 3 , 0xF0 - //4a0 - , 0x1F , 0x90 , 0x3F , 1 , 0xF8 , 0x1F , 0xD0 ,0xF - , 0xF8 , 0x37 , 1 , 0xF8 , 7 , 0xF0 ,0xF , 0xC0 - , 0x3F , 0 , 0xFE , 3 , 0xF8 ,0xF , 0xC0 , 0x3F - , 0 , 0xFA , 3 , 0xF0 ,0xF , 0x80 , 0xFF , 1 - //4c0 - , 0xB8 , 7 , 0xF0 , 1 , 0xFC , 1 , 0xBC , 0x80 - , 0x13 , 0x1E , 0 , 0x7F , 0xE1 , 0x40 , 0x7F , 0xA0 - , 0x7F , 0xB0 , 0 , 0x3F , 0xC0 , 0x1F , 0xC0 , 0x38 - , 0xF , 0xF0 , 0x1F , 0x80 , 0xFF , 1 , 0xFC , 3 - //4e0 - , 0xF1 , 0x7E , 1 , 0xFE , 1 , 0xF0 , 0xFF , 0 - , 0x7F , 0xC0 , 0x1D , 7 , 0xF0 ,0xF , 0xC0 , 0x7E - , 6 , 0xE0 , 7 , 0xE0 ,0xF , 0xF8 , 6 , 0xC1 - , 0xFE , 1 , 0xFC , 3 , 0xE0 ,0xF , 0 , 0xFC + 0x38 , 0x84 , 0x6B , 0x19 , 0xC6 , 0x63 , 0x18 , 0x86 + , 0x73 , 0x98 , 0xC6 , 0xB1 , 0x1C , 0xCA , 0x31 , 0x8C + , 0xC7 , 0x31 , 0x88 , 0xC2 , 0x30 , 0x98 , 0x46 , 0x31 + , 0x18 , 0xC6 , 0x35 ,0xC , 0xCA , 0x31 ,0xC , 0xC6 + //20 + , 0x21 , 0x10 , 0x24 , 0x69 , 0x12 , 0xC2 , 0x31 , 0x14 + , 0xC4 , 0x71 , 8 , 0x4A , 0x22 , 0x49 , 0xAB , 0x6A + , 0xA8 , 0xAC , 0x49 , 0x51 , 0x32 , 0xD5 , 0x52 , 0x88 + , 0x93 , 0x6C , 0x94 , 0x22 , 0x15 , 0x54 , 0xD2 , 0x25 + //40 + , 0x96 , 0xD4 , 0x50 , 0xA5 , 0x46 , 0x21 , 8 , 0x85 + , 0x6B , 0x18 , 0xC4 , 0x63 , 0x10 , 0xCE , 0x6B , 0x18 + , 0x8C , 0x71 , 0x19 , 0x8C , 0x63 , 0x35 ,0xC , 0xC6 + , 0x33 , 0x99 , 0xCC , 0x6C , 0xB5 , 0x4E , 0xA2 , 0x99 + //60 + , 0x46 , 0x21 , 0x28 , 0x82 , 0x95 , 0x2E , 0xE3 , 0x30 + , 0x9C , 0xC5 , 0x30 , 0x9C , 0xA2 , 0xB1 , 0x9C , 0x67 + , 0x31 , 0x88 , 0x66 , 0x59 , 0x2C , 0x53 , 0x18 , 0x84 + , 0x67 , 0x50 , 0xCA , 0xE3 ,0xA , 0xAC , 0xAB , 0x30 + //80 + , 0xAC , 0x62 , 0x30 , 0x8C , 0x63 , 0x10 , 0x94 , 0x62 + , 0xB1 , 0x8C , 0x82 , 0x28 , 0x96 , 0x33 , 0x98 , 0xD6 + , 0xB5 , 0x4C , 0x62 , 0x29 , 0xA5 , 0x4A , 0xB5 , 0x9C + , 0xC6 , 0x31 , 0x14 , 0xD6 , 0x38 , 0x9C , 0x4B , 0xB4 + //A0 + , 0x86 , 0x65 , 0x18 , 0xAE , 0x67 , 0x1C , 0xA6 , 0x63 + , 0x19 , 0x96 , 0x23 , 0x19 , 0x84 , 0x13 , 8 , 0xA6 + , 0x52 , 0xAC , 0xCA , 0x22 , 0x89 , 0x6E , 0xAB , 0x19 + , 0x8C , 0x62 , 0x34 , 0xC4 , 0x62 , 0x19 , 0x86 , 0x63 + //C0 + , 0x18 , 0xC4 , 0x23 , 0x58 , 0xD6 , 0xA3 , 0x50 , 0x42 + , 0x54 , 0x4A , 0xAD , 0x4A , 0x25 , 0x11 , 0x6B , 0x64 + , 0x89 , 0x4A , 0x63 , 0x39 , 0x8A , 0x23 , 0x31 , 0x2A + , 0xEA , 0xA2 , 0xA9 , 0x44 , 0xC5 , 0x12 , 0xCD , 0x42 + //E0 + , 0x34 , 0x8C , 0x62 , 0x18 , 0x8C , 0x63 , 0x11 , 0x48 + , 0x66 , 0x31 , 0x9D , 0x44 , 0x33 , 0x1D , 0x46 , 0x31 + , 0x9C , 0xC6 , 0xB1 ,0xC , 0xCD , 0x32 , 0x88 , 0xC4 + , 0x73 , 0x18 , 0x86 , 0x73 , 8 , 0xD6 , 0x63 , 0x58 + //100 + , 7 , 0x81 , 0xE0 , 0xF0 , 0x3C , 7 , 0x87 , 0x90 + , 0x3C , 0x7C ,0xF , 0xC7 , 0xC0 , 0xC0 , 0xF0 , 0x7C + , 0x1E , 7 , 0x80 , 0x80 , 0 , 0x1C , 0x78 , 0x70 + , 0xF1 , 0xC7 , 0x1F , 0xC0 ,0xC , 0xFE , 0x1C , 0x1F + //120 + , 0x1F ,0xE ,0xA , 0x7A , 0xC0 , 0x71 , 0xF2 , 0x83 + , 0x8F , 3 ,0xF ,0xF ,0xC , 0 , 0x79 , 0xF8 + , 0x61 , 0xE0 , 0x43 ,0xF , 0x83 , 0xE7 , 0x18 , 0xF9 + , 0xC1 , 0x13 , 0xDA , 0xE9 , 0x63 , 0x8F ,0xF , 0x83 + //140 + , 0x83 , 0x87 , 0xC3 , 0x1F , 0x3C , 0x70 , 0xF0 , 0xE1 + , 0xE1 , 0xE3 , 0x87 , 0xB8 , 0x71 ,0xE , 0x20 , 0xE3 + , 0x8D , 0x48 , 0x78 , 0x1C , 0x93 , 0x87 , 0x30 , 0xE1 + , 0xC1 , 0xC1 , 0xE4 , 0x78 , 0x21 , 0x83 , 0x83 , 0xC3 + //160 + , 0x87 , 6 , 0x39 , 0xE5 , 0xC3 , 0x87 , 7 ,0xE + , 0x1C , 0x1C , 0x70 , 0xF4 , 0x71 , 0x9C , 0x60 , 0x36 + , 0x32 , 0xC3 , 0x1E , 0x3C , 0xF3 , 0x8F ,0xE , 0x3C + , 0x70 , 0xE3 , 0xC7 , 0x8F ,0xF ,0xF ,0xE , 0x3C + //180 + , 0x78 , 0xF0 , 0xE3 , 0x87 , 6 , 0xF0 , 0xE3 , 7 + , 0xC1 , 0x99 , 0x87 ,0xF , 0x18 , 0x78 , 0x70 , 0x70 + , 0xFC , 0xF3 , 0x10 , 0xB1 , 0x8C , 0x8C , 0x31 , 0x7C + , 0x70 , 0xE1 , 0x86 , 0x3C , 0x64 , 0x6C , 0xB0 , 0xE1 + //1A0 + , 0xE3 ,0xF , 0x23 , 0x8F ,0xF , 0x1E , 0x3E , 0x38 + , 0x3C , 0x38 , 0x7B , 0x8F , 7 ,0xE , 0x3C , 0xF4 + , 0x17 , 0x1E , 0x3C , 0x78 , 0xF2 , 0x9E , 0x72 , 0x49 + , 0xE3 , 0x25 , 0x36 , 0x38 , 0x58 , 0x39 , 0xE2 , 0xDE + //1C0 + , 0x3C , 0x78 , 0x78 , 0xE1 , 0xC7 , 0x61 , 0xE1 , 0xE1 + , 0xB0 , 0xF0 , 0xF0 , 0xC3 , 0xC7 ,0xE , 0x38 , 0xC0 + , 0xF0 , 0xCE , 0x73 , 0x73 , 0x18 , 0x34 , 0xB0 , 0xE1 + , 0xC7 , 0x8E , 0x1C , 0x3C , 0xF8 , 0x38 , 0xF0 , 0xE1 + //1E0 + , 0xC1 , 0x8B , 0x86 , 0x8F , 0x1C , 0x78 , 0x70 , 0xF0 + , 0x78 , 0xAC , 0xB1 , 0x8F , 0x39 , 0x31 , 0xDB , 0x38 + , 0x61 , 0xC3 ,0xE ,0xE , 0x38 , 0x78 , 0x73 , 0x17 + , 0x1E , 0x39 , 0x1E , 0x38 , 0x64 , 0xE1 , 0xF1 , 0xC1 + //200 + , 0x4E ,0xF , 0x40 , 0xA2 , 2 , 0xC5 , 0x8F , 0x81 + , 0xA1 , 0xFC , 0x12 , 8 , 0x64 , 0xE0 , 0x3C , 0x22 + , 0xE0 , 0x45 , 7 , 0x8E ,0xC , 0x32 , 0x90 , 0xF0 + , 0x1F , 0x20 , 0x49 , 0xE0 , 0xF8 ,0xC , 0x60 , 0xF0 + //220 + , 0x17 , 0x1A , 0x41 , 0xAA , 0xA4 , 0xD0 , 0x8D , 0x12 + , 0x82 , 0x1E , 0x1E , 3 , 0xF8 , 0x3E , 3 ,0xC + , 0x73 , 0x80 , 0x70 , 0x44 , 0x26 , 3 , 0x24 , 0xE1 + , 0x3E , 4 , 0x4E , 4 , 0x1C , 0xC1 , 9 , 0xCC + //240 + , 0x9E , 0x90 , 0x21 , 7 , 0x90 , 0x43 , 0x64 , 0xC0 + , 0xF , 0xC6 , 0x90 , 0x9C , 0xC1 , 0x5B , 3 , 0xE2 + , 0x1D , 0x81 , 0xE0 , 0x5E , 0x1D , 3 , 0x84 , 0xB8 + , 0x2C ,0xF , 0x80 , 0xB1 , 0x83 , 0xE0 , 0x30 , 0x41 + //260 + , 0x1E , 0x43 , 0x89 , 0x83 , 0x50 , 0xFC , 0x24 , 0x2E + , 0x13 , 0x83 , 0xF1 , 0x7C , 0x4C , 0x2C , 0xC9 ,0xD + , 0x83 , 0xB0 , 0xB5 , 0x82 , 0xE4 , 0xE8 , 6 , 0x9C + , 7 , 0xA0 , 0x99 , 0x1D , 7 , 0x3E , 0x82 , 0x8F + //280 + , 0x70 , 0x30 , 0x74 , 0x40 , 0xCA , 0x10 , 0xE4 , 0xE8 + , 0xF , 0x92 , 0x14 , 0x3F , 6 , 0xF8 , 0x84 , 0x88 + , 0x43 , 0x81 ,0xA , 0x34 , 0x39 , 0x41 , 0xC6 , 0xE3 + , 0x1C , 0x47 , 3 , 0xB0 , 0xB8 , 0x13 ,0xA , 0xC2 + //2A0 + , 0x64 , 0xF8 , 0x18 , 0xF9 , 0x60 , 0xB3 , 0xC0 , 0x65 + , 0x20 , 0x60 , 0xA6 , 0x8C , 0xC3 , 0x81 , 0x20 , 0x30 + , 0x26 , 0x1E , 0x1C , 0x38 , 0xD3 , 1 , 0xB0 , 0x26 + , 0x40 , 0xF4 ,0xB , 0xC3 , 0x42 , 0x1F , 0x85 , 0x32 + //2C0 + , 0x26 , 0x60 , 0x40 , 0xC9 , 0xCB , 1 , 0xEC , 0x11 + , 0x28 , 0x40 , 0xFA , 4 , 0x34 , 0xE0 , 0x70 , 0x4C + , 0x8C , 0x1D , 7 , 0x69 , 3 , 0x16 , 0xC8 , 4 + , 0x23 , 0xE8 , 0xC6 , 0x9A ,0xB , 0x1A , 3 , 0xE0 + //2E0 + , 0x76 , 6 , 5 , 0xCF , 0x1E , 0xBC , 0x58 , 0x31 + , 0x71 , 0x66 , 0 , 0xF8 , 0x3F , 4 , 0xFC ,0xC + , 0x74 , 0x27 , 0x8A , 0x80 , 0x71 , 0xC2 , 0x3A , 0x26 + , 6 , 0xC0 , 0x1F , 5 ,0xF , 0x98 , 0x40 , 0xAE + //300 + , 1 , 0x7F , 0xC0 , 7 , 0xFF , 0 ,0xE , 0xFE + , 0 , 3 , 0xDF , 0x80 , 3 , 0xEF , 0x80 , 0x1B + , 0xF1 , 0xC2 , 0 , 0xE7 , 0xE0 , 0x18 , 0xFC , 0xE0 + , 0x21 , 0xFC , 0x80 , 0x3C , 0xFC , 0x40 ,0xE , 0x7E + //320 + , 0 , 0x3F , 0x3E , 0 ,0xF , 0xFE , 0 , 0x1F + , 0xFF , 0 , 0x3E , 0xF0 , 7 , 0xFC , 0 , 0x7E + , 0x10 , 0x3F , 0xFF , 0 , 0x3F , 0x38 ,0xE , 0x7C + , 1 , 0x87 ,0xC , 0xFC , 0xC7 , 0 , 0x3E , 4 + //340 + , 0xF , 0x3E , 0x1F ,0xF ,0xF , 0x1F ,0xF , 2 + , 0x83 , 0x87 , 0xCF , 3 , 0x87 ,0xF , 0x3F , 0xC0 + , 7 , 0x9E , 0x60 , 0x3F , 0xC0 , 3 , 0xFE , 0 + , 0x3F , 0xE0 , 0x77 , 0xE1 , 0xC0 , 0xFE , 0xE0 , 0xC3 + //360 + , 0xE0 , 1 , 0xDF , 0xF8 , 3 , 7 , 0 , 0x7E + , 0x70 , 0 , 0x7C , 0x38 , 0x18 , 0xFE ,0xC , 0x1E + , 0x78 , 0x1C , 0x7C , 0x3E ,0xE , 0x1F , 0x1E , 0x1E + , 0x3E , 0 , 0x7F , 0x83 , 7 , 0xDB , 0x87 , 0x83 + //380 + , 7 , 0xC7 , 7 , 0x10 , 0x71 , 0xFF , 0 , 0x3F + , 0xE2 , 1 , 0xE0 , 0xC1 , 0xC3 , 0xE1 , 0 , 0x7F + , 0xC0 , 5 , 0xF0 , 0x20 , 0xF8 , 0xF0 , 0x70 , 0xFE + , 0x78 , 0x79 , 0xF8 , 2 , 0x3F ,0xC , 0x8F , 3 + //3a0 + , 0xF , 0x9F , 0xE0 , 0xC1 , 0xC7 , 0x87 , 3 , 0xC3 + , 0xC3 , 0xB0 , 0xE1 , 0xE1 , 0xC1 , 0xE3 , 0xE0 , 0x71 + , 0xF0 , 0 , 0xFC , 0x70 , 0x7C ,0xC , 0x3E , 0x38 + , 0xE , 0x1C , 0x70 , 0xC3 , 0xC7 , 3 , 0x81 , 0xC1 + //3c0 + , 0xC7 , 0xE7 , 0 ,0xF , 0xC7 , 0x87 , 0x19 , 9 + , 0xEF , 0xC4 , 0x33 , 0xE0 , 0xC1 , 0xFC , 0xF8 , 0x70 + , 0xF0 , 0x78 , 0xF8 , 0xF0 , 0x61 , 0xC7 , 0 , 0x1F + , 0xF8 , 1 , 0x7C , 0xF8 , 0xF0 , 0x78 , 0x70 , 0x3C + //3e0 + , 0x7C , 0xCE ,0xE , 0x21 , 0x83 , 0xCF , 8 , 7 + , 0x8F , 8 , 0xC1 , 0x87 , 0x8F , 0x80 , 0xC7 , 0xE3 + , 0 , 7 , 0xF8 , 0xE0 , 0xEF , 0 , 0x39 , 0xF7 + , 0x80 ,0xE , 0xF8 , 0xE1 , 0xE3 , 0xF8 , 0x21 , 0x9F + //400 + , 0xC0 , 0xFF , 3 , 0xF8 , 7 , 0xC0 , 0x1F , 0xF8 + , 0xC4 , 4 , 0xFC , 0xC4 , 0xC1 , 0xBC , 0x87 , 0xF0 + , 0xF , 0xC0 , 0x7F , 5 , 0xE0 , 0x25 , 0xEC , 0xC0 + , 0x3E , 0x84 , 0x47 , 0xF0 , 0x8E , 3 , 0xF8 , 3 + //420 + , 0xFB , 0xC0 , 0x19 , 0xF8 , 7 , 0x9C ,0xC , 0x17 + , 0xF8 , 7 , 0xE0 , 0x1F , 0xA1 , 0xFC ,0xF , 0xFC + , 1 , 0xF0 , 0x3F , 0 , 0xFE , 3 , 0xF0 , 0x1F + , 0 , 0xFD , 0 , 0xFF , 0x88 ,0xD , 0xF9 , 1 + //440 + , 0xFF , 0 , 0x70 , 7 , 0xC0 , 0x3E , 0x42 , 0xF3 + , 0xD , 0xC4 , 0x7F , 0x80 , 0xFC , 7 , 0xF0 , 0x5E + , 0xC0 , 0x3F , 0 , 0x78 , 0x3F , 0x81 , 0xFF , 1 + , 0xF8 , 1 , 0xC3 , 0xE8 ,0xC , 0xE4 , 0x64 , 0x8F + ////460 + , 0xE4 ,0xF , 0xF0 , 7 , 0xF0 , 0xC2 , 0x1F , 0 + , 0x7F , 0xC0 , 0x6F , 0x80 , 0x7E , 3 , 0xF8 , 7 + , 0xF0 , 0x3F , 0xC0 , 0x78 ,0xF , 0x82 , 7 , 0xFE + , 0x22 , 0x77 , 0x70 , 2 , 0x76 , 3 , 0xFE , 0 + //480 + , 0xFE , 0x67 , 0 , 0x7C , 0xC7 , 0xF1 , 0x8E , 0xC6 + , 0x3B , 0xE0 , 0x3F , 0x84 , 0xF3 , 0x19 , 0xD8 , 3 + , 0x99 , 0xFC , 9 , 0xB8 ,0xF , 0xF8 , 0 , 0x9D + , 0x24 , 0x61 , 0xF9 ,0xD , 0 , 0xFD , 3 , 0xF0 + //4a0 + , 0x1F , 0x90 , 0x3F , 1 , 0xF8 , 0x1F , 0xD0 ,0xF + , 0xF8 , 0x37 , 1 , 0xF8 , 7 , 0xF0 ,0xF , 0xC0 + , 0x3F , 0 , 0xFE , 3 , 0xF8 ,0xF , 0xC0 , 0x3F + , 0 , 0xFA , 3 , 0xF0 ,0xF , 0x80 , 0xFF , 1 + //4c0 + , 0xB8 , 7 , 0xF0 , 1 , 0xFC , 1 , 0xBC , 0x80 + , 0x13 , 0x1E , 0 , 0x7F , 0xE1 , 0x40 , 0x7F , 0xA0 + , 0x7F , 0xB0 , 0 , 0x3F , 0xC0 , 0x1F , 0xC0 , 0x38 + , 0xF , 0xF0 , 0x1F , 0x80 , 0xFF , 1 , 0xFC , 3 + //4e0 + , 0xF1 , 0x7E , 1 , 0xFE , 1 , 0xF0 , 0xFF , 0 + , 0x7F , 0xC0 , 0x1D , 7 , 0xF0 ,0xF , 0xC0 , 0x7E + , 6 , 0xE0 , 7 , 0xE0 ,0xF , 0xF8 , 6 , 0xC1 + , 0xFE , 1 , 0xFC , 3 , 0xE0 ,0xF , 0 , 0xFC }; diff --git a/src/render.c b/src/render.c index 102d4b9..3bce174 100755 --- a/src/render.c +++ b/src/render.c @@ -56,27 +56,22 @@ extern char *buffer; //timetable for more accurate c64 simulation int timetable[5][5] = { - {162, 167, 167, 127, 128}, - {226, 60, 60, 0, 0}, - {225, 60, 59, 0, 0}, - {200, 0, 0, 54, 55}, - {199, 0, 0, 54, 54} + {162, 167, 167, 127, 128}, + {226, 60, 60, 0, 0}, + {225, 60, 59, 0, 0}, + {200, 0, 0, 54, 55}, + {199, 0, 0, 54, 54} }; -static unsigned oldtimetableindex = 0; -void Output8BitAry(int index, unsigned char ary[5]) +void Output(int index, unsigned char A) { - int k; - bufferpos += timetable[oldtimetableindex][index]; - oldtimetableindex = index; - // write a little bit in advance - for(k=0; k<5; k++) - buffer[bufferpos/50 + k] = ary[k]; -} -void Output8Bit(int index, unsigned char A) -{ - unsigned char ary[5] = {A,A,A,A,A}; - Output8BitAry(index, ary); + static unsigned oldtimetableindex = 0; + int k; + bufferpos += timetable[oldtimetableindex][index]; + oldtimetableindex = index; + // write a little bit in advance + for(k=0; k<5; k++) + buffer[bufferpos/50 + k] = (A & 15)*16; } @@ -85,7 +80,6 @@ void Output8Bit(int index, unsigned char A) - //written by me because of different table positions. // mem[47] = ... // 168=pitches @@ -97,34 +91,34 @@ void Output8Bit(int index, unsigned char A) // 174=amplitude3 unsigned char Read(unsigned char p, unsigned char Y) { - switch(p) - { - case 168: return pitches[Y]; - case 169: return frequency1[Y]; - case 170: return frequency2[Y]; - case 171: return frequency3[Y]; - case 172: return amplitude1[Y]; - case 173: return amplitude2[Y]; - case 174: return amplitude3[Y]; - } - printf("Error reading to tables"); - return 0; + switch(p) + { + case 168: return pitches[Y]; + case 169: return frequency1[Y]; + case 170: return frequency2[Y]; + case 171: return frequency3[Y]; + case 172: return amplitude1[Y]; + case 173: return amplitude2[Y]; + case 174: return amplitude3[Y]; + } + printf("Error reading to tables"); + return 0; } void Write(unsigned char p, unsigned char Y, unsigned char value) { - switch(p) - { - case 168: pitches[Y] = value; return; - case 169: frequency1[Y] = value; return; - case 170: frequency2[Y] = value; return; - case 171: frequency3[Y] = value; return; - case 172: amplitude1[Y] = value; return; - case 173: amplitude2[Y] = value; return; - case 174: amplitude3[Y] = value; return; - } - printf("Error writing to tables\n"); + switch(p) + { + case 168: pitches[Y] = value; return; + case 169: frequency1[Y] = value; return; + case 170: frequency2[Y] = value; return; + case 171: frequency3[Y] = value; return; + case 172: amplitude1[Y] = value; return; + case 173: amplitude2[Y] = value; return; + case 174: amplitude3[Y] = value; return; + } + printf("Error writing to tables\n"); } @@ -187,154 +181,154 @@ void Write(unsigned char p, unsigned char Y, unsigned char value) // Code48227() void RenderSample(unsigned char *mem66) { - int tempA; - // current phoneme's index - mem49 = Y; + int tempA; + // current phoneme's index + mem49 = Y; - // mask low three bits and subtract 1 get value to - // convert 0 bits on unvoiced samples. - A = mem39&7; - X = A-1; + // mask low three bits and subtract 1 get value to + // convert 0 bits on unvoiced samples. + A = mem39&7; + X = A-1; // store the result - mem56 = X; + mem56 = X; - // determine which offset to use from table { 0x18, 0x1A, 0x17, 0x17, 0x17 } - // T, S, Z 0 0x18 - // CH, J, SH, ZH 1 0x1A - // P, F*, V, TH, DH 2 0x17 - // /H 3 0x17 - // /X 4 0x17 + // determine which offset to use from table { 0x18, 0x1A, 0x17, 0x17, 0x17 } + // T, S, Z 0 0x18 + // CH, J, SH, ZH 1 0x1A + // P, F*, V, TH, DH 2 0x17 + // /H 3 0x17 + // /X 4 0x17 // get value from the table - mem53 = tab48426[X]; - mem47 = X; //46016+mem[56]*256 + mem53 = tab48426[X]; + mem47 = X; //46016+mem[56]*256 - // voiced sample? - A = mem39 & 248; - if(A == 0) - { + // voiced sample? + A = mem39 & 248; + if(A == 0) + { // voiced phoneme: Z*, ZH, V*, DH - Y = mem49; - A = pitches[mem49] >> 4; + Y = mem49; + A = pitches[mem49] >> 4; - // jump to voiced portion - goto pos48315; - } + // jump to voiced portion + goto pos48315; + } - Y = A ^ 255; + Y = A ^ 255; pos48274: // step through the 8 bits in the sample - mem56 = 8; + mem56 = 8; - // get the next sample from the table + // get the next sample from the table // mem47*256 = offset to start of samples - A = sampleTable[mem47*256+Y]; + A = sampleTable[mem47*256+Y]; pos48280: // left shift to get the high bit - tempA = A; - A = A << 1; - //48281: BCC 48290 + tempA = A; + A = A << 1; + //48281: BCC 48290 - // bit not set? - if ((tempA & 128) == 0) - { + // bit not set? + if ((tempA & 128) == 0) + { // convert the bit to value from table - X = mem53; - //mem[54296] = X; + X = mem53; + //mem[54296] = X; // output the byte - Output8Bit(1, (X&0x0f) * 16); - // if X != 0, exit loop - if(X != 0) goto pos48296; - } + Output(1, X); + // if X != 0, exit loop + if(X != 0) goto pos48296; + } - // output a 5 for the on bit - Output8Bit(2, 5 * 16); + // output a 5 for the on bit + Output(2, 5); - //48295: NOP + //48295: NOP pos48296: - X = 0; + X = 0; // decrement counter - mem56--; + mem56--; - // if not done, jump to top of loop - if (mem56 != 0) goto pos48280; + // if not done, jump to top of loop + if (mem56 != 0) goto pos48280; - // increment position - Y++; - if (Y != 0) goto pos48274; + // increment position + Y++; + if (Y != 0) goto pos48274; - // restore values and return - mem44 = 1; - Y = mem49; - return; + // restore values and return + mem44 = 1; + Y = mem49; + return; - unsigned char phase1; + unsigned char phase1; pos48315: // handle voiced samples here // number of samples? - phase1 = A ^ 255; + phase1 = A ^ 255; - Y = *mem66; - do - { - //pos48321: + Y = *mem66; + do + { + //pos48321: // shift through all 8 bits - mem56 = 8; - //A = Read(mem47, Y); + mem56 = 8; + //A = Read(mem47, Y); - // fetch value from table - A = sampleTable[mem47*256+Y]; + // fetch value from table + A = sampleTable[mem47*256+Y]; // loop 8 times - //pos48327: - do - { - //48327: ASL A - //48328: BCC 48337 - - // left shift and check high bit - tempA = A; - A = A << 1; - if ((tempA & 128) != 0) - { + //pos48327: + do + { + //48327: ASL A + //48328: BCC 48337 + + // left shift and check high bit + tempA = A; + A = A << 1; + if ((tempA & 128) != 0) + { // if bit set, output 26 - X = 26; - Output8Bit(3, (X&0xf)*16); - } else - { - //timetable 4 - // bit is not set, output a 6 - X=6; - Output8Bit(4, (X&0xf)*16); - } - - mem56--; - } while(mem56 != 0); + X = 26; + Output(3, X); + } else + { + //timetable 4 + // bit is not set, output a 6 + X=6; + Output(4, X); + } + + mem56--; + } while(mem56 != 0); // move ahead in the table - Y++; + Y++; - // continue until counter done - phase1++; + // continue until counter done + phase1++; - } while (phase1 != 0); - // if (phase1 != 0) goto pos48321; + } while (phase1 != 0); + // if (phase1 != 0) goto pos48321; - // restore values and return - A = 1; - mem44 = 1; - *mem66 = Y; - Y = mem49; - return; + // restore values and return + A = 1; + mem44 = 1; + *mem66 = Y; + Y = mem49; + return; } @@ -358,20 +352,21 @@ void RenderSample(unsigned char *mem66) //void Code47574() void Render() { - unsigned char phase1 = 0; //mem43 - unsigned char phase2=0; - unsigned char phase3=0; - unsigned char mem66=0; - unsigned char mem38=0; - unsigned char mem40=0; - unsigned char speedcounter=0; //mem45 - unsigned char mem48=0; - int i; - if (phonemeIndexOutput[0] == 255) return; //exit if no data - - A = 0; - X = 0; - mem44 = 0; + unsigned char phase1 = 0; //mem43 + unsigned char phase2; + unsigned char phase3; + unsigned char mem66; + unsigned char mem38; + unsigned char mem40; + unsigned char speedcounter; //mem45 + unsigned char mem48; + int i; + int carry; + if (phonemeIndexOutput[0] == 255) return; //exit if no data + + A = 0; + X = 0; + mem44 = 0; // CREATE FRAMES @@ -387,58 +382,58 @@ void Render() do { // get the index - Y = mem44; - // get the phoneme at the index - A = phonemeIndexOutput[mem44]; - mem56 = A; + Y = mem44; + // get the phoneme at the index + A = phonemeIndexOutput[mem44]; + mem56 = A; - // if terminal phoneme, exit the loop - if (A == 255) break; + // if terminal phoneme, exit the loop + if (A == 255) break; - // period phoneme *. - if (A == 1) - { + // period phoneme *. + if (A == 1) + { // add rising inflection - A = 1; - mem48 = 1; - //goto pos48376; - AddInflection(mem48, phase1); - } - /* - if (A == 2) goto pos48372; - */ - - // question mark phoneme? - if (A == 2) - { + A = 1; + mem48 = 1; + //goto pos48376; + AddInflection(mem48, phase1); + } + /* + if (A == 2) goto pos48372; + */ + + // question mark phoneme? + if (A == 2) + { // create falling inflection - mem48 = 255; - AddInflection(mem48, phase1); - } - // pos47615: + mem48 = 255; + AddInflection(mem48, phase1); + } + // pos47615: // get the stress amount (more stress = higher pitch) - phase1 = tab47492[stressOutput[Y] + 1]; + phase1 = tab47492[stressOutput[Y] + 1]; // get number of frames to write - phase2 = phonemeLengthOutput[Y]; - Y = mem56; - - // copy from the source to the frames list - do - { - frequency1[X] = freq1data[Y]; // F1 frequency - frequency2[X] = freq2data[Y]; // F2 frequency - frequency3[X] = freq3data[Y]; // F3 frequency - amplitude1[X] = ampl1data[Y]; // F1 amplitude - amplitude2[X] = ampl2data[Y]; // F2 amplitude - amplitude3[X] = ampl3data[Y]; // F3 amplitude - sampledConsonantFlag[X] = sampledConsonantFlags[Y]; // phoneme data for sampled consonants - pitches[X] = pitch + phase1; // pitch - X++; - phase2--; - } while(phase2 != 0); - mem44++; + phase2 = phonemeLengthOutput[Y]; + Y = mem56; + + // copy from the source to the frames list + do + { + frequency1[X] = freq1data[Y]; // F1 frequency + frequency2[X] = freq2data[Y]; // F2 frequency + frequency3[X] = freq3data[Y]; // F3 frequency + amplitude1[X] = ampl1data[Y]; // F1 amplitude + amplitude2[X] = ampl2data[Y]; // F2 amplitude + amplitude3[X] = ampl3data[Y]; // F3 amplitude + sampledConsonantFlag[X] = sampledConsonantFlags[Y]; // phoneme data for sampled consonants + pitches[X] = pitch + phase1; // pitch + X++; + phase2--; + } while(phase2 != 0); + mem44++; } while(mem44 != 0); // ------------------- //pos47694: @@ -572,65 +567,65 @@ do // 241 2 10 2 65 1 96 59 * <-- OutBlendFrames = 1 // 241 0 6 0 73 0 99 61 - A = 0; - mem44 = 0; - mem49 = 0; // mem49 starts at as 0 - X = 0; - while(1) //while No. 1 - { + A = 0; + mem44 = 0; + mem49 = 0; // mem49 starts at as 0 + X = 0; + while(1) //while No. 1 + { // get the current and following phoneme - Y = phonemeIndexOutput[X]; - A = phonemeIndexOutput[X+1]; - X++; + Y = phonemeIndexOutput[X]; + A = phonemeIndexOutput[X+1]; + X++; - // exit loop at end token - if (A == 255) break;//goto pos47970; + // exit loop at end token + if (A == 255) break;//goto pos47970; // get the ranking of each phoneme - X = A; - mem56 = blendRank[A]; - A = blendRank[Y]; + X = A; + mem56 = blendRank[A]; + A = blendRank[Y]; - // compare the rank - lower rank value is stronger - if (A == mem56) - { + // compare the rank - lower rank value is stronger + if (A == mem56) + { // same rank, so use out blend lengths from each phoneme - phase1 = outBlendLength[Y]; - phase2 = outBlendLength[X]; - } else - if (A < mem56) - { + phase1 = outBlendLength[Y]; + phase2 = outBlendLength[X]; + } else + if (A < mem56) + { // first phoneme is stronger, so us it's blend lengths - phase1 = inBlendLength[X]; - phase2 = outBlendLength[X]; - } else - { + phase1 = inBlendLength[X]; + phase2 = outBlendLength[X]; + } else + { // second phoneme is stronger, so use it's blend lengths // note the out/in are swapped - phase1 = outBlendLength[Y]; - phase2 = inBlendLength[Y]; - } - - Y = mem44; - A = mem49 + phonemeLengthOutput[mem44]; // A is mem49 + length - mem49 = A; // mem49 now holds length + position - A = A + phase2; //Maybe Problem because of carry flag - - //47776: ADC 42 - speedcounter = A; - mem47 = 168; - phase3 = mem49 - phase1; // what is mem49 - A = phase1 + phase2; // total transition? - mem38 = A; - - X = A; - X -= 2; - if ((X & 128) == 0) - do //while No. 2 - { - //pos47810: + phase1 = outBlendLength[Y]; + phase2 = inBlendLength[Y]; + } + + Y = mem44; + A = mem49 + phonemeLengthOutput[mem44]; // A is mem49 + length + mem49 = A; // mem49 now holds length + position + A = A + phase2; //Maybe Problem because of carry flag + + //47776: ADC 42 + speedcounter = A; + mem47 = 168; + phase3 = mem49 - phase1; // what is mem49 + A = phase1 + phase2; // total transition? + mem38 = A; + + X = A; + X -= 2; + if ((X & 128) == 0) + do //while No. 2 + { + //pos47810: // mem47 is used to index the tables: // 168 pitches[] @@ -641,98 +636,96 @@ do // 173 amplitude2 // 174 amplitude3 - mem40 = mem38; + mem40 = mem38; - if (mem47 == 168) // pitch - { + if (mem47 == 168) // pitch + { // unlike the other values, the pitches[] interpolates from // the middle of the current phoneme to the middle of the // next phoneme - unsigned char mem36, mem37; - // half the width of the current phoneme - mem36 = phonemeLengthOutput[mem44] >> 1; - // half the width of the next phoneme - mem37 = phonemeLengthOutput[mem44+1] >> 1; - // sum the values - mem40 = mem36 + mem37; // length of both halves - mem37 += mem49; // center of next phoneme - mem36 = mem49 - mem36; // center index of current phoneme - A = Read(mem47, mem37); // value at center of next phoneme - end interpolation value - //A = mem[address]; - - Y = mem36; // start index of interpolation - mem53 = A - Read(mem47, mem36); // value to center of current phoneme - } else - { + unsigned char mem36, mem37; + // half the width of the current phoneme + mem36 = phonemeLengthOutput[mem44] >> 1; + // half the width of the next phoneme + mem37 = phonemeLengthOutput[mem44+1] >> 1; + // sum the values + mem40 = mem36 + mem37; // length of both halves + mem37 += mem49; // center of next phoneme + mem36 = mem49 - mem36; // center index of current phoneme + A = Read(mem47, mem37); // value at center of next phoneme - end interpolation value + //A = mem[address]; + + Y = mem36; // start index of interpolation + mem53 = A - Read(mem47, mem36); // value to center of current phoneme + } else + { // value to interpolate to - A = Read(mem47, speedcounter); - // position to start interpolation from - Y = phase3; - // value to interpolate from - mem53 = A - Read(mem47, phase3); - } - - //Code47503(mem40); - // ML : Code47503 is division with remainder, and mem50 gets the sign - - // calculate change per frame - signed char m53 = (signed char)mem53; - mem50 = mem53 & 128; - unsigned char m53abs = abs(m53); - mem51 = m53abs % mem40; //abs((char)m53) % mem40; - mem53 = (unsigned char)((signed char)(m53) / mem40); + A = Read(mem47, speedcounter); + // position to start interpolation from + Y = phase3; + // value to interpolate from + mem53 = A - Read(mem47, phase3); + } + + //Code47503(mem40); + // ML : Code47503 is division with remainder, and mem50 gets the sign + + // calculate change per frame + mem50 = (((char)(mem53) < 0) ? 128 : 0); + mem51 = abs((char)mem53) % mem40; + mem53 = (unsigned char)((char)(mem53) / mem40); // interpolation range - X = mem40; // number of frames to interpolate over - Y = phase3; // starting frame + X = mem40; // number of frames to interpolate over + Y = phase3; // starting frame // linearly interpolate values - mem56 = 0; - //47907: CLC - //pos47908: - while(1) //while No. 3 - { - A = Read(mem47, Y) + mem53; //carry alway cleared - - mem48 = A; - Y++; - X--; - if(X == 0) break; - - mem56 += mem51; - if (mem56 >= mem40) //??? - { - mem56 -= mem40; //carry? is set - //if ((mem56 & 128)==0) - if ((mem50 & 128)==0) - { - //47935: BIT 50 - //47937: BMI 47943 - if(mem48 != 0) mem48++; - } else mem48--; - } - //pos47945: - Write(mem47, Y, mem48); - } //while No. 3 - - //pos47952: - mem47++; - //if (mem47 != 175) goto pos47810; - } while (mem47 != 175); //while No. 2 - //pos47963: - mem44++; - X = mem44; - } //while No. 1 - - //goto pos47701; - //pos47970: + mem56 = 0; + //47907: CLC + //pos47908: + while(1) //while No. 3 + { + A = Read(mem47, Y) + mem53; //carry alway cleared + + mem48 = A; + Y++; + X--; + if(X == 0) break; + + mem56 += mem51; + if (mem56 >= mem40) //??? + { + mem56 -= mem40; //carry? is set + //if ((mem56 & 128)==0) + if ((mem50 & 128)==0) + { + //47935: BIT 50 + //47937: BMI 47943 + if(mem48 != 0) mem48++; + } else mem48--; + } + //pos47945: + Write(mem47, Y, mem48); + } //while No. 3 + + //pos47952: + mem47++; + //if (mem47 != 175) goto pos47810; + } while (mem47 != 175); //while No. 2 + //pos47963: + mem44++; + X = mem44; + } //while No. 1 + + //goto pos47701; + //pos47970: // add the length of this phoneme - mem48 = mem49 + phonemeLengthOutput[mem44]; + mem48 = mem49 + phonemeLengthOutput[mem44]; // ASSIGN PITCH CONTOUR @@ -742,45 +735,45 @@ do // pitch level (monotone). - // don't adjust pitch if in sing mode - if (!singmode) - { + // don't adjust pitch if in sing mode + if (!singmode) + { // iterate through the buffer - for(i=0; i<256; i++) { + for(i=0; i<256; i++) { // subtract half the frequency of the formant 1. // this adds variety to the voice - pitches[i] -= (frequency1[i] >> 1); + pitches[i] -= (frequency1[i] >> 1); } - } + } - phase1 = 0; - phase2 = 0; - phase3 = 0; - mem49 = 0; - speedcounter = 72; //sam standard speed + phase1 = 0; + phase2 = 0; + phase3 = 0; + mem49 = 0; + speedcounter = 72; //sam standard speed // RESCALE AMPLITUDE // // Rescale volume from a linear scale to decibels. // - //amplitude rescaling - for(i=255; i>=0; i--) - { - amplitude1[i] = amplitudeRescale[amplitude1[i]]; - amplitude2[i] = amplitudeRescale[amplitude2[i]]; - amplitude3[i] = amplitudeRescale[amplitude3[i]]; - } + //amplitude rescaling + for(i=255; i>=0; i--) + { + amplitude1[i] = amplitudeRescale[amplitude1[i]]; + amplitude2[i] = amplitudeRescale[amplitude2[i]]; + amplitude3[i] = amplitudeRescale[amplitude3[i]]; + } - Y = 0; - A = pitches[0]; - mem44 = A; - X = A; - mem38 = A - (A>>2); // 3/4*A ??? + Y = 0; + A = pitches[0]; + mem44 = A; + X = A; + mem38 = A - (A>>2); // 3/4*A ??? if (debug) { - PrintOutput(sampledConsonantFlag, frequency1, frequency2, frequency3, amplitude1, amplitude2, amplitude3, pitches); + PrintOutput(sampledConsonantFlag, frequency1, frequency2, frequency3, amplitude1, amplitude2, amplitude3, pitches); } // PROCESS THE FRAMES @@ -792,154 +785,143 @@ if (debug) // To simulate them being driven by the glottal pulse, the waveforms are // reset at the beginning of each glottal pulse. - //finally the loop for sound output - //pos48078: - while(1) - { + //finally the loop for sound output + //pos48078: + while(1) + { // get the sampled information on the phoneme - A = sampledConsonantFlag[Y]; - mem39 = A; + A = sampledConsonantFlag[Y]; + mem39 = A; - // unvoiced sampled phoneme? - A = A & 248; - if(A != 0) - { + // unvoiced sampled phoneme? + A = A & 248; + if(A != 0) + { // render the sample for the phoneme - RenderSample(&mem66); + RenderSample(&mem66); - // skip ahead two in the phoneme buffer - Y += 2; - mem48 -= 2; - } else - { + // skip ahead two in the phoneme buffer + Y += 2; + mem48 -= 2; + } else + { // simulate the glottal pulse and formants - unsigned char ary[5]; - unsigned int p1 = phase1 * 256; // Fixed point integers because we need to divide later on - unsigned int p2 = phase2 * 256; - unsigned int p3 = phase3 * 256; - int k; - for (k=0; k<5; k++) { - signed char sp1 = (signed char)sinus[0xff & (p1>>8)]; - signed char sp2 = (signed char)sinus[0xff & (p2>>8)]; - signed char rp3 = (signed char)rectangle[0xff & (p3>>8)]; - signed int sin1 = sp1 * ((unsigned char)amplitude1[Y] & 0x0f); - signed int sin2 = sp2 * ((unsigned char)amplitude2[Y] & 0x0f); - signed int rect = rp3 * ((unsigned char)amplitude3[Y] & 0x0f); - signed int mux = sin1 + sin2 + rect; - mux /= 32; - mux += 128; // Go from signed to unsigned amplitude - ary[k] = mux; - p1 += frequency1[Y] * 256 / 4; // Compromise, this becomes a shift and works well - p2 += frequency2[Y] * 256 / 4; - p3 += frequency3[Y] * 256 / 4; - } - // output the accumulated value - Output8BitAry(0, ary); - speedcounter--; - if (speedcounter != 0) goto pos48155; - Y++; //go to next amplitude - - // decrement the frame count - mem48--; - } - - // if the frame count is zero, exit the loop - if(mem48 == 0) return; - speedcounter = speed; + mem56 = multtable[sinus[phase1] | amplitude1[Y]]; + + carry = 0; + if ((mem56+multtable[sinus[phase2] | amplitude2[Y]] ) > 255) carry = 1; + mem56 += multtable[sinus[phase2] | amplitude2[Y]]; + A = mem56 + multtable[rectangle[phase3] | amplitude3[Y]] + (carry?1:0); + A = ((A + 136) & 255) >> 4; //there must be also a carry + //mem[54296] = A; + + // output the accumulated value + Output(0, A); + speedcounter--; + if (speedcounter != 0) goto pos48155; + Y++; //go to next amplitude + + // decrement the frame count + mem48--; + } + + // if the frame count is zero, exit the loop + if(mem48 == 0) return; + speedcounter = speed; pos48155: // decrement the remaining length of the glottal pulse - mem44--; + mem44--; - // finished with a glottal pulse? - if(mem44 == 0) - { + // finished with a glottal pulse? + if(mem44 == 0) + { pos48159: // fetch the next glottal pulse length - A = pitches[Y]; - mem44 = A; - A = A - (A>>2); - mem38 = A; - - // reset the formant wave generators to keep them in - // sync with the glottal pulse - phase1 = 0; - phase2 = 0; - phase3 = 0; - continue; - } - - // decrement the count - mem38--; - - // is the count non-zero and the sampled flag is zero? - if((mem38 != 0) || (mem39 == 0)) - { + A = pitches[Y]; + mem44 = A; + A = A - (A>>2); + mem38 = A; + + // reset the formant wave generators to keep them in + // sync with the glottal pulse + phase1 = 0; + phase2 = 0; + phase3 = 0; + continue; + } + + // decrement the count + mem38--; + + // is the count non-zero and the sampled flag is zero? + if((mem38 != 0) || (mem39 == 0)) + { // reset the phase of the formants to match the pulse - phase1 += frequency1[Y]; - phase2 += frequency2[Y]; - phase3 += frequency3[Y]; - continue; - } + phase1 += frequency1[Y]; + phase2 += frequency2[Y]; + phase3 += frequency3[Y]; + continue; + } - // voiced sampled phonemes interleave the sample with the - // glottal pulse. The sample flag is non-zero, so render - // the sample for the phoneme. - RenderSample(&mem66); - goto pos48159; - } //while + // voiced sampled phonemes interleave the sample with the + // glottal pulse. The sample flag is non-zero, so render + // the sample for the phoneme. + RenderSample(&mem66); + goto pos48159; + } //while // The following code is never reached. It's left over from when // the voiced sample code was part of this loop, instead of part // of RenderSample(); - //pos48315: - int tempA; - phase1 = A ^ 255; - Y = mem66; - do - { - //pos48321: - - mem56 = 8; - A = Read(mem47, Y); - - //pos48327: - do - { - //48327: ASL A - //48328: BCC 48337 - tempA = A; - A = A << 1; - if ((tempA & 128) != 0) - { - X = 26; - // mem[54296] = X; - bufferpos += 150; - buffer[bufferpos/50] = (X & 15)*16; - } else - { - //mem[54296] = 6; - X=6; - bufferpos += 150; - buffer[bufferpos/50] = (X & 15)*16; - } - - for(X = wait2; X>0; X--); //wait - mem56--; - } while(mem56 != 0); - - Y++; - phase1++; - - } while (phase1 != 0); - // if (phase1 != 0) goto pos48321; - A = 1; - mem44 = 1; - mem66 = Y; - Y = mem49; - return; + //pos48315: + int tempA; + phase1 = A ^ 255; + Y = mem66; + do + { + //pos48321: + + mem56 = 8; + A = Read(mem47, Y); + + //pos48327: + do + { + //48327: ASL A + //48328: BCC 48337 + tempA = A; + A = A << 1; + if ((tempA & 128) != 0) + { + X = 26; + // mem[54296] = X; + bufferpos += 150; + buffer[bufferpos/50] = (X & 15)*16; + } else + { + //mem[54296] = 6; + X=6; + bufferpos += 150; + buffer[bufferpos/50] = (X & 15)*16; + } + + for(X = wait2; X>0; X--); //wait + mem56--; + } while(mem56 != 0); + + Y++; + phase1++; + + } while (phase1 != 0); + // if (phase1 != 0) goto pos48321; + A = 1; + mem44 = 1; + mem66 = Y; + Y = mem49; + return; } @@ -949,46 +931,46 @@ if (debug) void AddInflection(unsigned char mem48, unsigned char phase1) { - //pos48372: - // mem48 = 255; + //pos48372: + // mem48 = 255; //pos48376: // store the location of the punctuation - mem49 = X; - A = X; - int Atemp = A; + mem49 = X; + A = X; + int Atemp = A; - // backup 30 frames - A = A - 30; - // if index is before buffer, point to start of buffer - if (Atemp <= 30) A=0; - X = A; + // backup 30 frames + A = A - 30; + // if index is before buffer, point to start of buffer + if (Atemp <= 30) A=0; + X = A; - // FIXME: Explain this fix better, it's not obvious - // ML : A =, fixes a problem with invalid pitch with '.' - while( (A=pitches[X]) == 127) X++; + // FIXME: Explain this fix better, it's not obvious + // ML : A =, fixes a problem with invalid pitch with '.' + while( (A=pitches[X]) == 127) X++; pos48398: - //48398: CLC - //48399: ADC 48 + //48398: CLC + //48399: ADC 48 - // add the inflection direction - A += mem48; - phase1 = A; + // add the inflection direction + A += mem48; + phase1 = A; - // set the inflection - pitches[X] = A; + // set the inflection + pitches[X] = A; pos48406: // increment the position - X++; + X++; - // exit if the punctuation has been reached - if (X == mem49) return; //goto pos47615; - if (pitches[X] == 255) goto pos48406; - A = phase1; - goto pos48398; + // exit if the punctuation has been reached + if (X == mem49) return; //goto pos47615; + if (pitches[X] == 255) goto pos48406; + A = phase1; + goto pos48398; } /* @@ -998,108 +980,108 @@ void AddInflection(unsigned char mem48, unsigned char phase1) */ void SetMouthThroat(unsigned char mouth, unsigned char throat) { - unsigned char initialFrequency; - unsigned char newFrequency = 0; - //unsigned char mouth; //mem38880 - //unsigned char throat; //mem38881 - - // mouth formants (F1) 5..29 - static unsigned char mouthFormants5_29[30] = { // AF, save some stack - 0, 0, 0, 0, 0, 10, - 14, 19, 24, 27, 23, 21, 16, 20, 14, 18, 14, 18, 18, - 16, 13, 15, 11, 18, 14, 11, 9, 6, 6, 6}; - - // throat formants (F2) 5..29 - static unsigned char throatFormants5_29[30] = { // AF, save some stack - 255, 255, - 255, 255, 255, 84, 73, 67, 63, 40, 44, 31, 37, 45, 73, 49, - 36, 30, 51, 37, 29, 69, 24, 50, 30, 24, 83, 46, 54, 86}; - - // there must be no zeros in this 2 tables - // formant 1 frequencies (mouth) 48..53 - unsigned char mouthFormants48_53[6] = {19, 27, 21, 27, 18, 13}; - - // formant 2 frequencies (throat) 48..53 - unsigned char throatFormants48_53[6] = {72, 39, 31, 43, 30, 34}; - - unsigned char pos = 5; //mem39216 + unsigned char initialFrequency; + unsigned char newFrequency = 0; + //unsigned char mouth; //mem38880 + //unsigned char throat; //mem38881 + + // mouth formants (F1) 5..29 + unsigned char mouthFormants5_29[30] = { + 0, 0, 0, 0, 0, 10, + 14, 19, 24, 27, 23, 21, 16, 20, 14, 18, 14, 18, 18, + 16, 13, 15, 11, 18, 14, 11, 9, 6, 6, 6}; + + // throat formants (F2) 5..29 + unsigned char throatFormants5_29[30] = { + 255, 255, + 255, 255, 255, 84, 73, 67, 63, 40, 44, 31, 37, 45, 73, 49, + 36, 30, 51, 37, 29, 69, 24, 50, 30, 24, 83, 46, 54, 86}; + + // there must be no zeros in this 2 tables + // formant 1 frequencies (mouth) 48..53 + unsigned char mouthFormants48_53[6] = {19, 27, 21, 27, 18, 13}; + + // formant 2 frequencies (throat) 48..53 + unsigned char throatFormants48_53[6] = {72, 39, 31, 43, 30, 34}; + + unsigned char pos = 5; //mem39216 //pos38942: - // recalculate formant frequencies 5..29 for the mouth (F1) and throat (F2) - while(pos != 30) - { - // recalculate mouth frequency - initialFrequency = mouthFormants5_29[pos]; - if (initialFrequency != 0) newFrequency = trans(mouth, initialFrequency); - freq1data[pos] = newFrequency; - - // recalculate throat frequency - initialFrequency = throatFormants5_29[pos]; - if(initialFrequency != 0) newFrequency = trans(throat, initialFrequency); - freq2data[pos] = newFrequency; - pos++; - } + // recalculate formant frequencies 5..29 for the mouth (F1) and throat (F2) + while(pos != 30) + { + // recalculate mouth frequency + initialFrequency = mouthFormants5_29[pos]; + if (initialFrequency != 0) newFrequency = trans(mouth, initialFrequency); + freq1data[pos] = newFrequency; + + // recalculate throat frequency + initialFrequency = throatFormants5_29[pos]; + if(initialFrequency != 0) newFrequency = trans(throat, initialFrequency); + freq2data[pos] = newFrequency; + pos++; + } //pos39059: - // recalculate formant frequencies 48..53 - pos = 48; - Y = 0; + // recalculate formant frequencies 48..53 + pos = 48; + Y = 0; while(pos != 54) { - // recalculate F1 (mouth formant) - initialFrequency = mouthFormants48_53[Y]; - newFrequency = trans(mouth, initialFrequency); - freq1data[pos] = newFrequency; - - // recalculate F2 (throat formant) - initialFrequency = throatFormants48_53[Y]; - newFrequency = trans(throat, initialFrequency); - freq2data[pos] = newFrequency; - Y++; - pos++; - } + // recalculate F1 (mouth formant) + initialFrequency = mouthFormants48_53[Y]; + newFrequency = trans(mouth, initialFrequency); + freq1data[pos] = newFrequency; + + // recalculate F2 (throat formant) + initialFrequency = throatFormants48_53[Y]; + newFrequency = trans(throat, initialFrequency); + freq2data[pos] = newFrequency; + Y++; + pos++; + } } //return = (mem39212*mem39213) >> 1 unsigned char trans(unsigned char mem39212, unsigned char mem39213) { - //pos39008: - unsigned char carry; - int temp; - unsigned char mem39214, mem39215; - A = 0; - mem39215 = 0; - mem39214 = 0; - X = 8; - do - { - carry = mem39212 & 1; - mem39212 = mem39212 >> 1; - if (carry != 0) - { - /* - 39018: LSR 39212 - 39021: BCC 39033 - */ - carry = 0; - A = mem39215; - temp = (int)A + (int)mem39213; - A = A + mem39213; - if (temp > 255) carry = 1; - mem39215 = A; - } - temp = mem39215 & 1; - mem39215 = (mem39215 >> 1) | (carry?128:0); - carry = temp; - //39033: ROR 39215 - X--; - } while (X != 0); - temp = mem39214 & 128; - mem39214 = (mem39214 << 1) | (carry?1:0); - carry = temp; - temp = mem39215 & 128; - mem39215 = (mem39215 << 1) | (carry?1:0); - carry = temp; - - return mem39215; + //pos39008: + unsigned char carry; + int temp; + unsigned char mem39214, mem39215; + A = 0; + mem39215 = 0; + mem39214 = 0; + X = 8; + do + { + carry = mem39212 & 1; + mem39212 = mem39212 >> 1; + if (carry != 0) + { + /* + 39018: LSR 39212 + 39021: BCC 39033 + */ + carry = 0; + A = mem39215; + temp = (int)A + (int)mem39213; + A = A + mem39213; + if (temp > 255) carry = 1; + mem39215 = A; + } + temp = mem39215 & 1; + mem39215 = (mem39215 >> 1) | (carry?128:0); + carry = temp; + //39033: ROR 39215 + X--; + } while (X != 0); + temp = mem39214 & 128; + mem39214 = (mem39214 << 1) | (carry?1:0); + carry = temp; + temp = mem39215 & 128; + mem39215 = (mem39215 << 1) | (carry?1:0); + carry = temp; + + return mem39215; } From a647d2704d9ade386cb14e61d9993144ce7ac393 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Wed, 5 Dec 2018 18:08:12 +0100 Subject: [PATCH 19/62] us a local copy of bufferpos in Output() gives big speedup. 30s -> 13s for sam -wav hello.wav Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0 --- AF_readme | 4 ++++ Makefile.amiga | 2 +- src/main.c | 5 +++++ src/render.c | 4 +++- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/AF_readme b/AF_readme index 1a0455c..cef9334 100644 --- a/AF_readme +++ b/AF_readme @@ -101,3 +101,7 @@ Fuer gprof test | gprof2dot -n0 -e0 | dot -Tpng -o output2.png && mirage output2.png (gemessen ohne Soundausgabe oder Wave-File-schreiben, compiliert mit -O2, -pg und auf WinUAE Cycleexact A500 getestet) +5.Dec.2018 +---------- +In render.c gibt es mehrere Stellen, an denen BufferPos/50 berechnet wird. Bufferpos ist ein int. Das Dauert. Wenn ich testweise statt dessen Bufferpos >> 6 rechne, also /64, dann ist das Ergebnis zwar falsch, aber statt 30 Sekunden werden nur noch 10 Sekunden benoetigt! + diff --git a/Makefile.amiga b/Makefile.amiga index 9327c99..c92c541 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -22,7 +22,7 @@ LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace # -ldebug #-lSDL #`sdl-config -- #CFLAGS += -ftest-coverage #CFLAGS += -fprofile-arcs #-pg # Profiler #LFLAGS += -lgcov -CFLAGS += -pg -fno-omit-frame-pointer +CFLAGS += -g -pg -fno-omit-frame-pointer LFLAGS += -pg diff --git a/src/main.c b/src/main.c index 485a9ca..8e4c141 100644 --- a/src/main.c +++ b/src/main.c @@ -308,7 +308,12 @@ int main(int argc, char **argv) PrintUsage(); return 1; } +{ printf("Sound berechnung nach %lld Sekunden\n",time(NULL)-StartZeit); +extern int bufferpos; +printf("%s(): BufferPos=%d\n",__FUNCTION__,bufferpos); +printf("%s(): GetBufferLength=%d\n",__FUNCTION__,GetBufferLength()); +} if (wavfilename != NULL) WriteWav(wavfilename, GetBuffer(), GetBufferLength()/50); else diff --git a/src/render.c b/src/render.c index 3bce174..5d22835 100755 --- a/src/render.c +++ b/src/render.c @@ -67,11 +67,13 @@ void Output(int index, unsigned char A) { static unsigned oldtimetableindex = 0; int k; + int local_bufferpos; // much faster if we use a local copy here 30s --> 13s for sam -wav hello.wav Hell, my name is sam. 1 2 3 4 5 6 7 8 9 0 bufferpos += timetable[oldtimetableindex][index]; + local_bufferpos=bufferpos; oldtimetableindex = index; // write a little bit in advance for(k=0; k<5; k++) - buffer[bufferpos/50 + k] = (A & 15)*16; + buffer[local_bufferpos/50 + k] = (A & 15)*16; // much faster if we use a local copy here } From fd672bdedc492520603baea44c43decdcb7f472d Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Wed, 5 Dec 2018 18:24:05 +0100 Subject: [PATCH 20/62] use a local buffer pointer in Output(). Speedup 13s -> 11..12s --- src/render.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/render.c b/src/render.c index 5d22835..dc28706 100755 --- a/src/render.c +++ b/src/render.c @@ -66,14 +66,20 @@ int timetable[5][5] = void Output(int index, unsigned char A) { static unsigned oldtimetableindex = 0; - int k; - int local_bufferpos; // much faster if we use a local copy here 30s --> 13s for sam -wav hello.wav Hell, my name is sam. 1 2 3 4 5 6 7 8 9 0 +// int k; + int local_bufferpos; // much faster if we use a local copy here 30s --> 13s for sam -wav hello.wav Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0 + char *local_buffer_ptr; bufferpos += timetable[oldtimetableindex][index]; - local_bufferpos=bufferpos; + local_bufferpos=bufferpos/50; + local_buffer_ptr=&buffer[local_bufferpos]; oldtimetableindex = index; // write a little bit in advance - for(k=0; k<5; k++) - buffer[local_bufferpos/50 + k] = (A & 15)*16; // much faster if we use a local copy here +// for(k=0; k<5; k++) + *local_buffer_ptr++ = (A & 15)*16; // much faster if we use a local copy here + *local_buffer_ptr++ = (A & 15)*16; // much faster if we use a local copy here + *local_buffer_ptr++ = (A & 15)*16; // much faster if we use a local copy here + *local_buffer_ptr++ = (A & 15)*16; // much faster if we use a local copy here + *local_buffer_ptr++ = (A & 15)*16; // much faster if we use a local copy here } From 9f2999472b18114d06ab80276f6fcf3b4e994d14 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Fri, 7 Dec 2018 13:59:14 +0100 Subject: [PATCH 21/62] added missing consts --- Makefile.amiga | 1 + src/debug.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index c92c541..d587df2 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -37,6 +37,7 @@ vpath amiga_version.c src/amiga/version/ sam: $(OBJS) $(CC) -o sam $(OBJS) $(LFLAGS) + sync %.o: src/%.c $(CC) $(CFLAGS) -c $< diff --git a/src/debug.c b/src/debug.c index 86e5797..d663ab1 100755 --- a/src/debug.c +++ b/src/debug.c @@ -1,7 +1,7 @@ #include -extern unsigned char signInputTable1[]; -extern unsigned char signInputTable2[]; +extern const unsigned char signInputTable1[]; +extern const unsigned char signInputTable2[]; void PrintPhonemes(unsigned char *phonemeindex, unsigned char *phonemeLength, unsigned char *stress) { From 020abb585decec26c84d7ed29624bd6c9278e457 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Fri, 7 Dec 2018 23:46:41 +0100 Subject: [PATCH 22/62] fixed CTRL-C Enforcer-Hit, added more CTRL-C checking. Newer compiler. --- Makefile.amiga | 14 +++++++++----- src/amiga/portaudio/portaudio_audev.c | 4 ++-- src/amiga/sdlwrapper.c | 4 +++- src/main.c | 1 + src/render.c | 11 +++++++++++ 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index d587df2..88b5a0e 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -1,8 +1,9 @@ OBJS = reciter.o sam.o render.o main.o debug.o endian.o sdlwrapper.o portaudio_ahidev.o portaudio_audev.o portaudio.o subtask_support.o amiga_version.o -COMPILER_INSTALL_DIR = /home/osboxes/opt/m68k-amigaos_30Nov18 +COMPILER_INSTALL_DIR = /home/osboxes/opt/m68k-amigaos_06Dec18 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc +STRIP = $(COMPILER_DIR)/m68k-amigaos-strip TOOLCHAIN_VER=$(shell cat $(COMPILER_DIR)/toolchain_commit.txt) @@ -15,15 +16,15 @@ CFLAGS += -Iamiga/ -Iamiga/portaudio/ -I. -I$(COMPILER_INSTALL_DIR)/include/SDL CFLAGS += $(CPUFLAGS) CFLAGS += -Wall -O2 -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` -LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace # -ldebug #-lSDL #`sdl-config --libs` +LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace -ldebug #-lSDL #`sdl-config --libs` #coverage #CFLAGS += -fprofile-generate=VBox:$(shell pwd | cut -c2-) # remove first "/" from pwd -> VBox:home/... #CFLAGS += -ftest-coverage #CFLAGS += -fprofile-arcs #-pg # Profiler #LFLAGS += -lgcov -CFLAGS += -g -pg -fno-omit-frame-pointer -LFLAGS += -pg +#CFLAGS += -g -pg -fno-omit-frame-pointer +#LFLAGS += -pg vpath sdlwrapper.c src/amiga/ @@ -39,6 +40,9 @@ sam: $(OBJS) $(CC) -o sam $(OBJS) $(LFLAGS) sync +strip: sam + $(STRIP) $< + %.o: src/%.c $(CC) $(CFLAGS) -c $< @@ -46,7 +50,7 @@ package: tar -cvzf sam.tar.gz README.md Makefile sing src/ clean: - rm -f *.o + rm -f *.o *.wav sam sam.map archive: rm -f sam_windows.zip diff --git a/src/amiga/portaudio/portaudio_audev.c b/src/amiga/portaudio/portaudio_audev.c index d90cf14..3b3ac4e 100644 --- a/src/amiga/portaudio/portaudio_audev.c +++ b/src/amiga/portaudio/portaudio_audev.c @@ -1208,13 +1208,13 @@ void __attribute__((no_instrument_function)) Abort_Pa_CloseStream_audev (void) { if(GlobalPaStreamPtr) { - // KPrintF("%s() called with Stream=$%08lx\n",__FUNCTION__,GlobalPaStreamPtr); + KPrintF("%s() called with Stream=$%08lx\n",__FUNCTION__,GlobalPaStreamPtr); Pa_CloseStream_audev(GlobalPaStreamPtr); GlobalPaStreamPtr=NULL; } else { - // KPrintF("%s() called but nothing to do\n",__FUNCTION__); + KPrintF("%s() called but nothing to do\n",__FUNCTION__); } } diff --git a/src/amiga/sdlwrapper.c b/src/amiga/sdlwrapper.c index 0206516..db417ba 100644 --- a/src/amiga/sdlwrapper.c +++ b/src/amiga/sdlwrapper.c @@ -28,6 +28,7 @@ void SDL_CloseAudio(void) void SDL_Delay(Uint32 ms) { // KPrintF("%s(%ld)\n",__FUNCTION__,ms); + __chkabort(); usleep(ms*1000); } /************************************************************** */ @@ -135,5 +136,6 @@ void SDL_PauseAudio(int pause_on) void SDL_Quit(void) // useful with atexit() { -// KPrintF("%s()\n",__FUNCTION__); + KPrintF("%s()\n",__FUNCTION__); + Abort_Pa_CloseStream(); } diff --git a/src/main.c b/src/main.c index 8e4c141..38a8930 100644 --- a/src/main.c +++ b/src/main.c @@ -170,6 +170,7 @@ int main(int argc, char **argv) char* wavfilename = NULL; static char input[256]; // AF, save some stack + printf("Los...\n"); time_t StartZeit=time(NULL); #ifdef USESDL diff --git a/src/render.c b/src/render.c index dc28706..4ebdbab 100755 --- a/src/render.c +++ b/src/render.c @@ -581,6 +581,9 @@ do X = 0; while(1) //while No. 1 { +#ifdef __AMIGA__ + __chkabort(); /* look for CTRL-C */ +#endif // get the current and following phoneme Y = phonemeIndexOutput[X]; @@ -633,6 +636,10 @@ do if ((X & 128) == 0) do //while No. 2 { +#ifdef __AMIGA__ + __chkabort(); /* look for CTRL-C */ +#endif + //pos47810: // mem47 is used to index the tables: @@ -697,6 +704,10 @@ do //pos47908: while(1) //while No. 3 { +#ifdef __AMIGA__ + __chkabort(); /* look for CTRL-C */ +#endif + A = Read(mem47, Y) + mem53; //carry alway cleared mem48 = A; From 37342b853a0270563e32f41a01eeb7606ffa101f Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Tue, 11 Dec 2018 01:28:34 +0100 Subject: [PATCH 23/62] added amiga demos --- AF_readme | 11 +++++ Makefile.amiga | 5 +++ demos_amiga/demo1 | 3 ++ demos_amiga/demo2 | 29 +++++++++++++ demos_amiga/demo3 | 43 +++++++++++++++++++ demos_amiga/demo4 | 7 ++++ demos_amiga/demo5 | 19 +++++++++ demos_amiga/demo6 | 105 ++++++++++++++++++++++++++++++++++++++++++++++ demos_amiga/demo7 | 6 +++ demos_amiga/demo8 | 11 +++++ demos_amiga/demo9 | 16 +++++++ demos_amiga/demoA | 6 +++ demos_amiga/demoB | 9 ++++ demos_amiga/demoC | 13 ++++++ demos_amiga/demoD | 5 +++ 15 files changed, 288 insertions(+) create mode 100755 demos_amiga/demo1 create mode 100755 demos_amiga/demo2 create mode 100755 demos_amiga/demo3 create mode 100755 demos_amiga/demo4 create mode 100755 demos_amiga/demo5 create mode 100755 demos_amiga/demo6 create mode 100755 demos_amiga/demo7 create mode 100755 demos_amiga/demo8 create mode 100755 demos_amiga/demo9 create mode 100755 demos_amiga/demoA create mode 100755 demos_amiga/demoB create mode 100755 demos_amiga/demoC create mode 100755 demos_amiga/demoD diff --git a/AF_readme b/AF_readme index cef9334..1309826 100644 --- a/AF_readme +++ b/AF_readme @@ -105,3 +105,14 @@ gprof test | gprof2dot -n0 -e0 | dot -Tpng -o output2.png && mirage output2.pn ---------- In render.c gibt es mehrere Stellen, an denen BufferPos/50 berechnet wird. Bufferpos ist ein int. Das Dauert. Wenn ich testweise statt dessen Bufferpos >> 6 rechne, also /64, dann ist das Ergebnis zwar falsch, aber statt 30 Sekunden werden nur noch 10 Sekunden benoetigt! +8.12.2018 +--------- +-msmall-code saves a few bytes 2k oder so. +-fbaserel spart 8k oder so, das Programm wird aber langsamer 12..13 Sekunden statt 10..11 Sekunden. +-resident bekomme ich nur compiliert, wenn ich __ctypes.c patche. Sonst passiert sam: .text reloc for __ctype_ is out of range: 00000000 +Aber auch mit patch stürzt das Programm immer ab. + +10.12.2018 +---------- +Demos fuer Amiga angepasst. Neues Verzeichnis demos_amiga + diff --git a/Makefile.amiga b/Makefile.amiga index 88b5a0e..2c94a13 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -16,7 +16,12 @@ CFLAGS += -Iamiga/ -Iamiga/portaudio/ -I. -I$(COMPILER_INSTALL_DIR)/include/SDL CFLAGS += $(CPUFLAGS) CFLAGS += -Wall -O2 -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` +#CFLAGS += -fbaserel +#CFLAGS += -msmall-code + LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace -ldebug #-lSDL #`sdl-config --libs` +#LFLAGS += -fbaserel + #coverage #CFLAGS += -fprofile-generate=VBox:$(shell pwd | cut -c2-) # remove first "/" from pwd -> VBox:home/... diff --git a/demos_amiga/demo1 b/demos_amiga/demo1 new file mode 100755 index 0000000..215e775 --- /dev/null +++ b/demos_amiga/demo1 @@ -0,0 +1,3 @@ + +/sam -debug "to bee or not to bee, that is the question"; +/sam -phonetic "MAY4 NEYM IHZ SAE4M."; diff --git a/demos_amiga/demo2 b/demos_amiga/demo2 new file mode 100755 index 0000000..e6d7c17 --- /dev/null +++ b/demos_amiga/demo2 @@ -0,0 +1,29 @@ + +/sam -pitch 64 -speed 72 -phonetic "/HEH4LOW DHEHR. YUW4 NOW MIY4Y, AY4 AEM SAE5M,"; +/sam -pitch 64 -speed 72 -phonetic "DHAH SAO4FTWEHR MAW5TH"; +/sam -pitch 64 -speed 72 -phonetic "FOHR YOHR KAA4MIXDOH6R SIH4KSTIYFOH6R KUMPYUW4TER."; +/sam -pitch 64 -speed 72 -phonetic "AY4 KUHD AO4LWEYZ DUW LAA3TS AHV AHMEY4ZIHNX THIHNXGZ."; +/sam -pitch 64 -speed 35 -phonetic "AY5 KUHD TAO5K VEH4RIY KWIH4KLIY WHEHN AY WAA4NTIHD."; +/sam -pitch 64 -speed 140 -phonetic "AE4ND AY KUHD TAO4K VEH3RIY SLOW4LIY TUW."; +/sam -pitch 30 -speed 72 -phonetic "AY5 KUHD SPIY5K IHNAH VEH3RIY /HAY5 VOYS."; +/sam -pitch 169 -speed 72 -phonetic "AE4ND AY KUHD SPIY5K RIY3L LOW."; +/sam -pitch 64 -speed 72 -phonetic "BAHT NAW4 AY KAEN DUW5 SAH4MPTHIHNX IY5VUN MOH4R AHMEY3ZIHNX."; + +/sam -mouth 110 -throat 160 -pitch 64 -speed 72 -phonetic "AY4 KAEN CHEY4NJ MAY VOY5S KUMPLIY3TLIY.Q."; +/sam -mouth 110 -throat 160 -pitch 64 -speed 72 -phonetic "AY4 KAEN BIY5 AH LIH4TUL EH5LF /HUW TAO5KS LAYK DHIH5S. OH3R."; + +/sam -mouth 190 -throat 190 -pitch 60 -speed 42 -phonetic "AY5 KAEN BIHKAH5M AH STREY4NJ EY4LIYUN."; +/sam -mouth 190 -throat 190 -pitch 60 -speed 42 -phonetic "YUW5 KAEN YUW4Z DHIHS VOY5S IHN AH SPEY4S GEY5M."; + +/sam -mouth 110 -throat 105 -pitch 72 -speed 82 -phonetic "OHR /HAW5 AHBAW5T DHIH3S STAH4FIY LIH5TUL KEH4RIXKTER."; +/sam -mouth 110 -throat 105 -pitch 72 -speed 82 -phonetic "EY SIH4LIY VOY5S FOHR AH KUMPYUW4TER."; + +/sam -mouth 145 -throat 145 -pitch 32 -speed 72 -phonetic "AY5 KAEN TAO5K LAYK AH LIH5TUL OH5LD LEY5DIY."; +/sam -mouth 145 -throat 145 -pitch 32 -speed 72 -phonetic "NAAT MEH5NIY KUMPYUW5TERZ KAEN DUW DHIH4S - SWIY5TIY."; + +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "AE4ND AEZ AH MAE5TER AHV FAE4KT,"; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "AY4 KAEN BIYKAH5M DHAX LEY4TIXST MUW4VIY /HIY4ROW - AEND SEH8EY4,"; + +/sam -mouth 150 -throat 200 -pitch 58 -speed 120 -phonetic "IY4IY6 TTIY6 -FOW5N /HOW5MM. IY4IY6 TTIY6 - FOW5N /HOW5MM."; + +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "DHEH4RZ NOW4 TEH5LIHNX WHAH5T SAE5M WIHL DUW NEH5KST."; diff --git a/demos_amiga/demo3 b/demos_amiga/demo3 new file mode 100755 index 0000000..9ea77bb --- /dev/null +++ b/demos_amiga/demo3 @@ -0,0 +1,43 @@ + +/sam -pitch 64 -speed 74 -phonetic "/HEHLOW3 EH5VRIXWAHN. IHT SHUH4R IHZ NAY3S - TAX BIY /HIY4R TUH7DEY."; +/sam -pitch 64 -speed 74 -phonetic "AY3 AEM SAE4M -"; +/sam -pitch 64 -speed 74 -phonetic "DHAX BRAE4ND NUW5 VOY4S FOHR DHAX KAA4MIXDOH6R"; +/sam -pitch 64 -speed 74 -phonetic "SIH4KSTIYFOH6R KUMPYUW4TER."; +/sam -pitch 64 -speed 74 -phonetic "AY4 AEM DHAX MOW5ST VER4SIXTUL -"; +/sam -pitch 64 -speed 74 -phonetic "AH5NDERSTAE4NDIXBUL SPIY5CH SIH3NTHAXSAY7ZER"; +/sam -pitch 64 -speed 74 -phonetic "AAN DHAX MAA3RKIXT."; +/sam -pitch 64 -speed 74 -phonetic "AE4AE7ND- AY4 AEM DHAX LOHOW4EHST PRAY4ST- AHV DHEHM AO4UL."; +/sam -pitch 64 -speed 74 -phonetic "BAH6T WHAH4T KAEN YUW DUW3 WHIHTH MIYIY."; +/sam -pitch 64 -speed 74 -phonetic "WAY7 YUW3 KAEN PUH5T MIY-IH5NTUX YOHR OW7N PROH3GRAEMZ."; +/sam -pitch 64 -speed 74 -phonetic "/HAW4 WUHD YUW4 LAYK YOHR BIH3ZNIXS SAO5FTWEHR TUX SEY-"; +/sam -pitch 64 -speed 74 -phonetic "PLIY4Z EH5NTER DHIH4S WIY6KS PER3CHAHSIXZ."; +/sam -pitch 64 -speed 74 -phonetic "OH3ER- IHMAE3JIXN AEN EHDVEH4NCHER GEY6M DHAET DAH6Z DHIH4S."; +/sam -pitch 64 -speed 74 -phonetic "DHIY EH3LF WAHZ KAE3PCHERD-BAY DHAX JAY3IXNT."; +/sam -pitch 64 -speed 74 -phonetic "/HIY BIHGAE5N TUX KRAA3IY-AEND /HIY SEH4D."; + +/sam -pitch 31 -speed 72 -phonetic "OH5OW7 NAX5OW. PLIY5Z DOWNT /HER5T MIY-MIH6STER JAYIXNT?"; + +/sam -pitch 64 -speed 76 -phonetic "BAH6T DHAX JAY4IXNT WAHZ VEH3RIY MIY6N-"; +/sam -pitch 64 -speed 76 -phonetic "AEND /HIY4 OW3NLIY SEHD-"; + +/sam -pitch 120 -speed 80 -phonetic "/HOW2- /HOW4- /HOW."; + +/sam -pitch 64 -speed 72 -phonetic "DHEH5R IHZ NOW LIH3MIXT-TUX DHAX PAA4SAXBUL AE5PLIXKEY3SHUNZ-"; +/sam -pitch 64 -speed 72 -phonetic "AHV SPIY4CH IHN YOH7R PROH3GRAEMZ."; +/sam -pitch 64 -speed 72 -phonetic "AO3LSOW7W3- AY4 AEM VEH3RIY IY4ZIY TUX YUW4Z."; +/sam -pitch 64 -speed 72 -phonetic "EH2NIYWAH6N KAEN AE5DSPIY5CH-TUX6 AH BEY4SIHKQPROH4GRAEM."; +/sam -pitch 64 -speed 72 -phonetic "AY4 KAEN IY3VIXN TAOK VEH4RIY KWIH4KLIY."; +/sam -pitch 64 -speed 72 -phonetic "LIH4SUN TUX6 DHIH3S WAHN."; + +/sam -speed 30 -phonetic "PIY4TER PAY3PER- PIH4KT AH PEH4K AHV PIH4KULD PEH4PERZ."; + +/sam -speed 28 -phonetic "/HAW3 MEHNIY PEH4KS AHV PIH4KULD PEH4PERZ-DIHD PIY4TER PAY3PER PIH6K."; + +/sam -speed 100 -phonetic "QQQQ WWAW7IY1IY3IY. DHAE3T WHAHZ AH TAH4FIY."; + +/sam -speed 72 -phonetic "EH2NIYWEY6- YUW4 GEHT DHIY AYDIY5AH."; +/sam -speed 72 -phonetic "SAE3M IHZ DHIY MOW3STEHKSAY4TIHNX NUW4 PRAA4DAHKT - AHV DHIHS YIY4R."; +/sam -speed 72 -phonetic "SOH3OW7-/HAW4AHBAW3T IHT. WOH3NT YUW PLIY2Z TEY6KMIY /HOW6M?"; +/sam -speed 72 -phonetic "Q SAE4M IHZ /HIY3R TUX STEY4IY."; +/sam -speed 72 -phonetic "THAE2NXKS FOHR LIH4SUNIHNX EHVRIXBAH5DIY."; +/sam -speed 72 -phonetic "AY /HOW3P YUW EHNJOY4D-MAYLIH4TUL TAOK."; diff --git a/demos_amiga/demo4 b/demos_amiga/demo4 new file mode 100755 index 0000000..0573c61 --- /dev/null +++ b/demos_amiga/demo4 @@ -0,0 +1,7 @@ + +/sam "Four score and seven years ago."; +/sam "Our fathers brought forth on this continent, a new nation."; +/sam "Conceived in Libberty. And dedicated to the prop-position that all men are created equal."; + +/sam "Now we are engaged in a great civvil war! Testing whether that nation, or any nation."; +/sam "So conceived, and so dedicated, can long endure."; diff --git a/demos_amiga/demo5 b/demos_amiga/demo5 new file mode 100755 index 0000000..17155ac --- /dev/null +++ b/demos_amiga/demo5 @@ -0,0 +1,19 @@ + +/sam -mouth 110 -throat 160 -pitch 64 -speed 72 -phonetic "AY4 KAEN CHEY4NJ MAY VOY5S KUMPLIY3TLIY.Q."; + +/sam -mouth 150 -throat 200 -pitch 58 -speed 120 "Eee Tea! Phone home."; +/sam -mouth 150 -throat 200 -pitch 58 -speed 120 "Eee Tea? Phone home?"; + +/sam -mouth 150 -throat 200 -pitch 58 -speed 140 "Ha ha ha ha ha ha ha!"; +/sam -mouth 150 -throat 100 -pitch 58 -speed 140 "Ha ha ha ha ha ha ha?"; + +/sam -speed 140 -pitch 64 -throat 110 -mouth 160 "Ho ha ha ha!"; +/sam -speed 140 -pitch 60 -throat 190 -mouth 190 "Ha ha ha ha ha ha ha?"; + +/sam -speed 140 -pitch 72 -throat 110 -mouth 105 "He he ha ha he he ha!"; +/sam -speed 140 -pitch 32 -throat 145 -mouth 145 "Ha ha ho he he ha?"; + +/sam -speed 140 -pitch 64 -throat 150 -mouth 200 "Ha ha ho ho ha ho?"; +/sam -speed 35 -pitch 92 -throat 128 -mouth 128 "Ha ha ha ha ha ha ha? Ha ha ha ha ha ha ha!"; + +/sam "That's not funny."; diff --git a/demos_amiga/demo6 b/demos_amiga/demo6 new file mode 100755 index 0000000..0cf8948 --- /dev/null +++ b/demos_amiga/demo6 @@ -0,0 +1,105 @@ + +/sam "Hello my name is Sam."; +/sam "I will sing the national anthem of the United States of America."; +/sam "The Star Spangled Banner!"; +/sam -sing -speed 40 -pitch 64 -phonetic "ohohoh"; +/sam -sing -speed 40 -pitch 76 -phonetic "ohohoh"; +/sam -sing -speed 40 -pitch 96 -phonetic "sehehehehehehehehehey"; +/sam -sing -speed 40 -pitch 76 -phonetic "kaeaeaeaeaeaeaeaeaen"; +/sam -sing -speed 40 -pitch 64 -phonetic "yuxuxuxuxuxuxw"; +/sam -sing -speed 40 -pitch 48 -phonetic "siyiyiyiyiyiyiyiyiyiyiyiyiyiyiyiyiyiy"; +/sam -sing -speed 40 -pitch 38 -phonetic "baaaaay"; +/sam -sing -speed 40 -pitch 42 -phonetic "dhaaaxaxaxax"; +/sam -sing -speed 40 -pitch 48 -phonetic "daoaoaoaoaoaoaonz"; +/sam -sing -speed 40 -pitch 76 -phonetic "ererererererer"; +/sam -sing -speed 40 -pitch 68 -phonetic "liyiyiyiyiyiyiyiyiy"; +/sam -sing -speed 40 -pitch 64 -phonetic "laaaaaaaaaaaaaaaaaaaaaaaaayt"; +/sam -sing -speed 40 -pitch 64 -phonetic "whahahaht"; +/sam -sing -speed 40 -pitch 64 -phonetic "sohohuw"; +/sam -sing -speed 40 -pitch 38 -phonetic "praaaaaaaaaaaaaaaauwd"; +/sam -sing -speed 40 -pitch 42 -phonetic "liyiyiy"; +/sam -sing -speed 40 -pitch 48 -phonetic "wiyiyiyiyiyiyiyiyiy"; +/sam -sing -speed 40 -pitch 51 -phonetic "/heheheheheheheheheheheheheheheheheheyld"; +/sam -sing -speed 40 -pitch 56 -phonetic "aeaeaeaet"; +/sam -sing -speed 40 -pitch 51 -phonetic "dhaaaxaxaxax"; +/sam -sing -speed 40 -pitch 48 -phonetic "twaaaaaaaaaaaaaaiy"; +/sam -sing -speed 40 -pitch 48 -phonetic "laaaaaaaaaaaaiyts"; +/sam -sing -speed 40 -pitch 64 -phonetic "laeaeaeaeaeaeaeaeaest"; +/sam -sing -speed 40 -pitch 76 -phonetic "gliyiyiyiyiyiyiyiyiym"; +/sam -sing -speed 40 -pitch 96 -phonetic "mihihihihihihihihihihnx"; +/sam -sing -speed 40 -pitch 64 -phonetic "/huxuxuxuxuxuxuxuxuxuxwz"; +/sam -sing -speed 40 -pitch 76 -phonetic "braoaoaod"; +/sam -sing -speed 40 -pitch 96 -phonetic "straaaaaaaaaaaaiyps"; +/sam -sing -speed 40 -pitch 76 -phonetic "aeaeaeaeaeaeaeaeaeaend"; +/sam -sing -speed 40 -pitch 64 -phonetic "braaaaaaaaaaaaaaiyt"; +/sam -sing -speed 40 -pitch 48 -phonetic "staaaaaaaaaaaaaaaaaaaaaaaaaarz"; +/sam -sing -speed 40 -pitch 38 -phonetic "thruxuxw"; +/sam -sing -speed 40 -pitch 42 -phonetic "dhaaaxaxaxax"; +/sam -sing -speed 40 -pitch 48 -phonetic "pehehehehehehehehehehr"; +/sam -sing -speed 40 -pitch 76 -phonetic "rixixixixixixixixixixixixl"; +/sam -sing -speed 40 -pitch 68 -phonetic "lahahahahahahahahahs"; +/sam -sing -speed 40 -pitch 64 -phonetic "faaaaaaaaaaaaaaaaaaaaaaaaaaiyt"; +/sam -sing -speed 40 -pitch 64 -phonetic "ohohohr"; +/sam -sing -speed 40 -pitch 64 -phonetic "dhaaaxaxaxax"; +/sam -sing -speed 40 -pitch 38 -phonetic "raeaeaeaeaeaeaeaeaeaeaeaem"; +/sam -sing -speed 40 -pitch 42 -phonetic "paaaarts"; +/sam -sing -speed 40 -pitch 48 -phonetic "wiyiyiyiyiyiyiyiyiy"; +/sam -sing -speed 40 -pitch 51 -phonetic "waaaaaaaaaaaaaaaaaaaaaaaaaachd"; +/sam -sing -speed 40 -pitch 56 -phonetic "werer"; +/sam -sing -speed 40 -pitch 51 -phonetic "sohohw"; +/sam -sing -speed 40 -pitch 48 -phonetic "gaeaeaeaeaeaeaeaeaeael"; +/sam -sing -speed 40 -pitch 48 -phonetic "lixixixixixixixixixixixixixnt"; +/sam -sing -speed 40 -pitch 64 -phonetic "liyiyiyiyiyiyiyiyiy"; +/sam -sing -speed 40 -pitch 76 -phonetic "striyiyiyiyiyiyiyiyiym"; +/sam -sing -speed 40 -pitch 96 -phonetic "mihihihihihihihihihnx"; +/sam -sing -speed 40 -pitch 38 -phonetic "aeaeaeaeaend"; +/sam -sing -speed 40 -pitch 38 -phonetic "dhaaaxaxaxax"; +/sam -sing -speed 40 -pitch 38 -phonetic "raaaaaaaaaaaak"; +/sam -sing -speed 40 -pitch 36 -phonetic "kixixixixixixixixixixixts"; +/sam -sing -speed 40 -pitch 32 -phonetic "rehehehehehehehehehd"; +/sam -sing -speed 40 -pitch 32 -phonetic "gleheheheheheheheheheheheheheheherer"; +/sam -sing -speed 40 -pitch 36 -phonetic "dhaaaxaxaxax"; +/sam -sing -speed 40 -pitch 38 -phonetic "baaaamz"; +/sam -sing -speed 40 -pitch 42 -phonetic "bererererererst"; +/sam -sing -speed 40 -pitch 38 -phonetic "tihihihihihihihihihnx"; +/sam -sing -speed 40 -pitch 36 -phonetic "ihihihihihihihihihihn"; +/sam -sing -speed 40 -pitch 36 -phonetic "eheheheheheheheheheheheheheheheheheyr"; +/sam -sing -speed 40 -pitch 36 -phonetic "geheheheyv"; +/sam -sing -speed 40 -pitch 38 -phonetic "pruxuxuxuxuxuxuxuxuxuxuxuxwf"; +/sam -sing -speed 40 -pitch 42 -phonetic "thruxuxw"; +/sam -sing -speed 40 -pitch 48 -phonetic "dhaaaxaxax"; +/sam -sing -speed 40 -pitch 51 -phonetic "naaaaaaaaaaaaaaaaaaaaaaayiyt"; +/sam -sing -speed 40 -pitch 56 -phonetic "dhaeaeaeaet"; +/sam -sing -speed 40 -pitch 51 -phonetic "aaaaaauwr"; +/sam -sing -speed 40 -pitch 48 -phonetic "flaeaeaeaeaeaeaeaeaeg"; +/sam -sing -speed 40 -pitch 76 -phonetic "wahahahahahahahahahz"; +/sam -sing -speed 40 -pitch 68 -phonetic "stihihihihihihihihihl"; +/sam -sing -speed 40 -pitch 64 -phonetic "dhehehehehehehehehehehehehehehehehehehehr"; +/sam -sing -speed 40 -pitch 64 -phonetic "ohohohohohohow"; +/sam -sing -speed 40 -pitch 48 -phonetic "sehehehehehehehehehey"; +/sam -sing -speed 40 -pitch 48 -phonetic "dahahahahahahahahahz"; +/sam -sing -speed 40 -pitch 48 -phonetic "dhaeaeae"; +/sam -sing -speed 40 -pitch 51 -phonetic "aeaeaet"; +/sam -sing -speed 40 -pitch 56 -phonetic "staaaaaaaaaaaar"; +/sam -sing -speed 40 -pitch 56 -phonetic "spehehehehehehehehehiynx"; +/sam -sing -speed 40 -pitch 56 -phonetic "gaxaxaxaxaxaxaxaxaxaxaxaxld"; +/sam -sing -speed 40 -pitch 42 -phonetic "baeaeaeaeaeaeaeaeaen"; +/sam -sing -speed 40 -pitch 36 -phonetic "nerer"; +/sam -sing -speed 40 -pitch 38 -phonetic "ererer"; +/sam -sing -speed 40 -pitch 42 -phonetic "yeheheh"; +/sam -sing -speed 40 -pitch 48 -phonetic "eheheheht"; +/sam -sing -speed 40 -pitch 48 -phonetic "weheheheheheheheheheheh"; +/sam -sing -speed 40 -pitch 51 -phonetic "ehehehehehehehiyiyiyv"; +/sam -sing -speed 40 -pitch 64 -phonetic "ohohohr"; +/sam -sing -speed 40 -pitch 64 -phonetic "dhaaaxaxaxax"; +/sam -sing -speed 40 -pitch 48 -phonetic "laeaeaeaeaeaeaeaeaeaeaeae"; +/sam -sing -speed 40 -pitch 42 -phonetic "aeaeaend"; +/sam -sing -speed 40 -pitch 38 -phonetic "ahahahv"; +/sam -sing -speed 40 -pitch 36 -phonetic "dhaaaxaxaxax"; +/sam -sing -speed 40 -pitch 32 -phonetic "friyiyiyiyiyiyiyiyiyiyiyiyiyiyiyiyiyiy"; +/sam -sing -speed 40 -pitch 48 -phonetic "aeaeaend"; +/sam -sing -speed 40 -pitch 42 -phonetic "dhaaaxaxaxax"; +/sam -sing -speed 40 -pitch 38 -phonetic "/hohohohohohohohohowm"; +/sam -sing -speed 40 -pitch 36 -phonetic "ahahahahv"; +/sam -sing -speed 40 -pitch 42 -phonetic "dhaaaxaxaxaxaxaxaxaxaxaxaxaxax"; +/sam -sing -speed 40 -pitch 48 -phonetic "brehehehehehehehehehehiyiyiyv"; diff --git a/demos_amiga/demo7 b/demos_amiga/demo7 new file mode 100755 index 0000000..9770fbc --- /dev/null +++ b/demos_amiga/demo7 @@ -0,0 +1,6 @@ + +/sam -sing -pitch 96 -speed 50 "It's Jazzy Jazzy Jazzy"; +/sam -sing -pitch 68 -speed 50 "Jazzy Jazzy Jazzy"; +/sam -sing -pitch 48 -speed 50 "Jazzy Jazzy Jazzy"; +/sam -sing -pitch 32 -speed 50 "Jazzy Jazzy Jazzy"; +/sam -sing -pitch 96 -speed 50 "Jazzy"; diff --git a/demos_amiga/demo8 b/demos_amiga/demo8 new file mode 100755 index 0000000..0fb193c --- /dev/null +++ b/demos_amiga/demo8 @@ -0,0 +1,11 @@ + +/sam "More than ever before. Americans are suff-er-ing from back, problems."; +/sam "Back. tach-sis."; +/sam "Back. rent?"; +/sam "Back. car payments."; +/sam "What we need is to get back. to the basics."; + +/sam "And say chilldren: What does it all mean."; + +/sam "And remember."; +/sam "If you want to see a comic strip? You should see me in the shouwer."; diff --git a/demos_amiga/demo9 b/demos_amiga/demo9 new file mode 100755 index 0000000..58dd9f3 --- /dev/null +++ b/demos_amiga/demo9 @@ -0,0 +1,16 @@ + +/sam -mouth 145 -throat 135 -pitch 40 -speed 72 -phonetic "AY5 KAEN TAO5K LAYK AH LIH5TUL OH5LD LEY5DIY.- SWIY5TIY."; + +/sam -mouth 145 -throat 125 -pitch 40 -speed 72 "You can do anything, but not everything."; +/sam -mouth 135 -throat 135 -pitch 35 -speed 72 "The richest man is not he who has the most. But he who wants the least."; +/sam -mouth 145 -throat 135 -pitch 40 -speed 72 "To the man who only has a hammer, everything he encounters looks like a nail."; +/sam -mouth 145 -throat 125 -pitch 35 -speed 72 "Before I got married I had six ideas about bringing up kids; now I have six kids. And no idea?"; +/sam -mouth 135 -throat 135 -pitch 40 -speed 72 "Always forgive your enemies. Nothing annoys them more."; +/sam -mouth 145 -throat 125 -pitch 35 -speed 72 "All people are frauds. The only difference between them is that some admit it. I myself totally dee-nigh. it."; +/sam -mouth 135 -throat 135 -pitch 40 -speed 72 "I do not mind what Con-gress does. As long as they do not do it. in the streets. And frighten the kids!"; + +/sam -speed 55 -pitch 92 -throat 128 -mouth 128 "Ha ha ha ha ha ha ha? Ha ha ha ha ha ha ha!"; +/sam "That's not funny grandma."; + +/sam -mouth 145 -throat 125 -pitch 40 -speed 72 "O.K. Let grandma take it from here."; +/sam -mouth 145 -throat 135 -pitch 40 -speed 72 -phonetic "SWIY5TIY."; diff --git a/demos_amiga/demoA b/demos_amiga/demoA new file mode 100755 index 0000000..00af1cb --- /dev/null +++ b/demos_amiga/demoA @@ -0,0 +1,6 @@ + +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "/HEHLOH3OW. MAY4 NEY4M IHZ SAE4M."; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "AY4 EHM DHAX SAO4FTWEH4R SPIY4CH SIH3NTHAXSAY4ZER FOH4R DHAX KAA3MAXDOH4R KUMPYUWTER."; + +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "AY4 PROWDUW3S /HAY4 KWAALAXTIY SPIY4CH FRAXM SIHMPAXL FAXNEHTIHK IH3NPUHT."; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "OH3R, AY4 KAEN TRAE3NZLEYT IYNGLIHSH DAXREHKTLIY TUH SPIYCH."; diff --git a/demos_amiga/demoB b/demos_amiga/demoB new file mode 100755 index 0000000..e0472ba --- /dev/null +++ b/demos_amiga/demoB @@ -0,0 +1,9 @@ + +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "DHAX SOHLIHLAXKWIY FRAXM /HAE3MLEHT. BAY WIHLYAXM SHEY4KSPIHR."; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "TUH BIYIYIY2--OHR NAAT-TUH BIYIYIY."; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "DHAET IHZ THAX KWEHSCHAXN."; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "WEHDHER TIHZ NOHBLER IHN DHAX MAY4ND, TUH SAH4FER THAX SLIY3NGZ AEN3D"; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "EH4ROWZ AXV AWT REY3JAXS FOH4RCHAXN."; + +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "OHR TUH TEYK AARMZ AXGEHNST AX4 SIY AXV TRAH4BAXLZ."; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "AEND BAY AHPOWZIHNG, EHND DHEHM."; diff --git a/demos_amiga/demoC b/demos_amiga/demoC new file mode 100755 index 0000000..ee7dae3 --- /dev/null +++ b/demos_amiga/demoC @@ -0,0 +1,13 @@ + +/sam -mouth 145 -throat 125 -pitch 40 -speed 72 "This is the original file extracted from the Commodore 64."; +/sam -mouth 145 -throat 125 -pitch 40 -speed 72 "O.K. ../sam. You can take it from here."; +/sam -mouth 145 -throat 135 -pitch 40 -speed 72 -phonetic "SWIY5TIY."; + +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "AY4 WIHL NAW4 KWOWT-DHAX GEHTIYZBERG AXDREH3S."; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "FOH4R SKOH4R AEND SEHVIXN YIH3RZ AXGOW- AAR FAA3DHERZ BRAAT FOHRTH"; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "AXPAAN DHIHS KAANTIHNEHNT- EY NUH NEY4SHAXN."; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "KAHNSIYVD IHN LIH4BERTIY, AEND DEH4DIHKEYTIHD TUH DHAX PRAAPAXSIHSHAXN"; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "DHAET AAL MEHN AAR KRIYEY4TAXD IYKWUL."; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "NAW4 WIY AAR EHNGEYJD IHN DHAX GREYT SIHVAXL WOHR. TEHSTIHNG WEHDHER"; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "DHAE4T NEY4SHAXN, OHR EH4NIY NEYSHAXN SOH KAXNSIYVD AEND SOH"; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "DEH4DAHKEYTIHD, KAEN LAONX EHNDUH6UHR."; diff --git a/demos_amiga/demoD b/demos_amiga/demoD new file mode 100755 index 0000000..a474d19 --- /dev/null +++ b/demos_amiga/demoD @@ -0,0 +1,5 @@ + +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "AY4 PLEHJ AXLIYJAXNS TUH DHAX FLAEG, AXV DHIY YUWNAYTEHD STEYTS"; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "AXV AXMEHRIYKAX. AEND TUH DHAX RIYPAHBLIHK FOHR WIHCH IHT STAENDZ."; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "WAHN NEYSHAXN AHNDER GAA5AA8D"; +/sam -mouth 128 -throat 128 -pitch 64 -speed 72 -phonetic "IHNDIHVIH4ZAXBAXL, WIHTH LIHBERTTIY, AEND JAH4STIHS- FOHR AAL."; From e3c3ca695afe6f2598989447edd5870bb9da7f62 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Tue, 11 Dec 2018 14:49:55 +0100 Subject: [PATCH 24/62] compile all with -Os but render.c with -Os. Use -msmall-code --- AF_readme | 4 ++++ Makefile.amiga | 15 ++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/AF_readme b/AF_readme index 1309826..b22fe10 100644 --- a/AF_readme +++ b/AF_readme @@ -116,3 +116,7 @@ Aber auch mit patch stürzt das Programm immer ab. ---------- Demos fuer Amiga angepasst. Neues Verzeichnis demos_amiga +11.12.2018 +---------- +Makefile geaendert. Alles ausser render.c wird mit -Os compiliert. rendr.c mit -O2. Alles mir -msamll-code. +SAM ist jetzt 59912 Bytes gross. diff --git a/Makefile.amiga b/Makefile.amiga index 2c94a13..521382b 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -1,4 +1,5 @@ -OBJS = reciter.o sam.o render.o main.o debug.o endian.o sdlwrapper.o portaudio_ahidev.o portaudio_audev.o portaudio.o subtask_support.o amiga_version.o +# All the o-Files in Link-Order +OBJS_ORDERED = reciter.o sam.o render.o main.o debug.o endian.o sdlwrapper.o portaudio_ahidev.o portaudio_audev.o portaudio.o subtask_support.o amiga_version.o COMPILER_INSTALL_DIR = /home/osboxes/opt/m68k-amigaos_06Dec18 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin @@ -14,10 +15,11 @@ CFLAGS += -DPLATFORM_IS_BIG_ENDIAN -DSTATIC_FUNC= -DUSESDL CFLAGS += -DTOOLCHAIN_VER="\"$(TOOLCHAIN_VER)\"" CFLAGS += -Iamiga/ -Iamiga/portaudio/ -I. -I$(COMPILER_INSTALL_DIR)/include/SDL CFLAGS += $(CPUFLAGS) -CFLAGS += -Wall -O2 -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` +CFLAGS += -Os # all but render.c arecompiled for size. Only render.c will be compiled for speed +CFLAGS += -Wall -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` #CFLAGS += -fbaserel -#CFLAGS += -msmall-code +CFLAGS += -msmall-code LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace -ldebug #-lSDL #`sdl-config --libs` #LFLAGS += -fbaserel @@ -41,13 +43,16 @@ vpath subtask_support.c src/amiga/portaudio/ vpath amiga_version.c src/amiga/version/ -sam: $(OBJS) - $(CC) -o sam $(OBJS) $(LFLAGS) +sam: $(OBJS_ORDERED) + $(CC) -o sam $(OBJS_ORDERED) $(LFLAGS) sync strip: sam $(STRIP) $< +render.o: src/render.c + $(CC) $(CFLAGS) -O2 -c $< # this one is compiled with -O2 as it is the time critical part + %.o: src/%.c $(CC) $(CFLAGS) -c $< From 69f2c6e9c269bdf0d7bd996f65cfd7509280f070 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Tue, 11 Dec 2018 16:09:28 +0100 Subject: [PATCH 25/62] removed debug-code from portaudio, audiotask must be __saveds for -fbaserel --- AF_readme | 5 +++ Makefile.amiga | 6 +-- src/amiga/portaudio/portaudio_ahidev.c | 35 ++++++---------- src/amiga/portaudio/portaudio_ahidev.h | 14 ------- src/amiga/portaudio/portaudio_audev.c | 55 +++++++++++--------------- src/amiga/portaudio/portaudio_audev.h | 14 ------- 6 files changed, 43 insertions(+), 86 deletions(-) diff --git a/AF_readme b/AF_readme index b22fe10..e8b5795 100644 --- a/AF_readme +++ b/AF_readme @@ -120,3 +120,8 @@ Demos fuer Amiga angepasst. Neues Verzeichnis demos_amiga ---------- Makefile geaendert. Alles ausser render.c wird mit -Os compiliert. rendr.c mit -O2. Alles mir -msamll-code. SAM ist jetzt 59912 Bytes gross. + +* Portaudio: debug-code entfern. (getMilliseconds(), File +* Audiotask muss __saveds sein, wenn mit -fbaserel uebersetzt wird. +* Programm ist nicht GPL, entsprechenden Header in meinen Audiofiles entfernt. + diff --git a/Makefile.amiga b/Makefile.amiga index 521382b..0904a32 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -18,11 +18,11 @@ CFLAGS += $(CPUFLAGS) CFLAGS += -Os # all but render.c arecompiled for size. Only render.c will be compiled for speed CFLAGS += -Wall -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` -#CFLAGS += -fbaserel +CFLAGS += -fbaserel CFLAGS += -msmall-code -LFLAGS = -g -noixemul -Wl,-Map=sam.map,--trace -ldebug #-lSDL #`sdl-config --libs` -#LFLAGS += -fbaserel +LFLAGS = -g -noixemul $(CPUFLAGS) -Wl,-Map=sam.map,--trace -ldebug #-lSDL #`sdl-config --libs` +LFLAGS += -fbaserel #coverage diff --git a/src/amiga/portaudio/portaudio_ahidev.c b/src/amiga/portaudio/portaudio_ahidev.c index 71a048d..8367b86 100644 --- a/src/amiga/portaudio/portaudio_ahidev.c +++ b/src/amiga/portaudio/portaudio_ahidev.c @@ -1,20 +1,6 @@ /*************************************************************************** * Copyright (C) 2017 by Alexander Fritsch * * email: selco@t-online.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * - * . * ***************************************************************************/ /* Amiga ahi.device part */ @@ -64,14 +50,14 @@ #endif /*extern "C"*/ LONG KPrintF(STRPTR format, ...); - +/* extern unsigned int global_bufsize_factor; // AF Test einstellbare Audio Buffergroesse n mal 512 Bytes extern unsigned int global_benchmark_flag; // AF Einschalten der Ausgabe der durchschnittlichen Zeit fuer die portaudio-Callbackfunktion extern char *global_ProgramName; // AF argv[0] - - +*/ +/* FILE *File_ahi=NULL; // testweise samples in File schreiben - +*/ unsigned int g_AHI_Unit=0; // can be changed via command line (speak.cpp) //UBYTE chans[] ={1,2,4,8}; /* get any of the four channels RKRM Audio-example */ @@ -134,7 +120,7 @@ struct MsgPort *AHImp = NULL; extern struct Device* TimerBase; // nur zum Benchmarking static struct IORequest timereq; // nur zum Benchmarking -VOID /*__asm __saveds*/ SamAudioTask_AHI(VOID) +VOID /*__asm */__saveds SamAudioTask_AHI(VOID) { // KPrintF("%s() called\n",__FUNCTION__); @@ -404,11 +390,12 @@ VOID /*__asm __saveds*/ SamAudioTask_AHI(VOID) //KPrintF("stm=%lx\n",stm); Error=paNoError; // return;// Error; - - if(global_benchmark_flag) /* if Benchmarking was done */ +/* + if(global_benchmark_flag) // if Benchmarking was done { printf("%s, Average BufferTime %lums, Max Buffertime %lums, (Buffer is %lums), Compiled for " __CPU__ " " __FPU__ "\n",global_ProgramName,CallbackTime/CallBackCount,CallBackMaxTime,(ULONG)(global_bufsize_factor*512*1000/PortAudioStreamData->sampleRate)); } +*/ //KPrintF("Calling DeletePort st->st_Port\n"); DeletePort(st->st_Port); st->st_Port=NULL; @@ -604,7 +591,7 @@ PaError Pa_OpenDefaultStream_ahidev( PortAudioStream** stream, StreamNr++; StreamStruct->callback=callback; // store ptr to callback function - StreamStruct->framesPerBuffer=framesPerBuffer*global_bufsize_factor; // AF Test mit n mal 512 Byte Puffern + StreamStruct->framesPerBuffer=framesPerBuffer;//*global_bufsize_factor; // AF Test mit n mal 512 Byte Puffern StreamStruct->numInputChannels=numInputChannels; StreamStruct->numOutputChannels=numOutputChannels; StreamStruct->sampleFormat=sampleFormat; @@ -834,13 +821,13 @@ PaError __attribute__((no_instrument_function)) Pa_CloseStream_ahidev( PortAudio return paBadStreamPtr; // <0 is error } - +/* if(File_ahi) { fclose(File_ahi); File_ahi=NULL; } - +*/ } diff --git a/src/amiga/portaudio/portaudio_ahidev.h b/src/amiga/portaudio/portaudio_ahidev.h index 4b7b07d..3b7d736 100644 --- a/src/amiga/portaudio/portaudio_ahidev.h +++ b/src/amiga/portaudio/portaudio_ahidev.h @@ -1,20 +1,6 @@ /*************************************************************************** * Copyright (C) 2017 by Alexander Fritsch * * email: selco@t-online.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * - * . * ***************************************************************************/ /* diff --git a/src/amiga/portaudio/portaudio_audev.c b/src/amiga/portaudio/portaudio_audev.c index 3b3ac4e..4ece16b 100644 --- a/src/amiga/portaudio/portaudio_audev.c +++ b/src/amiga/portaudio/portaudio_audev.c @@ -1,20 +1,6 @@ /*************************************************************************** * Copyright (C) 2017 by Alexander Fritsch * * email: selco@t-online.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * - * . * ***************************************************************************/ /* Amiga audio.device part */ @@ -89,18 +75,21 @@ void setAudioFilterState(unsigned int val) getAudioFilterState(); } +/* #include static struct timeval startTime; - +*/ +/* void TimerAuDevStartup() { GetSysTime(&startTime); } +*/ +//extern unsigned int global_bufsize_factor; // AF Test einstellbare Audio Buffergroesse n mal 512 Bytes +//extern unsigned int global_benchmark_flag; // AF Einschalten der Ausgabe der durchschnittlichen Zeit fuer die portaudio-Callbackfunktion +//extern char *global_ProgramName; // AF argv[0] -extern unsigned int global_bufsize_factor; // AF Test einstellbare Audio Buffergroesse n mal 512 Bytes -extern unsigned int global_benchmark_flag; // AF Einschalten der Ausgabe der durchschnittlichen Zeit fuer die portaudio-Callbackfunktion -extern char *global_ProgramName; // AF argv[0] - +/* ULONG TimerAuDevGetMilliseconds() { struct timeval endTime; @@ -113,7 +102,7 @@ ULONG TimerAuDevGetMilliseconds() { FILE *File=NULL; // testweise samples in File schreiben - +*/ //UBYTE chans[] ={1,2,4,8}; /* get any of the four channels RKRM Audio-example */ UBYTE chans[] ={3,5,10,12}; /* get a pair of stereo channels, RKRM Devices */ @@ -182,7 +171,7 @@ STATIC_FUNC UWORD Convert8USamples(UBYTE *Source8U, BYTE *Dest8S, ULONG SampleCo struct Device* TimerBase; // nur zum Benchmarking static struct IORequest timereq; // nur zum Benchmarking -VOID /*__asm __saveds*/ SamAudioTask(VOID) +VOID /*__asm*/ __saveds SamAudioTask(VOID) { // KPrintF("%s() called\n",__FUNCTION__); @@ -454,12 +443,13 @@ VOID /*__asm __saveds*/ SamAudioTask(VOID) { }; - +/* if(global_benchmark_flag) { - TimerAuDevStartup(); /* set CallbackTime startvalue */ + TimerAuDevStartup(); // set CallbackTime startvalue } - // printf("Callback() called %u\n",count); +*/ + // printf("Callback() called %u\n",count); if( 0!=PortAudioStreamData->callback(NULL,FastMemBuf,PortAudioStreamData->framesPerBuffer,0,NULL)) /* Last Buffer */ { /* we queue this last buffer for playback and wait for the previous one and this one to finish */ @@ -505,9 +495,10 @@ VOID /*__asm __saveds*/ SamAudioTask(VOID) } else /* There are more buffers to come */ { +/* if(global_benchmark_flag) { - unsigned long Time=TimerAuDevGetMilliseconds(); /* measure time for callbacks for benchmarking */ + unsigned long Time=TimerAuDevGetMilliseconds(); // measure time for callbacks for benchmarking if(Time>CallBackMaxTime) { CallBackMaxTime=Time; @@ -515,7 +506,8 @@ VOID /*__asm __saveds*/ SamAudioTask(VOID) CallbackTime+=Time; CallBackCount+=1; } - //KPrintF("Convert16SSamples($%08lx,$%08lx)\n",(ULONG)PortAudioStreamData->FastMemBuf1, (ULONG)PortAudioStreamData->ChipMemBuf1); +*/ + //KPrintF("Convert16SSamples($%08lx,$%08lx)\n",(ULONG)PortAudioStreamData->FastMemBuf1, (ULONG)PortAudioStreamData->ChipMemBuf1); //fwrite(PortAudioStreamData->FastMemBuf1,PortAudioStreamData->framesPerBuffer,1,File); Convert8USamples(FastMemBuf, ChipMemBuf ,PortAudioStreamData->framesPerBuffer); @@ -573,11 +565,12 @@ VOID /*__asm __saveds*/ SamAudioTask(VOID) BeginIO((struct IORequest*)PortAudioStreamData->AIOptr1); PortAudioStreamData->AIOptr2->ioa_Request.io_Command=ADCMD_FINISH; BeginIO((struct IORequest*)PortAudioStreamData->AIOptr2); - - if(global_benchmark_flag) /* if Benchmarking was done */ +/* + if(global_benchmark_flag) // if Benchmarking was done { printf("%s, Average BufferTime %lums, Max Buffertime %lums, (Buffer is %lums), Compiled for " __CPU__ " " __FPU__ "\n",global_ProgramName,CallbackTime/CallBackCount,CallBackMaxTime,(ULONG)(global_bufsize_factor*512*1000/PortAudioStreamData->sampleRate)); } +*/ //KPrintF("Calling DeletePort st->st_Port\n"); DeletePort(st->st_Port); st->st_Port=NULL; @@ -812,7 +805,7 @@ PaError Pa_OpenDefaultStream_audev( PortAudioStream** stream, StreamNr++; StreamStruct->callback=callback; // store ptr to callback function - StreamStruct->framesPerBuffer=framesPerBuffer*global_bufsize_factor; // AF Test mit n mal 512 Byte Puffern + StreamStruct->framesPerBuffer=framesPerBuffer;//*global_bufsize_factor; // AF Test mit n mal 512 Byte Puffern StreamStruct->numInputChannels=numInputChannels; StreamStruct->numOutputChannels=numOutputChannels; StreamStruct->sampleFormat=sampleFormat; @@ -1101,13 +1094,13 @@ PaError __attribute__((no_instrument_function)) Pa_CloseStream_audev( PortAudioS return paBadStreamPtr; // <0 is error } - +/* if(File) { fclose(File); File=NULL; } - +*/ } diff --git a/src/amiga/portaudio/portaudio_audev.h b/src/amiga/portaudio/portaudio_audev.h index 065362f..4efd64c 100644 --- a/src/amiga/portaudio/portaudio_audev.h +++ b/src/amiga/portaudio/portaudio_audev.h @@ -1,20 +1,6 @@ /*************************************************************************** * Copyright (C) 2017 by Alexander Fritsch * * email: selco@t-online.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * - * . * ***************************************************************************/ /* * portaudio_audev.h From e428c349d00b02f06de76c65e1f1f1650320ac84 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Tue, 11 Dec 2018 16:28:23 +0100 Subject: [PATCH 26/62] portaudion-ahi still wanted chip-mem. fixed. removed timer-debug-stuff from portaudio --- src/amiga/portaudio/portaudio_ahidev.c | 57 ++------------------- src/amiga/portaudio/portaudio_audev.c | 68 -------------------------- 2 files changed, 4 insertions(+), 121 deletions(-) diff --git a/src/amiga/portaudio/portaudio_ahidev.c b/src/amiga/portaudio/portaudio_ahidev.c index 8367b86..4611988 100644 --- a/src/amiga/portaudio/portaudio_ahidev.c +++ b/src/amiga/portaudio/portaudio_ahidev.c @@ -88,12 +88,12 @@ typedef struct struct MsgPort *AHImp; struct MsgPort *portStartStop; ULONG device; // Audio device handle - BYTE *ChipMemBuf1; // Amiga-Audiobuffer - BYTE *ChipMemBuf2; // Amiga-Audiobuffer +// BYTE *ChipMemBuf1; // Amiga-Audiobuffer +// BYTE *ChipMemBuf2; // Amiga-Audiobuffer SHORT *FastMemBuf1; // Espeak-AudioBuffer used in Callback SHORT *FastMemBuf2; // Espeak-AudioBuffer used in Callback - unsigned int LeftChannel; // left Audiochannel we got allocated in OpenDevice() or 0 - unsigned int RightChannel; // right Audiochannel we got allocated in OpenDevice() or 0 +// unsigned int LeftChannel; // left Audiochannel we got allocated in OpenDevice() or 0 +// unsigned int RightChannel; // right Audiochannel we got allocated in OpenDevice() or 0 }PortAudioStreamStruct; @@ -117,8 +117,6 @@ void ConvertU8Samples(UBYTE *data, unsigned int SampleCount) // AHI does not sup // Loeschen! struct MsgPort *AHImp = NULL; -extern struct Device* TimerBase; // nur zum Benchmarking -static struct IORequest timereq; // nur zum Benchmarking VOID /*__asm */__saveds SamAudioTask_AHI(VOID) { @@ -152,10 +150,6 @@ VOID /*__asm */__saveds SamAudioTask_AHI(VOID) PortAudioStreamStruct *PortAudioStreamData=(PortAudioStreamStruct*)(st->st_Data); int Error=paInternalError; - if(0==OpenDevice((CONST_STRPTR)TIMERNAME, UNIT_MICROHZ, &timereq, 0)) // nur zum test - { - TimerBase = timereq.io_Device; // nur zum test - /* Make four Reply-Ports */ PortAudioStreamData->AHImp=CreatePort(0,0); if(PortAudioStreamData->AHImp) @@ -434,12 +428,6 @@ VOID /*__asm */__saveds SamAudioTask_AHI(VOID) printf(" Could not create AHImp\n"); Error=paInsufficientMemory; } - CloseDevice(&timereq); - } - else - { - printf(" Could not open " TIMERNAME"\n"); - } // Error uebergeben? //KPrintF("Calling ExitSubtask. stm=%lx\n",(ULONG)stm); @@ -605,16 +593,8 @@ PaError Pa_OpenDefaultStream_ahidev( PortAudioStream** stream, GlobalPaStreamPtr_ahi=StreamStruct; /* in case of CTRL-C atexit()-Functions are void so a global pointer is needed */ - /* Allocate two Audio Buffers in ChipMem for Amiga-8Bit-Samples */ - StreamStruct->ChipMemBuf1=(BYTE*)AllocMem(StreamStruct->framesPerBuffer,MEMF_CHIP); - if(StreamStruct->ChipMemBuf1) - { //KPrintF("Zeile %ld\n",__LINE__); - StreamStruct->ChipMemBuf2=(BYTE*)AllocMem(StreamStruct->framesPerBuffer,MEMF_CHIP); - if(StreamStruct->ChipMemBuf2) - { - //KPrintF("Zeile %ld\n",__LINE__); /* Allocate two Audio Buffers in FastMem for Espeak-16Bit-Samples */ StreamStruct->FastMemBuf1=(SHORT*)AllocMem(StreamStruct->framesPerBuffer*Pa_GetSampleSize(StreamStruct->sampleFormat),MEMF_PUBLIC); @@ -691,22 +671,6 @@ PaError Pa_OpenDefaultStream_ahidev( PortAudioStream** stream, printf(" Could not allocate FastMemBuf1 (%lu Bytes)\n",StreamStruct->framesPerBuffer*Pa_GetSampleSize(StreamStruct->sampleFormat)); Error=paInsufficientMemory; } - FreeMem(StreamStruct->ChipMemBuf2,StreamStruct->framesPerBuffer); - StreamStruct->ChipMemBuf2=NULL; - } - else - { - printf(" Could not allocate ChipMemBuf2 (%lu Bytes)\n",StreamStruct->framesPerBuffer); - Error=paInsufficientMemory; - } - FreeMem(StreamStruct->ChipMemBuf1,StreamStruct->framesPerBuffer); - StreamStruct->ChipMemBuf1=NULL; - } - else - { - printf(" Could not allocate ChipMemBuf1 (%lu Bytes)\n",StreamStruct->framesPerBuffer); - Error=paInsufficientMemory; - } free(StreamStruct); StreamStruct=NULL; @@ -794,19 +758,6 @@ PaError __attribute__((no_instrument_function)) Pa_CloseStream_ahidev( PortAudio StreamStruct->FastMemBuf1=NULL; } - - if(StreamStruct->ChipMemBuf2) - { - FreeMem(StreamStruct->ChipMemBuf2,StreamStruct->framesPerBuffer); - StreamStruct->ChipMemBuf2=NULL; - } - - if(StreamStruct->ChipMemBuf1) - { - FreeMem(StreamStruct->ChipMemBuf1,StreamStruct->framesPerBuffer); - StreamStruct->ChipMemBuf1=NULL; - } - free(StreamStruct); GlobalPaStreamPtr_ahi=NULL; /* in case of CTRL-C atexit()-Functions are void so a global pointer is needed */ diff --git a/src/amiga/portaudio/portaudio_audev.c b/src/amiga/portaudio/portaudio_audev.c index 4ece16b..324db0b 100644 --- a/src/amiga/portaudio/portaudio_audev.c +++ b/src/amiga/portaudio/portaudio_audev.c @@ -75,34 +75,6 @@ void setAudioFilterState(unsigned int val) getAudioFilterState(); } -/* -#include -static struct timeval startTime; -*/ -/* -void TimerAuDevStartup() { - GetSysTime(&startTime); -} -*/ - -//extern unsigned int global_bufsize_factor; // AF Test einstellbare Audio Buffergroesse n mal 512 Bytes -//extern unsigned int global_benchmark_flag; // AF Einschalten der Ausgabe der durchschnittlichen Zeit fuer die portaudio-Callbackfunktion -//extern char *global_ProgramName; // AF argv[0] - -/* -ULONG TimerAuDevGetMilliseconds() { - struct timeval endTime; - - GetSysTime(&endTime); - SubTime(&endTime, &startTime); - - return (endTime.tv_secs * 1000 + endTime.tv_micro / 1000); -} - - - -FILE *File=NULL; // testweise samples in File schreiben -*/ //UBYTE chans[] ={1,2,4,8}; /* get any of the four channels RKRM Audio-example */ UBYTE chans[] ={3,5,10,12}; /* get a pair of stereo channels, RKRM Devices */ @@ -168,8 +140,6 @@ void SetAudioUnit(struct IOAudio *AIOptr,unsigned int Channel) STATIC_FUNC UWORD Convert8USamples(UBYTE *Source8U, BYTE *Dest8S, ULONG SampleCount); /* reads 16Bit Signed Samples from Source and writes 8Bit Signed Samples to Dest. DestLen Samples will be read */ -struct Device* TimerBase; // nur zum Benchmarking -static struct IORequest timereq; // nur zum Benchmarking VOID /*__asm*/ __saveds SamAudioTask(VOID) { @@ -201,10 +171,6 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) PortAudioStreamStruct *PortAudioStreamData=(PortAudioStreamStruct*)(st->st_Data); int Error=paInternalError; - if(0==OpenDevice((CONST_STRPTR)TIMERNAME, UNIT_MICROHZ, &timereq, 0)) // nur zum test - { - TimerBase = timereq.io_Device; // nur zum test - /* Make four Reply-Ports */ PortAudioStreamData->port1=CreatePort(0,0); if(PortAudioStreamData->port1) @@ -443,12 +409,6 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) { }; -/* - if(global_benchmark_flag) - { - TimerAuDevStartup(); // set CallbackTime startvalue - } -*/ // printf("Callback() called %u\n",count); if( 0!=PortAudioStreamData->callback(NULL,FastMemBuf,PortAudioStreamData->framesPerBuffer,0,NULL)) /* Last Buffer */ { @@ -495,18 +455,6 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) } else /* There are more buffers to come */ { -/* - if(global_benchmark_flag) - { - unsigned long Time=TimerAuDevGetMilliseconds(); // measure time for callbacks for benchmarking - if(Time>CallBackMaxTime) - { - CallBackMaxTime=Time; - } - CallbackTime+=Time; - CallBackCount+=1; - } -*/ //KPrintF("Convert16SSamples($%08lx,$%08lx)\n",(ULONG)PortAudioStreamData->FastMemBuf1, (ULONG)PortAudioStreamData->ChipMemBuf1); //fwrite(PortAudioStreamData->FastMemBuf1,PortAudioStreamData->framesPerBuffer,1,File); @@ -535,15 +483,6 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) } - //TimerAuuDevstartup(); // Zeit Anfang - //KPrintF("PortAudioStreamData->port1->mp_SigBit = 0x%04lx\n",(ULONG)PortAudioStreamData->port1->mp_SigBit); - //KPrintF("wakebit = 0x%04lx\n",(ULONG)wakebit); - //KPrintF("st->st_Port->mp_SigBit = 0x%04lx\n\n",(ULONG)st->st_Port->mp_SigBit); - - //ULONG Zeit=getMilliseconds(); - //KPrintF("Dauer: %lums\n",Zeit); - - // fwrite(PortAudioStreamData->ChipMemBuf1,PortAudioStreamData->framesPerBuffer,1,File); /* Since we are very busy working, we do not Wait() for signals. */ } else @@ -637,13 +576,6 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) Error=paInsufficientMemory; } - CloseDevice(&timereq); - } - else - { - printf(" Could not open " TIMERNAME "\n"); - } - // Error uebergeben? //KPrintF("Calling ExitSubtask. stm=%lx\n",(ULONG)stm); ExitSubTask(st,stm); From bb8b386b48abdc8fe93c5abd5a9661f8a5e44618 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Fri, 14 Dec 2018 15:19:27 +0100 Subject: [PATCH 27/62] 68000/68020 aware Render() and RenderSample(), guess_number.rexx --- AF_readme | 3 + Makefile.amiga | 12 ++-- demos_amiga/guess_number.rexx | 92 ++++++++++++++++++++++++++ sam.readme | 36 ++++++++++ src/amiga/portaudio/portaudio_ahidev.c | 31 ++++----- src/amiga/portaudio/portaudio_audev.c | 47 ++++++------- src/amiga/sdlwrapper.c | 3 + src/main.c | 5 ++ src/render.c | 27 ++++++++ 9 files changed, 209 insertions(+), 47 deletions(-) create mode 100755 demos_amiga/guess_number.rexx create mode 100644 sam.readme diff --git a/AF_readme b/AF_readme index e8b5795..75d9643 100644 --- a/AF_readme +++ b/AF_readme @@ -125,3 +125,6 @@ SAM ist jetzt 59912 Bytes gross. * Audiotask muss __saveds sein, wenn mit -fbaserel uebersetzt wird. * Programm ist nicht GPL, entsprechenden Header in meinen Audiofiles entfernt. +14.12.2018 +---------- +Render() und RenderSample() gibt es jetzt als 68000 und 68020 Version, die automatisch ausgewaehlt werden. guess_number.rexx gemacht. Portaudio warnings behoben. diff --git a/Makefile.amiga b/Makefile.amiga index 0904a32..04324eb 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -1,5 +1,5 @@ # All the o-Files in Link-Order -OBJS_ORDERED = reciter.o sam.o render.o main.o debug.o endian.o sdlwrapper.o portaudio_ahidev.o portaudio_audev.o portaudio.o subtask_support.o amiga_version.o +OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o render.o render000.o render020.o main.o portaudio_ahidev.o portaudio.o subtask_support.o amiga_version.o COMPILER_INSTALL_DIR = /home/osboxes/opt/m68k-amigaos_06Dec18 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin @@ -18,11 +18,11 @@ CFLAGS += $(CPUFLAGS) CFLAGS += -Os # all but render.c arecompiled for size. Only render.c will be compiled for speed CFLAGS += -Wall -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` -CFLAGS += -fbaserel +#CFLAGS += -fbaserel CFLAGS += -msmall-code LFLAGS = -g -noixemul $(CPUFLAGS) -Wl,-Map=sam.map,--trace -ldebug #-lSDL #`sdl-config --libs` -LFLAGS += -fbaserel +#LFLAGS += -fbaserel #coverage @@ -50,9 +50,11 @@ sam: $(OBJS_ORDERED) strip: sam $(STRIP) $< -render.o: src/render.c - $(CC) $(CFLAGS) -O2 -c $< # this one is compiled with -O2 as it is the time critical part +render000.o: src/render2.c + $(CC) $(CFLAGS) -Os -c $< -o render000.o # this one is compiled with -O2 as it is the time critical part +render020.o: src/render2.c + $(CC) $(CFLAGS) -m68020 -Os -c $< -o render020.o # this one is compiled with -O2 as it is the time critical part %.o: src/%.c $(CC) $(CFLAGS) -c $< diff --git a/demos_amiga/guess_number.rexx b/demos_amiga/guess_number.rexx new file mode 100755 index 0000000..67804d9 --- /dev/null +++ b/demos_amiga/guess_number.rexx @@ -0,0 +1,92 @@ +/* /start with "rx guess_number.rexx" */ +/* Adapted by AF, 14.Dec.2018 */ + +ADDLIB("rexxsupport.library",0, -30, 0) + +/* RANDOM() always delivers the same sequence, seems a varying seed is needed. */ +Seed=TIME(SECONDS) +SAY "Seed="Seed + +MAIN: /*:MAIN*/ +cls() +number=RANDOM(1,100,Seed) +/* rem goto WINNER */ +DELAY(50) +ECHO "Sam's NUMBER GUESSING GAME!" +ADDRESS COMMAND; "/SAM" "Sam's NUMBER GUESSING GAME!"; ADDRESS REXX +DELAY(50) +ECHO +DELAY(50) +ECHO +DELAY(50) +ECHO +DELAY(50) +ECHO "It's easy to play!" +ADDRESS COMMAND; "/SAM" "It's easy to play!"; ADDRESS REXX +DELAY(50) +ECHO +DELAY(50) +ECHO "The computer generates a number between 1 and 100, and you try to guess it!" +ADDRESS COMMAND; "/SAM" "The computer generates a number between 1 and 1 hundred, and you try to guess it!"; ADDRESS REXX +DELAY(50) +ECHO +DELAY(50) +ECHO +DELAY(50) +ECHO +ECHO "To begin the game, type your name and press Enter" +ADDRESS COMMAND; "/SAM" "To begin the game, type your name and press Enter"; ADDRESS REXX +PULL Name +HOME: +cls() +ECHO "Well" Name "Now GUESS THE NUMBER!" +ADDRESS COMMAND; "/SAM" "Well " Name ", now GUESS THE NUMBER!"; ADDRESS REXX +ECHO +ECHO +PULL guess +ECHO + +SELECT + WHEN guess < number THEN SIGNAL LOWER + WHEN guess > number THEN SIGNAL HIGHER + WHEN guess = number THEN SIGNAL WINNER +END + +LOWER: +cls() +ECHO "Your guess is lower than the number!" +ADDRESS COMMAND; "/SAM" "Your guess is lower than the number!"; ADDRESS REXX +ECHO +ECHO +pause +SIGNAL HOME + +HIGHER: +cls() +ECHO "Your guess is higher than the number!" +ADDRESS COMMAND; "/SAM" "Your guess is higher than the number!"; ADDRESS REXX +ECHO +ECHO +SIGNAL HOME + +WINNER: +cls() +ECHO +ADDRESS COMMAND; "/SAM" "-speed 55 -pitch 92 -throat 128 -mouth 128 " "Ha ha ha ha ha ha ha? Ha ha ha ha ha ha ha!"; ADDRESS REXX +ECHO "Congratulations " Name "! You guessed the number correctly!" +ADDRESS COMMAND; "/SAM" "Congratulations" Name "!"; ADDRESS REXX +ADDRESS COMMAND; "/SAM" "You guessed the number correctly!"; ADDRESS REXX +ECHO +ECHO +ECHO "The number was" number +ADDRESS COMMAND; "/SAM" "The number was" Number; ADDRESS REXX +ECHO "Thanks for playing " Name ",thanks for playing!" +ADDRESS COMMAND; "/SAM" "Thanks for playing?" Name "Thanks for playing."; ADDRESS REXX +DELAY(100) +EXIT + + +cls: PROCEDURE +ECHO "1B"x"[0;0H" "1B"x"[J" +RETURN 0 + diff --git a/sam.readme b/sam.readme new file mode 100644 index 0000000..47c439e --- /dev/null +++ b/sam.readme @@ -0,0 +1,36 @@ +Short: amiga-port of famous C64 speech synthesizer SAM +Author: sebastian@macke.de (Sebastian Macke) +Uploader: selco@t-online.de (Alexander Fritsch) +Type: util/sys +Version: 1.1 +Architecture: m68k-amigaos +Distribution: Aminet + + +This is the Amiga port of Sebastian Macke's C-adaption of the speech software +SAM (Software Automatic Mouth) for the Commodore C64. +It creates a nice sounding voice direct from text. That sound can be played +via audio.device (default) or via ahi.device (-ahi unit). The sound can +also be saved to a wave-file. Input is possible in either English text mode +for automatic translation or in phoneme mode (-phonetic) + +Just enter sam to get a list of options. + +sam Hello, my name is sam. + +For a few more examples cd into demos_amiga drawer and enjoy the show. + +cd demos_amiga +execute demo1 +execute demo2 +; and so on... +; also try the tiny game +rx guess_number.rexx + + +Requirements: +Any Amiga will do. An 68000 is sufficient but an 68020 or better is utilized +if present. On a plain 7MHz 68000 it takes a few seconds to calculate until +sound occurs. Standard Amiga stack (4096) is sufficient. +Either audio.device or ahi.device are used for playback. + diff --git a/src/amiga/portaudio/portaudio_ahidev.c b/src/amiga/portaudio/portaudio_ahidev.c index 4611988..8be173f 100644 --- a/src/amiga/portaudio/portaudio_ahidev.c +++ b/src/amiga/portaudio/portaudio_ahidev.c @@ -148,7 +148,7 @@ VOID /*__asm */__saveds SamAudioTask_AHI(VOID) BOOL worktodo = FALSE; PortAudioStreamStruct *PortAudioStreamData=(PortAudioStreamStruct*)(st->st_Data); - int Error=paInternalError; + //int Error=paInternalError; /* Make four Reply-Ports */ PortAudioStreamData->AHImp=CreatePort(0,0); @@ -215,9 +215,9 @@ VOID /*__asm */__saveds SamAudioTask_AHI(VOID) /* variables are declared here because they should be initialized to Zero */ /* in the for loop they would become initialized at the beginning of every turn - which is wrong */ - ULONG CallbackTime=0; /* For Callback benchmarking */ - ULONG CallBackCount=0; - ULONG CallBackMaxTime=0; + //ULONG CallbackTime=0; /* For Callback benchmarking */ + //ULONG CallBackCount=0; + //ULONG CallBackMaxTime=0; ULONG BufferLength=PortAudioStreamData->framesPerBuffer * Pa_GetSampleSize_ahidev(PortAudioStreamData->sampleFormat); @@ -297,7 +297,7 @@ VOID /*__asm */__saveds SamAudioTask_AHI(VOID) { //#ifdef ALEXANDER int LastBuf; - ULONG signals; + //ULONG signals; /* if there is work to do,... */ @@ -337,15 +337,8 @@ VOID /*__asm */__saveds SamAudioTask_AHI(VOID) if(link) { // Wait until the last buffer is finished (== the new buffer is started) - signals=Wait(SIGBREAKF_CTRL_C | (1L << PortAudioStreamData->AHImp->mp_SigBit)); -#ifdef ALEXANDER - // Check for Ctrl-C and abort if pressed - if(signals & SIGBREAKF_CTRL_C) { - SetIoErr(ERROR_BREAK); - break; - } -#endif -// Remove the reply and abort on error + /*signals=*/Wait(SIGBREAKF_CTRL_C | (1L << PortAudioStreamData->AHImp->mp_SigBit)); + // Remove the reply and abort on error if(WaitIO((struct IORequest *) link)) { SetIoErr(ERROR_WRITE_PROTECTED); // break; @@ -382,7 +375,7 @@ VOID /*__asm */__saveds SamAudioTask_AHI(VOID) } //KPrintF("stm=%lx\n",stm); - Error=paNoError; + //Error=paNoError; // return;// Error; /* if(global_benchmark_flag) // if Benchmarking was done @@ -397,7 +390,7 @@ VOID /*__asm */__saveds SamAudioTask_AHI(VOID) else // st->st_Port = CreateMsgPort() failed { printf(" Subtask CreateMsgPort() failed\n"); - Error=paInsufficientMemory; + //Error=paInsufficientMemory; } //KPrintF("Calling CloseDevice\n"); CloseDevice((struct IORequest*)PortAudioStreamData->AHIio); @@ -406,7 +399,7 @@ VOID /*__asm */__saveds SamAudioTask_AHI(VOID) else { printf(" Could not open " AHINAME " version 4\n"); - Error=paDeviceUnavailable; + //Error=paDeviceUnavailable; } //KPrintF("Calling DeletePortStartStop\n"); @@ -416,7 +409,7 @@ VOID /*__asm */__saveds SamAudioTask_AHI(VOID) else { printf(" Could not create portStartStop\n"); - Error=paInsufficientMemory; + //Error=paInsufficientMemory; } //KPrintF("Calling DeleteAHImp\n"); DeletePort(PortAudioStreamData->AHImp); @@ -426,7 +419,7 @@ VOID /*__asm */__saveds SamAudioTask_AHI(VOID) else { printf(" Could not create AHImp\n"); - Error=paInsufficientMemory; + //Error=paInsufficientMemory; } // Error uebergeben? diff --git a/src/amiga/portaudio/portaudio_audev.c b/src/amiga/portaudio/portaudio_audev.c index 324db0b..74dbf4c 100644 --- a/src/amiga/portaudio/portaudio_audev.c +++ b/src/amiga/portaudio/portaudio_audev.c @@ -169,7 +169,7 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) BOOL worktodo = FALSE; PortAudioStreamStruct *PortAudioStreamData=(PortAudioStreamStruct*)(st->st_Data); - int Error=paInternalError; + //int Error=paInternalError; /* Make four Reply-Ports */ PortAudioStreamData->port1=CreatePort(0,0); @@ -279,9 +279,9 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) BYTE *ChipMemBuf=NULL; /* Amiga-Audiobuffer for double buffer switching */ SHORT *FastMemBuf=NULL; /* Espeak-AudioBuffer used in Callback for double buffer switching */ - ULONG CallbackTime=0; /* For Callback benchmarking */ - ULONG CallBackCount=0; - ULONG CallBackMaxTime=0; + //ULONG CallbackTime=0; /* For Callback benchmarking */ + //ULONG CallBackCount=0; + //ULONG CallBackMaxTime=0; stm->stm_Result = TRUE; ReplyMsg((struct Message *)stm); @@ -397,14 +397,14 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) */ struct Message *msg; - ULONG wakebit; + //ULONG wakebit; - wakebit=Wait(1 << port->mp_SigBit); + /*wakebit=*/Wait(1 << port->mp_SigBit); while((msg=GetMsg(port))==0) { }; //KPrintF("GetMsg() returned 0x%08lx\n",msg); - wakebit=Wait(1 << port_2->mp_SigBit); + /*wakebit=*/Wait(1 << port_2->mp_SigBit); while((msg=GetMsg(port_2))==0) // the 2. channel has also finished. Clear that message queue, too { }; @@ -433,9 +433,9 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) port=PortAudioStreamData->port1; port_2=PortAudioStreamData->port1_2; } - wakebit=Wait(1 << port->mp_SigBit); /* wait until last buffer has finished */ + /*wakebit=*/Wait(1 << port->mp_SigBit); /* wait until last buffer has finished */ while((msg=GetMsg(port))==0) {}; - wakebit=Wait(1 << port_2->mp_SigBit); /* wait until last buffer has finished */ + /*wakebit=*/Wait(1 << port_2->mp_SigBit); /* wait until last buffer has finished */ while((msg=GetMsg(port_2))==0) {}; if(Aptr==(struct IOAudio*)PortAudioStreamData->AIOptr1) @@ -448,9 +448,9 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) port=PortAudioStreamData->port1; port_2=PortAudioStreamData->port1_2; } - wakebit=Wait(1 << port->mp_SigBit); /* wait until last bufer has finished */ + /*wakebit=*/Wait(1 << port->mp_SigBit); /* wait until last bufer has finished */ while((msg=GetMsg(port))==0) {}; - wakebit=Wait(1 << port_2->mp_SigBit); /* wait until last bufer has finished */ + /*wakebit=*/Wait(1 << port_2->mp_SigBit); /* wait until last bufer has finished */ while((msg=GetMsg(port_2))==0) {}; } else /* There are more buffers to come */ @@ -496,8 +496,8 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) //KPrintF("stm=%lx\n",stm); - Error=paNoError; - // return;// Error; + //Error=paNoError; + // return;// Error; /* Wait for sound to finish ALEXANDER */ PortAudioStreamData->AIOptr1->ioa_Request.io_Command=ADCMD_FINISH; @@ -517,7 +517,7 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) else // st->st_Port = CreateMsgPort() failed { printf(" Subtask CreateMsgPort() failed\n"); - Error=paInsufficientMemory; + //Error=paInsufficientMemory; } //KPrintF("Calling CloseDevice\n"); CloseDevice((struct IORequest*)PortAudioStreamData->AIOptr1); @@ -526,7 +526,7 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) else { printf(" Could not open " AUDIONAME "\n"); - Error=paDeviceUnavailable; + //Error=paDeviceUnavailable; } /* --------------------- */ //KPrintF("Calling DeletePortStartStop\n"); @@ -536,7 +536,7 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) else { printf(" Could not create portStartStop\n"); - Error=paInsufficientMemory; + //Error=paInsufficientMemory; } //KPrintF("Calling DeletePort2_2\n"); DeletePort(PortAudioStreamData->port2_2); @@ -546,7 +546,7 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) else { printf(" Could not create port2_2\n"); - Error=paInsufficientMemory; + //Error=paInsufficientMemory; } //KPrintF("Calling DeletePort2\n"); DeletePort(PortAudioStreamData->port2); @@ -555,7 +555,7 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) else { printf(" Could not create port2\n"); - Error=paInsufficientMemory; + //Error=paInsufficientMemory; } //KPrintF("Calling DeletePort1_2\n"); DeletePort(PortAudioStreamData->port1_2); @@ -564,7 +564,7 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) else { printf(" Could not create port1_2\n"); - Error=paInsufficientMemory; + //Error=paInsufficientMemory; } //KPrintF("Calling DeletePort1\n"); DeletePort(PortAudioStreamData->port1); @@ -573,7 +573,7 @@ VOID /*__asm*/ __saveds SamAudioTask(VOID) else { printf(" Could not create port1\n"); - Error=paInsufficientMemory; + //Error=paInsufficientMemory; } // Error uebergeben? @@ -1124,22 +1124,23 @@ STATIC_FUNC UWORD Convert8USamples(UBYTE *Source8U, BYTE *Dest8S, ULONG SampleCo { *Dest8S++=(*Source8U++)-128; } + return (UWORD)SampleCount; } #endif /* used for atexit(). Therefore void parameter -> global Pointer needed */ -void __attribute__((no_instrument_function)) Abort_Pa_CloseStream_audev (void) +void Abort_Pa_CloseStream_audev (void) { if(GlobalPaStreamPtr) { - KPrintF("%s() called with Stream=$%08lx\n",__FUNCTION__,GlobalPaStreamPtr); + // KPrintF("%s() called with Stream=$%08lx\n",__FUNCTION__,GlobalPaStreamPtr); Pa_CloseStream_audev(GlobalPaStreamPtr); GlobalPaStreamPtr=NULL; } else { - KPrintF("%s() called but nothing to do\n",__FUNCTION__); + // KPrintF("%s() called but nothing to do\n",__FUNCTION__); } } diff --git a/src/amiga/sdlwrapper.c b/src/amiga/sdlwrapper.c index db417ba..e4fceea 100644 --- a/src/amiga/sdlwrapper.c +++ b/src/amiga/sdlwrapper.c @@ -12,6 +12,9 @@ unsigned int global_bufsize_factor=1; #include "portaudio18.h" +LONG KPrintF(STRPTR format, ...); +void Abort_Pa_CloseStream_audev (void); + static PortAudioStream *pa_stream=NULL; diff --git a/src/main.c b/src/main.c index 38a8930..cca1bd8 100644 --- a/src/main.c +++ b/src/main.c @@ -17,6 +17,7 @@ #include // AF, Test #ifdef __AMIGA__ // AF, use ahi.device instead of audio.device void set_ahi_devide(unsigned int unit); + void SetCpuSpecificFunctions(void); // AF, we compile some functions for 68000 and for 68020 #endif @@ -180,6 +181,10 @@ int main(int argc, char **argv) #endif #endif +#ifdef __AMIGA__ + SetCpuSpecificFunctions(); +#endif + for(i=0; i<256; i++) input[i] = 0; if (argc <= 1) diff --git a/src/render.c b/src/render.c index 4ebdbab..a88721f 100755 --- a/src/render.c +++ b/src/render.c @@ -131,6 +131,29 @@ void Write(unsigned char p, unsigned char Y, unsigned char value) +#ifdef __AMIGA__ + + #include + void Render_000(void); + void Render_020(void); + + void (*Render_Function)(void); + + void SetCpuSpecificFunctions(void) + { + extern struct ExecBase *SysBase; + if(SysBase->AttnFlags&AFF_68020) + { + Render_Function=Render_020; + } + else + { + Render_Function=Render_000; + } + } +#endif + + // ------------------------------------------------------------------------- //Code48227 // Render a sampled sound from the sampleTable. @@ -360,6 +383,9 @@ void RenderSample(unsigned char *mem66) //void Code47574() void Render() { +#ifdef __AMIGA__ + Render_Function(); +#else unsigned char phase1 = 0; //mem43 unsigned char phase2; unsigned char phase3; @@ -941,6 +967,7 @@ if (debug) mem66 = Y; Y = mem49; return; +#endif } From 17a56e8a18658dc4d421f65d83b1b5bd7a2de8a7 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Fri, 14 Dec 2018 15:44:30 +0100 Subject: [PATCH 28/62] forget to add render2.c (containing the 68000/68020 specific functions) --- src/render2.c | 908 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 908 insertions(+) create mode 100644 src/render2.c diff --git a/src/render2.c b/src/render2.c new file mode 100644 index 0000000..5d92f05 --- /dev/null +++ b/src/render2.c @@ -0,0 +1,908 @@ + +#ifdef mc68020 + #warning __mc68020__ + #define CPU_TYPE(x) x##_020 // https://stackoverflow.com/questions/1253934/c-pre-processor-defining-for-generated-function-names + #define CPU(x) CPU_TYPE(x) +#elif __mc68000__ + #warning 68000 + #define CPU_TYPE(x) x##_000 // https://stackoverflow.com/questions/1253934/c-pre-processor-defining-for-generated-function-names + #define CPU(x) CPU_TYPE(x) +#else +#warning NO valid CPU defined + #define CPU_TYPE(x) x##_standard // https://stackoverflow.com/questions/1253934/c-pre-processor-defining-for-generated-function-names + #define CPU(x) CPU_TYPE(x) +#endif + +#include +#include +#include "debug.h" + +/* from RenderTas.h */ +extern unsigned char multtable[256]; +extern unsigned char tab48426[5]; +extern unsigned char sampleTable[0x500]; +extern unsigned char tab47492[11]; +extern unsigned char amplitudeRescale[17]; // 17 also in RenderTab.h +extern unsigned char blendRank[80]; +extern unsigned char outBlendLength[80]; +extern unsigned char inBlendLength[80]; + +extern unsigned char sampledConsonantFlags[256]; +extern unsigned char freq1data[80]; +extern unsigned char freq2data[80]; +extern unsigned char freq3data[80]; +extern unsigned char ampl1data[80]; +extern unsigned char ampl2data[80]; +extern unsigned char ampl3data[80]; +extern unsigned char const sinus[256]; +extern unsigned char const rectangle[256]; + + + +extern int debug; + +extern unsigned char wait2; + + +extern unsigned char A, X, Y; +extern unsigned char mem44; +extern unsigned char mem47; +extern unsigned char mem49; +extern unsigned char mem39; +extern unsigned char mem50; +extern unsigned char mem51; +extern unsigned char mem53; +extern unsigned char mem56; + +extern unsigned char speed; +extern unsigned char pitch; +extern int singmode; + +extern unsigned char phonemeIndexOutput[60]; //tab47296 +extern unsigned char stressOutput[60]; //tab47365 +extern unsigned char phonemeLengthOutput[60]; //tab47416 + +extern unsigned char pitches[256]; // tab43008 + +extern unsigned char frequency1[256]; +extern unsigned char frequency2[256]; +extern unsigned char frequency3[256]; + +extern unsigned char amplitude1[256]; +extern unsigned char amplitude2[256]; +extern unsigned char amplitude3[256]; + +void AddInflection(unsigned char mem48, unsigned char phase1); +unsigned char Read(unsigned char p, unsigned char Y); +void Write(unsigned char p, unsigned char Y, unsigned char value); + + +// contains the final soundbuffer +extern int bufferpos; +extern char *buffer; + +extern unsigned char sampledConsonantFlag[256]; // tab44800 + +void Output(int index, unsigned char A); + + +// ------------------------------------------------------------------------- +//Code48227 +// Render a sampled sound from the sampleTable. +// +// Phoneme Sample Start Sample End +// 32: S* 15 255 +// 33: SH 257 511 +// 34: F* 559 767 +// 35: TH 583 767 +// 36: /H 903 1023 +// 37: /X 1135 1279 +// 38: Z* 84 119 +// 39: ZH 340 375 +// 40: V* 596 639 +// 41: DH 596 631 +// +// 42: CH +// 43: ** 399 511 +// +// 44: J* +// 45: ** 257 276 +// 46: ** +// +// 66: P* +// 67: ** 743 767 +// 68: ** +// +// 69: T* +// 70: ** 231 255 +// 71: ** +// +// The SampledPhonemesTable[] holds flags indicating if a phoneme is +// voiced or not. If the upper 5 bits are zero, the sample is voiced. +// +// Samples in the sampleTable are compressed, with bits being converted to +// bytes from high bit to low, as follows: +// +// unvoiced 0 bit -> X +// unvoiced 1 bit -> 5 +// +// voiced 0 bit -> 6 +// voiced 1 bit -> 24 +// +// Where X is a value from the table: +// +// { 0x18, 0x1A, 0x17, 0x17, 0x17 }; +// +// The index into this table is determined by masking off the lower +// 3 bits from the SampledPhonemesTable: +// +// index = (SampledPhonemesTable[i] & 7) - 1; +// +// For voices samples, samples are interleaved between voiced output. + + +// Code48227() +void CPU(RenderSample)(unsigned char *mem66) // 68000 or 68020 Version of this function +{ + { + static int Firsttime=1; + if(Firsttime) {Firsttime=0; printf("%s()\n",__FUNCTION__); } + } + + int tempA; + // current phoneme's index + mem49 = Y; + + // mask low three bits and subtract 1 get value to + // convert 0 bits on unvoiced samples. + A = mem39&7; + X = A-1; + + // store the result + mem56 = X; + + // determine which offset to use from table { 0x18, 0x1A, 0x17, 0x17, 0x17 } + // T, S, Z 0 0x18 + // CH, J, SH, ZH 1 0x1A + // P, F*, V, TH, DH 2 0x17 + // /H 3 0x17 + // /X 4 0x17 + + // get value from the table + mem53 = tab48426[X]; + mem47 = X; //46016+mem[56]*256 + + // voiced sample? + A = mem39 & 248; + if(A == 0) + { + // voiced phoneme: Z*, ZH, V*, DH + Y = mem49; + A = pitches[mem49] >> 4; + + // jump to voiced portion + goto pos48315; + } + + Y = A ^ 255; +pos48274: + + // step through the 8 bits in the sample + mem56 = 8; + + // get the next sample from the table + // mem47*256 = offset to start of samples + A = sampleTable[mem47*256+Y]; +pos48280: + + // left shift to get the high bit + tempA = A; + A = A << 1; + //48281: BCC 48290 + + // bit not set? + if ((tempA & 128) == 0) + { + // convert the bit to value from table + X = mem53; + //mem[54296] = X; + // output the byte + Output(1, X); + // if X != 0, exit loop + if(X != 0) goto pos48296; + } + + // output a 5 for the on bit + Output(2, 5); + + //48295: NOP +pos48296: + + X = 0; + + // decrement counter + mem56--; + + // if not done, jump to top of loop + if (mem56 != 0) goto pos48280; + + // increment position + Y++; + if (Y != 0) goto pos48274; + + // restore values and return + mem44 = 1; + Y = mem49; + return; + + + unsigned char phase1; + +pos48315: +// handle voiced samples here + + // number of samples? + phase1 = A ^ 255; + + Y = *mem66; + do + { + //pos48321: + + // shift through all 8 bits + mem56 = 8; + //A = Read(mem47, Y); + + // fetch value from table + A = sampleTable[mem47*256+Y]; + + // loop 8 times + //pos48327: + do + { + //48327: ASL A + //48328: BCC 48337 + + // left shift and check high bit + tempA = A; + A = A << 1; + if ((tempA & 128) != 0) + { + // if bit set, output 26 + X = 26; + Output(3, X); + } else + { + //timetable 4 + // bit is not set, output a 6 + X=6; + Output(4, X); + } + + mem56--; + } while(mem56 != 0); + + // move ahead in the table + Y++; + + // continue until counter done + phase1++; + + } while (phase1 != 0); + // if (phase1 != 0) goto pos48321; + + // restore values and return + A = 1; + mem44 = 1; + *mem66 = Y; + Y = mem49; + return; +} + +// RENDER THE PHONEMES IN THE LIST +// +// The phoneme list is converted into sound through the steps: +// +// 1. Copy each phoneme number of times into the frames list, +// where each frame represents 10 milliseconds of sound. +// +// 2. Determine the transitions lengths between phonemes, and linearly +// interpolate the values across the frames. +// +// 3. Offset the pitches by the fundamental frequency. +// +// 4. Render the each frame. + + + +//void Code47574() +void CPU(Render)(void) // 68000 or 68020 Version of this function +{ + { + static int Firsttime=1; + if(Firsttime) {Firsttime=0; printf("%s()\n",__FUNCTION__); } + } + + unsigned char phase1 = 0; //mem43 + unsigned char phase2; + unsigned char phase3; + unsigned char mem66; + unsigned char mem38; + unsigned char mem40; + unsigned char speedcounter; //mem45 + unsigned char mem48; + int i; + int carry; + if (phonemeIndexOutput[0] == 255) return; //exit if no data + + A = 0; + X = 0; + mem44 = 0; + + +// CREATE FRAMES +// +// The length parameter in the list corresponds to the number of frames +// to expand the phoneme to. Each frame represents 10 milliseconds of time. +// So a phoneme with a length of 7 = 7 frames = 70 milliseconds duration. +// +// The parameters are copied from the phoneme to the frame verbatim. + + +// pos47587: +do +{ + // get the index + Y = mem44; + // get the phoneme at the index + A = phonemeIndexOutput[mem44]; + mem56 = A; + + // if terminal phoneme, exit the loop + if (A == 255) break; + + // period phoneme *. + if (A == 1) + { + // add rising inflection + A = 1; + mem48 = 1; + //goto pos48376; + AddInflection(mem48, phase1); + } + /* + if (A == 2) goto pos48372; + */ + + // question mark phoneme? + if (A == 2) + { + // create falling inflection + mem48 = 255; + AddInflection(mem48, phase1); + } + // pos47615: + + // get the stress amount (more stress = higher pitch) + phase1 = tab47492[stressOutput[Y] + 1]; + + // get number of frames to write + phase2 = phonemeLengthOutput[Y]; + Y = mem56; + + // copy from the source to the frames list + do + { + frequency1[X] = freq1data[Y]; // F1 frequency + frequency2[X] = freq2data[Y]; // F2 frequency + frequency3[X] = freq3data[Y]; // F3 frequency + amplitude1[X] = ampl1data[Y]; // F1 amplitude + amplitude2[X] = ampl2data[Y]; // F2 amplitude + amplitude3[X] = ampl3data[Y]; // F3 amplitude + sampledConsonantFlag[X] = sampledConsonantFlags[Y]; // phoneme data for sampled consonants + pitches[X] = pitch + phase1; // pitch + X++; + phase2--; + } while(phase2 != 0); + mem44++; +} while(mem44 != 0); +// ------------------- +//pos47694: + +// CREATE TRANSITIONS +// +// Linear transitions are now created to smoothly connect the +// end of one sustained portion of a phoneme to the following +// phoneme. +// +// To do this, three tables are used: +// +// Table Purpose +// ========= ================================================== +// blendRank Determines which phoneme's blend values are used. +// +// blendOut The number of frames at the end of the phoneme that +// will be used to transition to the following phoneme. +// +// blendIn The number of frames of the following phoneme that +// will be used to transition into that phoneme. +// +// In creating a transition between two phonemes, the phoneme +// with the HIGHEST rank is used. Phonemes are ranked on how much +// their identity is based on their transitions. For example, +// vowels are and diphthongs are identified by their sustained portion, +// rather than the transitions, so they are given low values. In contrast, +// stop consonants (P, B, T, K) and glides (Y, L) are almost entirely +// defined by their transitions, and are given high rank values. +// +// Here are the rankings used by SAM: +// +// Rank Type Phonemes +// 2 All vowels IY, IH, etc. +// 5 Diphthong endings YX, WX, ER +// 8 Terminal liquid consonants LX, WX, YX, N, NX +// 9 Liquid consonants L, RX, W +// 10 Glide R, OH +// 11 Glide WH +// 18 Voiceless fricatives S, SH, F, TH +// 20 Voiced fricatives Z, ZH, V, DH +// 23 Plosives, stop consonants P, T, K, KX, DX, CH +// 26 Stop consonants J, GX, B, D, G +// 27-29 Stop consonants (internal) ** +// 30 Unvoiced consonants /H, /X and Q* +// 160 Nasal M +// +// To determine how many frames to use, the two phonemes are +// compared using the blendRank[] table. The phoneme with the +// higher rank is selected. In case of a tie, a blend of each is used: +// +// if blendRank[phoneme1] == blendRank[phomneme2] +// // use lengths from each phoneme +// outBlendFrames = outBlend[phoneme1] +// inBlendFrames = outBlend[phoneme2] +// else if blendRank[phoneme1] > blendRank[phoneme2] +// // use lengths from first phoneme +// outBlendFrames = outBlendLength[phoneme1] +// inBlendFrames = inBlendLength[phoneme1] +// else +// // use lengths from the second phoneme +// // note that in and out are SWAPPED! +// outBlendFrames = inBlendLength[phoneme2] +// inBlendFrames = outBlendLength[phoneme2] +// +// Blend lengths can't be less than zero. +// +// Transitions are assumed to be symetrical, so if the transition +// values for the second phoneme are used, the inBlendLength and +// outBlendLength values are SWAPPED. +// +// For most of the parameters, SAM interpolates over the range of the last +// outBlendFrames-1 and the first inBlendFrames. +// +// The exception to this is the Pitch[] parameter, which is interpolates the +// pitch from the CENTER of the current phoneme to the CENTER of the next +// phoneme. +// +// Here are two examples. First, For example, consider the word "SUN" (S AH N) +// +// Phoneme Duration BlendWeight OutBlendFrames InBlendFrames +// S 2 18 1 3 +// AH 8 2 4 4 +// N 7 8 1 2 +// +// The formant transitions for the output frames are calculated as follows: +// +// flags ampl1 freq1 ampl2 freq2 ampl3 freq3 pitch +// ------------------------------------------------ +// S +// 241 0 6 0 73 0 99 61 Use S (weight 18) for transition instead of AH (weight 2) +// 241 0 6 0 73 0 99 61 <-- (OutBlendFrames-1) = (1-1) = 0 frames +// AH +// 0 2 10 2 66 0 96 59 * <-- InBlendFrames = 3 frames +// 0 4 14 3 59 0 93 57 * +// 0 8 18 5 52 0 90 55 * +// 0 15 22 9 44 1 87 53 +// 0 15 22 9 44 1 87 53 +// 0 15 22 9 44 1 87 53 Use N (weight 8) for transition instead of AH (weight 2). +// 0 15 22 9 44 1 87 53 Since N is second phoneme, reverse the IN and OUT values. +// 0 11 17 8 47 1 98 56 * <-- (InBlendFrames-1) = (2-1) = 1 frames +// N +// 0 8 12 6 50 1 109 58 * <-- OutBlendFrames = 1 +// 0 5 6 5 54 0 121 61 +// 0 5 6 5 54 0 121 61 +// 0 5 6 5 54 0 121 61 +// 0 5 6 5 54 0 121 61 +// 0 5 6 5 54 0 121 61 +// 0 5 6 5 54 0 121 61 +// +// Now, consider the reverse "NUS" (N AH S): +// +// flags ampl1 freq1 ampl2 freq2 ampl3 freq3 pitch +// ------------------------------------------------ +// N +// 0 5 6 5 54 0 121 61 +// 0 5 6 5 54 0 121 61 +// 0 5 6 5 54 0 121 61 +// 0 5 6 5 54 0 121 61 +// 0 5 6 5 54 0 121 61 +// 0 5 6 5 54 0 121 61 Use N (weight 8) for transition instead of AH (weight 2) +// 0 5 6 5 54 0 121 61 <-- (OutBlendFrames-1) = (1-1) = 0 frames +// AH +// 0 8 11 6 51 0 110 59 * <-- InBlendFrames = 2 +// 0 11 16 8 48 0 99 56 * +// 0 15 22 9 44 1 87 53 Use S (weight 18) for transition instead of AH (weight 2) +// 0 15 22 9 44 1 87 53 Since S is second phoneme, reverse the IN and OUT values. +// 0 9 18 5 51 1 90 55 * <-- (InBlendFrames-1) = (3-1) = 2 +// 0 4 14 3 58 1 93 57 * +// S +// 241 2 10 2 65 1 96 59 * <-- OutBlendFrames = 1 +// 241 0 6 0 73 0 99 61 + + A = 0; + mem44 = 0; + mem49 = 0; // mem49 starts at as 0 + X = 0; + while(1) //while No. 1 + { +#ifdef __AMIGA__ + __chkabort(); /* look for CTRL-C */ +#endif + + // get the current and following phoneme + Y = phonemeIndexOutput[X]; + A = phonemeIndexOutput[X+1]; + X++; + + // exit loop at end token + if (A == 255) break;//goto pos47970; + + + // get the ranking of each phoneme + X = A; + mem56 = blendRank[A]; + A = blendRank[Y]; + + // compare the rank - lower rank value is stronger + if (A == mem56) + { + // same rank, so use out blend lengths from each phoneme + phase1 = outBlendLength[Y]; + phase2 = outBlendLength[X]; + } else + if (A < mem56) + { + // first phoneme is stronger, so us it's blend lengths + phase1 = inBlendLength[X]; + phase2 = outBlendLength[X]; + } else + { + // second phoneme is stronger, so use it's blend lengths + // note the out/in are swapped + phase1 = outBlendLength[Y]; + phase2 = inBlendLength[Y]; + } + + Y = mem44; + A = mem49 + phonemeLengthOutput[mem44]; // A is mem49 + length + mem49 = A; // mem49 now holds length + position + A = A + phase2; //Maybe Problem because of carry flag + + //47776: ADC 42 + speedcounter = A; + mem47 = 168; + phase3 = mem49 - phase1; // what is mem49 + A = phase1 + phase2; // total transition? + mem38 = A; + + X = A; + X -= 2; + if ((X & 128) == 0) + do //while No. 2 + { +#ifdef __AMIGA__ + __chkabort(); /* look for CTRL-C */ +#endif + + //pos47810: + + // mem47 is used to index the tables: + // 168 pitches[] + // 169 frequency1 + // 170 frequency2 + // 171 frequency3 + // 172 amplitude1 + // 173 amplitude2 + // 174 amplitude3 + + mem40 = mem38; + + if (mem47 == 168) // pitch + { + + // unlike the other values, the pitches[] interpolates from + // the middle of the current phoneme to the middle of the + // next phoneme + + unsigned char mem36, mem37; + // half the width of the current phoneme + mem36 = phonemeLengthOutput[mem44] >> 1; + // half the width of the next phoneme + mem37 = phonemeLengthOutput[mem44+1] >> 1; + // sum the values + mem40 = mem36 + mem37; // length of both halves + mem37 += mem49; // center of next phoneme + mem36 = mem49 - mem36; // center index of current phoneme + A = Read(mem47, mem37); // value at center of next phoneme - end interpolation value + //A = mem[address]; + + Y = mem36; // start index of interpolation + mem53 = A - Read(mem47, mem36); // value to center of current phoneme + } else + { + // value to interpolate to + A = Read(mem47, speedcounter); + // position to start interpolation from + Y = phase3; + // value to interpolate from + mem53 = A - Read(mem47, phase3); + } + + //Code47503(mem40); + // ML : Code47503 is division with remainder, and mem50 gets the sign + + // calculate change per frame + mem50 = (((char)(mem53) < 0) ? 128 : 0); + mem51 = abs((char)mem53) % mem40; + mem53 = (unsigned char)((char)(mem53) / mem40); + + // interpolation range + X = mem40; // number of frames to interpolate over + Y = phase3; // starting frame + + + // linearly interpolate values + + mem56 = 0; + //47907: CLC + //pos47908: + while(1) //while No. 3 + { +#ifdef __AMIGA__ + __chkabort(); /* look for CTRL-C */ +#endif + + A = Read(mem47, Y) + mem53; //carry alway cleared + + mem48 = A; + Y++; + X--; + if(X == 0) break; + + mem56 += mem51; + if (mem56 >= mem40) //??? + { + mem56 -= mem40; //carry? is set + //if ((mem56 & 128)==0) + if ((mem50 & 128)==0) + { + //47935: BIT 50 + //47937: BMI 47943 + if(mem48 != 0) mem48++; + } else mem48--; + } + //pos47945: + Write(mem47, Y, mem48); + } //while No. 3 + + //pos47952: + mem47++; + //if (mem47 != 175) goto pos47810; + } while (mem47 != 175); //while No. 2 + //pos47963: + mem44++; + X = mem44; + } //while No. 1 + + //goto pos47701; + //pos47970: + + // add the length of this phoneme + mem48 = mem49 + phonemeLengthOutput[mem44]; + + +// ASSIGN PITCH CONTOUR +// +// This subtracts the F1 frequency from the pitch to create a +// pitch contour. Without this, the output would be at a single +// pitch level (monotone). + + + // don't adjust pitch if in sing mode + if (!singmode) + { + // iterate through the buffer + for(i=0; i<256; i++) { + // subtract half the frequency of the formant 1. + // this adds variety to the voice + pitches[i] -= (frequency1[i] >> 1); + } + } + + phase1 = 0; + phase2 = 0; + phase3 = 0; + mem49 = 0; + speedcounter = 72; //sam standard speed + +// RESCALE AMPLITUDE +// +// Rescale volume from a linear scale to decibels. +// + + //amplitude rescaling + for(i=255; i>=0; i--) + { + amplitude1[i] = amplitudeRescale[amplitude1[i]]; + amplitude2[i] = amplitudeRescale[amplitude2[i]]; + amplitude3[i] = amplitudeRescale[amplitude3[i]]; + } + + Y = 0; + A = pitches[0]; + mem44 = A; + X = A; + mem38 = A - (A>>2); // 3/4*A ??? + +if (debug) +{ + PrintOutput(sampledConsonantFlag, frequency1, frequency2, frequency3, amplitude1, amplitude2, amplitude3, pitches); +} + +// PROCESS THE FRAMES +// +// In traditional vocal synthesis, the glottal pulse drives filters, which +// are attenuated to the frequencies of the formants. +// +// SAM generates these formants directly with sin and rectangular waves. +// To simulate them being driven by the glottal pulse, the waveforms are +// reset at the beginning of each glottal pulse. + + //finally the loop for sound output + //pos48078: + while(1) + { + unsigned char *local_multtable=multtable; + // get the sampled information on the phoneme + A = sampledConsonantFlag[Y]; + mem39 = A; + + // unvoiced sampled phoneme? + A = A & 248; + if(A != 0) + { + // render the sample for the phoneme + CPU(RenderSample)(&mem66); // call 68000 or 68020 Version of this function + + // skip ahead two in the phoneme buffer + Y += 2; + mem48 -= 2; + } else + { + // simulate the glottal pulse and formants + mem56 = multtable[sinus[phase1] | amplitude1[Y]]; + + carry = 0; + if ((mem56+local_multtable[sinus[phase2] | amplitude2[Y]] ) > 255) carry = 1; + mem56 += local_multtable[sinus[phase2] | amplitude2[Y]]; + A = mem56 + local_multtable[rectangle[phase3] | amplitude3[Y]] + (carry?1:0); + A = ((A + 136) & 255) >> 4; //there must be also a carry + //mem[54296] = A; + + // output the accumulated value + Output(0, A); + speedcounter--; + if (speedcounter != 0) goto pos48155; + Y++; //go to next amplitude + + // decrement the frame count + mem48--; + } + + // if the frame count is zero, exit the loop + if(mem48 == 0) return; + speedcounter = speed; +pos48155: + + // decrement the remaining length of the glottal pulse + mem44--; + + // finished with a glottal pulse? + if(mem44 == 0) + { +pos48159: + // fetch the next glottal pulse length + A = pitches[Y]; + mem44 = A; + A = A - (A>>2); + mem38 = A; + + // reset the formant wave generators to keep them in + // sync with the glottal pulse + phase1 = 0; + phase2 = 0; + phase3 = 0; + continue; + } + + // decrement the count + mem38--; + + // is the count non-zero and the sampled flag is zero? + if((mem38 != 0) || (mem39 == 0)) + { + // reset the phase of the formants to match the pulse + phase1 += frequency1[Y]; + phase2 += frequency2[Y]; + phase3 += frequency3[Y]; + continue; + } + + // voiced sampled phonemes interleave the sample with the + // glottal pulse. The sample flag is non-zero, so render + // the sample for the phoneme. + CPU(RenderSample)(&mem66); // call 68000 or 68020 Version of this function + goto pos48159; + } //while + + + // The following code is never reached. It's left over from when + // the voiced sample code was part of this loop, instead of part + // of RenderSample(); + + //pos48315: + int tempA; + phase1 = A ^ 255; + Y = mem66; + do + { + //pos48321: + + mem56 = 8; + A = Read(mem47, Y); + + //pos48327: + do + { + //48327: ASL A + //48328: BCC 48337 + tempA = A; + A = A << 1; + if ((tempA & 128) != 0) + { + X = 26; + // mem[54296] = X; + bufferpos += 150; + buffer[bufferpos/50] = (X & 15)*16; + } else + { + //mem[54296] = 6; + X=6; + bufferpos += 150; + buffer[bufferpos/50] = (X & 15)*16; + } + + for(X = wait2; X>0; X--); //wait + mem56--; + } while(mem56 != 0); + + Y++; + phase1++; + + } while (phase1 != 0); + // if (phase1 != 0) goto pos48321; + A = 1; + mem44 = 1; + mem66 = Y; + Y = mem49; + return; +} From 25a6e199a12806296702737a88f27508001ec24a Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Sun, 16 Dec 2018 22:59:01 +0100 Subject: [PATCH 29/62] program can now be made resident --- AF_readme | 4 ++++ Makefile.amiga | 6 +++--- src/amiga/portaudio/portaudio_ahidev.c | 10 ++++++++++ src/amiga/portaudio/portaudio_audev.c | 13 +++++++++++-- src/amiga/portaudio/subtask_support.c | 27 ++++++++++++++++++++++++-- src/amiga/sdlwrapper.c | 2 +- src/main.c | 1 + 7 files changed, 55 insertions(+), 8 deletions(-) diff --git a/AF_readme b/AF_readme index 75d9643..b9d24f3 100644 --- a/AF_readme +++ b/AF_readme @@ -128,3 +128,7 @@ SAM ist jetzt 59912 Bytes gross. 14.12.2018 ---------- Render() und RenderSample() gibt es jetzt als 68000 und 68020 Version, die automatisch ausgewaehlt werden. guess_number.rexx gemacht. Portaudio warnings behoben. + +16.12.2018 +---------- +Resident geht jetzt. Vorschlag von Bebbo zum Weitergeben von A4 ueber np_Input bzw pr_CIS gemacht diff --git a/Makefile.amiga b/Makefile.amiga index 04324eb..22bc554 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -1,7 +1,7 @@ # All the o-Files in Link-Order OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o render.o render000.o render020.o main.o portaudio_ahidev.o portaudio.o subtask_support.o amiga_version.o -COMPILER_INSTALL_DIR = /home/osboxes/opt/m68k-amigaos_06Dec18 +COMPILER_INSTALL_DIR = /home/osboxes/opt/m68k-amigaos_14Dec18 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc STRIP = $(COMPILER_DIR)/m68k-amigaos-strip @@ -18,11 +18,11 @@ CFLAGS += $(CPUFLAGS) CFLAGS += -Os # all but render.c arecompiled for size. Only render.c will be compiled for speed CFLAGS += -Wall -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` -#CFLAGS += -fbaserel +CFLAGS += -resident CFLAGS += -msmall-code LFLAGS = -g -noixemul $(CPUFLAGS) -Wl,-Map=sam.map,--trace -ldebug #-lSDL #`sdl-config --libs` -#LFLAGS += -fbaserel +LFLAGS += -resident #coverage diff --git a/src/amiga/portaudio/portaudio_ahidev.c b/src/amiga/portaudio/portaudio_ahidev.c index 8be173f..2c8200f 100644 --- a/src/amiga/portaudio/portaudio_ahidev.c +++ b/src/amiga/portaudio/portaudio_ahidev.c @@ -122,6 +122,16 @@ VOID /*__asm */__saveds SamAudioTask_AHI(VOID) { // KPrintF("%s() called\n",__FUNCTION__); + { + // do not use ExecBase via a4 yet + struct Library * SysBase = *(struct Library **)4; + struct Task * task = FindTask(0); + task->tc_UserData = (APTR)((struct Process *)task)->pr_CIS; // the main task put a4 via NP_Input into pr_CIS + __restore_a4(); // get A4 from there. Now we can access static and global data via A4 ! + + // now fix CIN to zero or allocate something or ... + ((struct Process *)task)->pr_CIS = 0; + } struct Task *me = FindTask(NULL); diff --git a/src/amiga/portaudio/portaudio_audev.c b/src/amiga/portaudio/portaudio_audev.c index 74dbf4c..fee8023 100644 --- a/src/amiga/portaudio/portaudio_audev.c +++ b/src/amiga/portaudio/portaudio_audev.c @@ -141,12 +141,21 @@ STATIC_FUNC UWORD Convert8USamples(UBYTE *Source8U, BYTE *Dest8S, ULONG SampleCo -VOID /*__asm*/ __saveds SamAudioTask(VOID) +VOID /*__asm*/ /*__saveds*/ SamAudioTask(VOID) { // KPrintF("%s() called\n",__FUNCTION__); - + { + // do not use ExecBase via a4 yet + struct Library * SysBase = *(struct Library **)4; + struct Task * task = FindTask(0); + task->tc_UserData = (APTR)((struct Process *)task)->pr_CIS; // the main task put a4 via NP_Input into pr_CIS + __restore_a4(); // get A4 from there. Now we can access static and global data via A4 ! + + // now fix CIS to zero or allocate something or ... + ((struct Process *)task)->pr_CIS = 0; + } struct Task *me = FindTask(NULL); struct SubTask *st; diff --git a/src/amiga/portaudio/subtask_support.c b/src/amiga/portaudio/subtask_support.c index 7bd1ac8..d60188c 100644 --- a/src/amiga/portaudio/subtask_support.c +++ b/src/amiga/portaudio/subtask_support.c @@ -11,7 +11,26 @@ #include #include +/* BEGIN -resident support for new task, suggested by bebbo 16.Dec1028 */ +// put the a4 reg into my task +// get a4 helper +ULONG __get_a4() { + asm("move.l a4,d0"); +} + +// load a4 from my task +void __restore_a4() { + // do not use ExecBase via a4 yet + struct Library * SysBase = *(struct Library **)4; + struct Task * task = FindTask(0); + asm("\tmove.l %0,a4 ;\n" + : /* output */ + : "r" (task->tc_UserData) /* input */ + ); +} + +/* END -resident support for new task, suggested by bebbo 16.Dec1028 */ LONG SendSubTaskMsg(struct SubTask *st,WORD command,APTR params) @@ -29,6 +48,7 @@ LONG SendSubTaskMsg(struct SubTask *st,WORD command,APTR params) return(st->st_Message.stm_Result); } + struct SubTask *SpawnSubTask(char *name,VOID (*func)(VOID),APTR data) { struct SubTask *st; @@ -40,10 +60,12 @@ struct SubTask *SpawnSubTask(char *name,VOID (*func)(VOID),APTR data) if (st->st_Reply) { st->st_Data = data; - - st->st_Task = (struct Task *)CreateNewProcTags(NP_Entry,(unsigned long)func,NP_Name,(unsigned long)name,TAG_DONE); + st->st_Task = (struct Task *)CreateNewProcTags(NP_Entry,(unsigned long)func,NP_Name,(unsigned long)name, + NP_Input, __get_a4(), // abuse NP_Input to pass a4 -> will be put into pr_CIS + TAG_DONE); if (st->st_Task) { + if (SendSubTaskMsg(st,STC_STARTUP,st)) { return(st); @@ -56,6 +78,7 @@ struct SubTask *SpawnSubTask(char *name,VOID (*func)(VOID),APTR data) return(NULL); } + VOID KillSubTask(struct SubTask *st) { SendSubTaskMsg(st,STC_SHUTDOWN,st); diff --git a/src/amiga/sdlwrapper.c b/src/amiga/sdlwrapper.c index e4fceea..678f009 100644 --- a/src/amiga/sdlwrapper.c +++ b/src/amiga/sdlwrapper.c @@ -139,6 +139,6 @@ void SDL_PauseAudio(int pause_on) void SDL_Quit(void) // useful with atexit() { - KPrintF("%s()\n",__FUNCTION__); +// KPrintF("%s()\n",__FUNCTION__); Abort_Pa_CloseStream(); } diff --git a/src/main.c b/src/main.c index cca1bd8..8031d87 100644 --- a/src/main.c +++ b/src/main.c @@ -163,6 +163,7 @@ void OutputSound() {} int debug = 0; + int main(int argc, char **argv) { int i; From 9eabca987112a84f3e33252c7d9f8190ed04784a Mon Sep 17 00:00:00 2001 From: githubaf Date: Mon, 17 Dec 2018 13:07:57 +0100 Subject: [PATCH 30/62] guess_number speaks full numbers now (68 instead of 6 8). freopen() removed for linux from main.c --- demos_amiga/guess_number.rexx | 46 ++++++++++++++++++++++++++++++++++- src/main.c | 4 +-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/demos_amiga/guess_number.rexx b/demos_amiga/guess_number.rexx index 67804d9..621d06e 100755 --- a/demos_amiga/guess_number.rexx +++ b/demos_amiga/guess_number.rexx @@ -79,7 +79,7 @@ ADDRESS COMMAND; "/SAM" "You guessed the number correctly!"; ADDRESS REXX ECHO ECHO ECHO "The number was" number -ADDRESS COMMAND; "/SAM" "The number was" Number; ADDRESS REXX +ADDRESS COMMAND; "/SAM" "The number was" getNumberString(Number); ADDRESS REXX ECHO "Thanks for playing " Name ",thanks for playing!" ADDRESS COMMAND; "/SAM" "Thanks for playing?" Name "Thanks for playing."; ADDRESS REXX DELAY(100) @@ -90,3 +90,47 @@ cls: PROCEDURE ECHO "1B"x"[0;0H" "1B"x"[J" RETURN 0 + +getNumberString: PROCEDURE + ARG number + + SELECT + WHEN number < 10 THEN return number + + WHEN number = 10 THEN return "ten" + WHEN number = 11 THEN return "eleven" + WHEN number = 12 THEN return "twelve" + WHEN number = 13 THEN return "thirteen" + WHEN number = 14 THEN return "fourteen" + WHEN number = 15 THEN return "fifteen" + WHEN number = 16 THEN return "sixteen" + WHEN number = 17 THEN return "seventeen" + WHEN number = 18 THEN return "eighteen" + WHEN number = 19 THEN return "9teen" + + WHEN number = 20 THEN return "twenty" + WHEN number < 30 THEN return "twenty" || number//20 + + WHEN number = 30 THEN return "thirty" + WHEN number < 40 THEN return "thirty" || number//30 + + WHEN number = 40 THEN return "fourty" + WHEN number < 50 THEN return "fourty" || number//40 + + WHEN number = 50 THEN return "fifty" + WHEN number < 60 THEN return "fifty" || number//50 + + WHEN number = 60 THEN return "sixty" + WHEN number < 70 THEN return "sixty" || number//60 + + WHEN number = 70 THEN return "seventy" + WHEN number < 80 THEN return "seventy" || number//70 + + WHEN number = 80 THEN return "eighty" + WHEN number < 90 THEN return "eighty" || number//80 + + WHEN number = 90 THEN return "9tee" + WHEN number <100 THEN return "9tee" || number//90 + END + + diff --git a/src/main.c b/src/main.c index 8031d87..2a35213 100644 --- a/src/main.c +++ b/src/main.c @@ -177,8 +177,8 @@ int main(int argc, char **argv) #ifdef USESDL #ifndef __AMIGA__ - freopen("CON", "w", stdout); - freopen("CON", "w", stderr); +// freopen("CON", "w", stdout); +// freopen("CON", "w", stderr); #endif #endif From b1c8591be719970df281017f1cdf36071e956ecf Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Mon, 17 Dec 2018 23:18:35 +0100 Subject: [PATCH 31/62] removed timimg-prints via define, mentioned resident in readme --- Makefile.amiga | 1 + sam.readme | 21 +++++++++++++-------- src/main.c | 15 +++++++++++---- src/render2.c | 16 ++++++++++++---- 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index 22bc554..9203f40 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -13,6 +13,7 @@ CPUFLAGS=-m68000 CFLAGS = -DDATE="\"$(shell /bin/date +'%d.%m.%Y')\"" CFLAGS += -DPLATFORM_IS_BIG_ENDIAN -DSTATIC_FUNC= -DUSESDL CFLAGS += -DTOOLCHAIN_VER="\"$(TOOLCHAIN_VER)\"" +#CFLAGS += -DDEBUG CFLAGS += -Iamiga/ -Iamiga/portaudio/ -I. -I$(COMPILER_INSTALL_DIR)/include/SDL CFLAGS += $(CPUFLAGS) CFLAGS += -Os # all but render.c arecompiled for size. Only render.c will be compiled for speed diff --git a/sam.readme b/sam.readme index 47c439e..86a3e91 100644 --- a/sam.readme +++ b/sam.readme @@ -7,30 +7,35 @@ Architecture: m68k-amigaos Distribution: Aminet -This is the Amiga port of Sebastian Macke's C-adaption of the speech software -SAM (Software Automatic Mouth) for the Commodore C64. -It creates a nice sounding voice direct from text. That sound can be played -via audio.device (default) or via ahi.device (-ahi unit). The sound can -also be saved to a wave-file. Input is possible in either English text mode -for automatic translation or in phoneme mode (-phonetic) +This is the Amiga port of Sebastian Macke's great C-adaption of the +speech software SAM (Software Automatic Mouth) for the Commodore C64. +It creates a nice sounding voice directly from text. That sound can be +played via audio.device (default) or via ahi.device (-ahi unit). +The sound can also be saved to a wave-file. Input is possible in either +English text mode for automatic translation or in phoneme mode (-phonetic) Just enter sam to get a list of options. sam Hello, my name is sam. +The program can be loaded resident to skip load times on further invocations. + +Resident sam PURE + For a few more examples cd into demos_amiga drawer and enjoy the show. +Resident sam PURE ; load sam only once cd demos_amiga execute demo1 execute demo2 ; and so on... ; also try the tiny game rx guess_number.rexx - +Resident sam Remove Requirements: Any Amiga will do. An 68000 is sufficient but an 68020 or better is utilized if present. On a plain 7MHz 68000 it takes a few seconds to calculate until sound occurs. Standard Amiga stack (4096) is sufficient. -Either audio.device or ahi.device are used for playback. +Either audio.device or ahi.device is used for playback. diff --git a/src/main.c b/src/main.c index 2a35213..ab84e98 100644 --- a/src/main.c +++ b/src/main.c @@ -18,6 +18,13 @@ #ifdef __AMIGA__ // AF, use ahi.device instead of audio.device void set_ahi_devide(unsigned int unit); void SetCpuSpecificFunctions(void); // AF, we compile some functions for 68000 and for 68020 + #endif + +#ifdef DEBUG + #define D(x) x +#else + // for debug-prints. Can be activated with -DDEBUG in Makefile + #define D(x) #endif @@ -172,7 +179,7 @@ int main(int argc, char **argv) char* wavfilename = NULL; static char input[256]; // AF, save some stack - printf("Los...\n"); + D(printf("Los...\n")); time_t StartZeit=time(NULL); #ifdef USESDL @@ -316,10 +323,10 @@ int main(int argc, char **argv) return 1; } { -printf("Sound berechnung nach %lld Sekunden\n",time(NULL)-StartZeit); +D(printf("Sound berechnung nach %lld Sekunden\n",time(NULL)-StartZeit)); extern int bufferpos; -printf("%s(): BufferPos=%d\n",__FUNCTION__,bufferpos); -printf("%s(): GetBufferLength=%d\n",__FUNCTION__,GetBufferLength()); +D(printf("%s(): BufferPos=%d\n",__FUNCTION__,bufferpos)); +D(printf("%s(): GetBufferLength=%d\n",__FUNCTION__,GetBufferLength())); } if (wavfilename != NULL) WriteWav(wavfilename, GetBuffer(), GetBufferLength()/50); diff --git a/src/render2.c b/src/render2.c index 5d92f05..44de7ff 100644 --- a/src/render2.c +++ b/src/render2.c @@ -13,6 +13,14 @@ #define CPU(x) CPU_TYPE(x) #endif +#ifdef DEBUG + #define D(x) x +#else + // for debug-prints. Can be activated with -DDEBUG in Makefile + #define D(x) +#endif + + #include #include #include "debug.h" @@ -144,10 +152,10 @@ void Output(int index, unsigned char A); // Code48227() void CPU(RenderSample)(unsigned char *mem66) // 68000 or 68020 Version of this function { - { + D({ static int Firsttime=1; if(Firsttime) {Firsttime=0; printf("%s()\n",__FUNCTION__); } - } + }) int tempA; // current phoneme's index @@ -318,10 +326,10 @@ void CPU(RenderSample)(unsigned char *mem66) // 68000 or 68020 Version of this //void Code47574() void CPU(Render)(void) // 68000 or 68020 Version of this function { - { + D({ static int Firsttime=1; if(Firsttime) {Firsttime=0; printf("%s()\n",__FUNCTION__); } - } + }) unsigned char phase1 = 0; //mem43 unsigned char phase2; From 8467db880ebd4a09bed6138c4c5903cfb394f1dd Mon Sep 17 00:00:00 2001 From: githubaf Date: Wed, 19 Dec 2018 09:52:25 +0100 Subject: [PATCH 32/62] removed last attribut no_instrument statements, new compiler --- Makefile.amiga | 7 +++++-- src/amiga/portaudio/portaudio.c | 2 +- src/amiga/portaudio/portaudio_ahidev.c | 4 ++-- src/amiga/portaudio/portaudio_audev.c | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index 9203f40..d2151a3 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -1,7 +1,7 @@ # All the o-Files in Link-Order OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o render.o render000.o render020.o main.o portaudio_ahidev.o portaudio.o subtask_support.o amiga_version.o -COMPILER_INSTALL_DIR = /home/osboxes/opt/m68k-amigaos_14Dec18 +COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_18Dec18 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc STRIP = $(COMPILER_DIR)/m68k-amigaos-strip @@ -46,16 +46,19 @@ vpath amiga_version.c src/amiga/version/ sam: $(OBJS_ORDERED) $(CC) -o sam $(OBJS_ORDERED) $(LFLAGS) + ls -la sam sync strip: sam $(STRIP) $< + ls -la sam + sync render000.o: src/render2.c $(CC) $(CFLAGS) -Os -c $< -o render000.o # this one is compiled with -O2 as it is the time critical part render020.o: src/render2.c - $(CC) $(CFLAGS) -m68020 -Os -c $< -o render020.o # this one is compiled with -O2 as it is the time critical part + $(CC) $(CFLAGS) -m68020 -O2 -c $< -o render020.o # this one is compiled with -O2 as it is the time critical part %.o: src/%.c $(CC) $(CFLAGS) -c $< diff --git a/src/amiga/portaudio/portaudio.c b/src/amiga/portaudio/portaudio.c index 91d5ee4..6bfe785 100644 --- a/src/amiga/portaudio/portaudio.c +++ b/src/amiga/portaudio/portaudio.c @@ -127,7 +127,7 @@ PaError Pa_GetSampleSize( PaSampleFormat format ) return (*Pa_GetSampleSize_FctPtr)( format ); } -void __attribute__((no_instrument_function)) Abort_Pa_CloseStream (void) +void Abort_Pa_CloseStream (void) { (*Abort_Pa_CloseStream_FctPtr)(); } diff --git a/src/amiga/portaudio/portaudio_ahidev.c b/src/amiga/portaudio/portaudio_ahidev.c index 2c8200f..cdf2cb7 100644 --- a/src/amiga/portaudio/portaudio_ahidev.c +++ b/src/amiga/portaudio/portaudio_ahidev.c @@ -697,7 +697,7 @@ PaError Pa_OpenDefaultStream_ahidev( PortAudioStream** stream, Pa_CloseStream() closes an audio stream, flushing any pending buffers. */ -PaError __attribute__((no_instrument_function)) Pa_CloseStream_ahidev( PortAudioStream *stream ) +PaError Pa_CloseStream_ahidev( PortAudioStream *stream ) { //KPrintF("%s() called\n",__FUNCTION__); //KPrintF("Zeile %ld\n",__LINE__); @@ -888,7 +888,7 @@ STATIC_FUNC ULONG getAHISampleType(PaSampleFormat format ) /* used for atexit(). Therefore void parameter -> global Pointer needed */ -void __attribute__((no_instrument_function)) Abort_Pa_CloseStream_ahidev (void) +void Abort_Pa_CloseStream_ahidev (void) { //KPrintF("Zeile %ld\n",__LINE__); if(GlobalPaStreamPtr_ahi) diff --git a/src/amiga/portaudio/portaudio_audev.c b/src/amiga/portaudio/portaudio_audev.c index fee8023..331785d 100644 --- a/src/amiga/portaudio/portaudio_audev.c +++ b/src/amiga/portaudio/portaudio_audev.c @@ -911,7 +911,7 @@ PaError Pa_OpenDefaultStream_audev( PortAudioStream** stream, Pa_CloseStream() closes an audio stream, flushing any pending buffers. */ -PaError __attribute__((no_instrument_function)) Pa_CloseStream_audev( PortAudioStream *stream ) +PaError Pa_CloseStream_audev( PortAudioStream *stream ) { //KPrintF("%s() called\n",__FUNCTION__); From 43b4456f865a3af43f7950644d6dcd3157120892 Mon Sep 17 00:00:00 2001 From: githubaf Date: Fri, 21 Dec 2018 08:58:19 +0100 Subject: [PATCH 33/62] added stopwatch --- AF_readme | 4 + Makefile.amiga | 9 +- src/amiga/stopwatch/stopwatch.c | 161 +++++++++++++++++++++++++++ src/amiga/stopwatch/stopwatch.h | 43 +++++++ src/amiga/stopwatch/stopwatch_test.c | 68 +++++++++++ src/main.c | 38 +++++++ 6 files changed, 319 insertions(+), 4 deletions(-) create mode 100644 src/amiga/stopwatch/stopwatch.c create mode 100644 src/amiga/stopwatch/stopwatch.h create mode 100644 src/amiga/stopwatch/stopwatch_test.c diff --git a/AF_readme b/AF_readme index b9d24f3..eb80900 100644 --- a/AF_readme +++ b/AF_readme @@ -132,3 +132,7 @@ Render() und RenderSample() gibt es jetzt als 68000 und 68020 Version, die autom 16.12.2018 ---------- Resident geht jetzt. Vorschlag von Bebbo zum Weitergeben von A4 ueber np_Input bzw pr_CIS gemacht + +21.12.2018 +---------- +Stopwatch fuer genauere Zeitmessung diff --git a/Makefile.amiga b/Makefile.amiga index d2151a3..20237d1 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -1,5 +1,5 @@ # All the o-Files in Link-Order -OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o render.o render000.o render020.o main.o portaudio_ahidev.o portaudio.o subtask_support.o amiga_version.o +OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o render.o render000.o render020.o main.o portaudio_ahidev.o portaudio.o subtask_support.o amiga_version.o stopwatch.o COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_18Dec18 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin @@ -13,7 +13,7 @@ CPUFLAGS=-m68000 CFLAGS = -DDATE="\"$(shell /bin/date +'%d.%m.%Y')\"" CFLAGS += -DPLATFORM_IS_BIG_ENDIAN -DSTATIC_FUNC= -DUSESDL CFLAGS += -DTOOLCHAIN_VER="\"$(TOOLCHAIN_VER)\"" -#CFLAGS += -DDEBUG +CFLAGS += -DDEBUG CFLAGS += -Iamiga/ -Iamiga/portaudio/ -I. -I$(COMPILER_INSTALL_DIR)/include/SDL CFLAGS += $(CPUFLAGS) CFLAGS += -Os # all but render.c arecompiled for size. Only render.c will be compiled for speed @@ -42,6 +42,7 @@ vpath portaudio_audev.c src/amiga/portaudio/ vpath portaudio.c src/amiga/portaudio/ vpath subtask_support.c src/amiga/portaudio/ vpath amiga_version.c src/amiga/version/ +vpath stopwatch.c src/amiga/stopwatch/ sam: $(OBJS_ORDERED) @@ -55,10 +56,10 @@ strip: sam sync render000.o: src/render2.c - $(CC) $(CFLAGS) -Os -c $< -o render000.o # this one is compiled with -O2 as it is the time critical part + $(CC) $(CFLAGS) -O3 -c $< -o render000.o # this one is compiled with -O2 as it is the time critical part render020.o: src/render2.c - $(CC) $(CFLAGS) -m68020 -O2 -c $< -o render020.o # this one is compiled with -O2 as it is the time critical part + $(CC) $(CFLAGS) -m68020 -O3 -c $< -o render020.o # this one is compiled with -O2 as it is the time critical part %.o: src/%.c $(CC) $(CFLAGS) -c $< diff --git a/src/amiga/stopwatch/stopwatch.c b/src/amiga/stopwatch/stopwatch.c new file mode 100644 index 0000000..30a1184 --- /dev/null +++ b/src/amiga/stopwatch/stopwatch.c @@ -0,0 +1,161 @@ +/*************************************************************************** + * Copyright (C) 2018 by Alexander Fritsch * + * email: selco@t-online.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write see: * + * . * + ***************************************************************************/ + +#include +#include +#include "stopwatch.h" +#include +#include + +struct StopWatch *AllocStopWatch(void) +{ + struct StopWatch *sw; + + sw=malloc(sizeof(struct StopWatch)); + if(sw) + { + ResetStopWatch(sw); + sw->OpenDevRetVal=1; + + sw->OpenDevRetVal=OpenDevice((CONST_STRPTR)TIMERNAME, UNIT_MICROHZ, &sw->timereq, 0); + if(0==sw->OpenDevRetVal) + { + sw->TimerBase = (struct TimeBase*)sw->timereq.io_Device; + return sw; + } + else + { + printf("%s(): OpenDevice(%s) failed.\n",__FUNCTION__,TIMERNAME); + } + free(sw); + sw=NULL; + } + else + { + printf("%s(): malloc failed.\n",__FUNCTION__); + } + return sw; +} + +void FreeStopWatch(struct StopWatch *sw) +{ + if(!sw) + { + printf("%s(): NULL-Pointer",__FUNCTION__); + return; + } + if(sw->OpenDevRetVal==0) + { + CloseDevice(&sw->timereq); + } + free(sw); +} + + +void StartStopWatch(struct StopWatch *sw) +{ + if(0==sw->running) + { + struct TimeBase *TimerBase=sw->TimerBase; /* GetSysTime and SubTime need a valid variable TimerBase */ + GetSysTime(&sw->StartTime); + sw->running=1; + } + else + { + printf("%s(): already running\n"); + } +} + +void StopStopWatch(struct StopWatch *sw) +{ + if(1==sw->running) + { + struct TimeBase *TimerBase=sw->TimerBase; /* GetSysTime and SubTime need a valid variable TimerBase */ + GetSysTime(&sw->StopTime); + SubTime(&sw->StopTime, &sw->StartTime); + + AddTime(&sw->TotalTime,&sw->StopTime); + sw->running=0; + } + else + { + printf("%S(): already stopped\n",__FUNCTION__); + } +} + +unsigned long StopWatchGetMilliSeconds(struct StopWatch *sw) +{ + if(0==sw->running) + { + return (sw->StopTime.tv_secs * 1000 + sw->StopTime.tv_micro / 1000); + } + else + { + printf("%s(): currently running\n"); + return 0; + } +} + +unsigned long StopWatchGetTotalMilliSeconds(struct StopWatch *sw) +{ + if(0==sw->running) + { + return (sw->TotalTime.tv_secs * 1000 + sw->TotalTime.tv_micro / 1000); + } + else + { + printf("%s(): currently running\n"); + return 0; + } +} + +unsigned long long StopWatchGetMicroSeconds(struct StopWatch *sw) +{ + if(0==sw->running) + { + return (sw->StopTime.tv_secs * 1000000 + sw->StopTime.tv_micro); + } + else + { + printf("%s(): currently running\n"); + return 0; + } +} + +unsigned long long StopWatchGetTotalMicroSeconds(struct StopWatch *sw) +{ + if(0==sw->running) + { + return (sw->TotalTime.tv_secs * 1000000 + sw->TotalTime.tv_micro); + } + else + { + printf("%s(): currently running\n"); + return 0; + } +} + + +void ResetStopWatch(struct StopWatch *sw) +{ + memset(&sw->StartTime,0,sizeof(sw->StartTime)); + memset(&sw->StopTime,0,sizeof(sw->StopTime)); + memset(&sw->TotalTime,0,sizeof(sw->TotalTime)); + sw->running=0; +} diff --git a/src/amiga/stopwatch/stopwatch.h b/src/amiga/stopwatch/stopwatch.h new file mode 100644 index 0000000..d06fbc2 --- /dev/null +++ b/src/amiga/stopwatch/stopwatch.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (C) 2018 by Alexander Fritsch * + * email: selco@t-online.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write see: * + * . * + ***************************************************************************/ + +#include +#include + +struct StopWatch +{ + struct timeval StartTime; /* start of current measurement */ + struct timeval StopTime; /* end of current measurement */ + struct timeval TotalTime; /* sum of all measurements */ + struct TimeBase *TimerBase; /* Device Base */ + struct IORequest timereq; /* IORequest */ + unsigned int OpenDevRetVal; /* Flag is OpenDevice was successful (0=success) */ + unsigned int running; /* Flag if th stopwatch is running */ +}; + +struct StopWatch *AllocStopWatch(void); +void FreeStopWatch(struct StopWatch *sw); +void StartStopWatch(struct StopWatch *sw); +void StopStopWatch(struct StopWatch *sw); +void ResetStopWatch(struct StopWatch *sw); +unsigned long StopWatchGetMilliSeconds(struct StopWatch *sw); +unsigned long long StopWatchGetMicroSeconds(struct StopWatch *sw); +unsigned long StopWatchGetTotalMilliSeconds(struct StopWatch *sw); +unsigned long long StopWatchGetTotalMicroSeconds(struct StopWatch *sw); + diff --git a/src/amiga/stopwatch/stopwatch_test.c b/src/amiga/stopwatch/stopwatch_test.c new file mode 100644 index 0000000..49999de --- /dev/null +++ b/src/amiga/stopwatch/stopwatch_test.c @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 2018 by Alexander Fritsch * + * email: selco@t-online.de * +***************************************************************************/ +/* + * copmile with +/home/osboxes/opt/m68k-amigaos_26Nov18/bin/m68k-amigaos-gcc stopwatch_test.c stopwatch.c -O0 -Wall -noixemul -o test && sync +*/ + +#include "stopwatch.h" +#include +#include + + +struct StopWatch *sw1=NULL; +struct StopWatch *sw2=NULL; + +void CleanUp(void) +{ + if(sw2) + { + FreeStopWatch(sw2); + sw2=NULL; + } + if(sw1) + { + FreeStopWatch(sw1); + sw1=NULL; + } +} + +int main(void) +{ + sw1=AllocStopWatch(); + if(NULL==sw1) + { + printf("InitStopWatch 1 failed\n"); + CleanUp(); + return 1; + } + + sw2=AllocStopWatch(); + if(NULL==sw2) + { + printf("InitStopWatch 2 failed\n"); + CleanUp(); + return 2; + } + + + printf("Waiting 1 second for StopWatch 1...\n"); + StartStopWatch(sw1); + usleep(1000000); + StopStopWatch(sw1); + printf("StopWatch 1: %ldms elapsed\n",StopWatchGetMilliSeconds(sw1)); + printf("StopWatch 1: %lldus elapsed\n",StopWatchGetMicroSeconds(sw1)); + + printf("Waiting 2 more seconds for StopWatch 1...\n"); + StartStopWatch(sw1); + usleep(2000000); + StopStopWatch(sw1); + printf("StopWatch 1: %ldms elapsed\n",StopWatchGetMilliSeconds(sw1)); + printf("StopWatch 1: %lldus elapsed\n",StopWatchGetMicroSeconds(sw1)); + + printf("%ldms in total elapsed\n",StopWatchGetTotalMilliSeconds(sw1)); + + CleanUp(); +} diff --git a/src/main.c b/src/main.c index ab84e98..fbbc3f3 100644 --- a/src/main.c +++ b/src/main.c @@ -18,13 +18,39 @@ #ifdef __AMIGA__ // AF, use ahi.device instead of audio.device void set_ahi_devide(unsigned int unit); void SetCpuSpecificFunctions(void); // AF, we compile some functions for 68000 and for 68020 + // AF STOPWATCH + #include "amiga/stopwatch/stopwatch.h" + struct StopWatch *sw_main=NULL; + + + #define ALLOCSTOPWATCH(x) \ + x=AllocStopWatch(); \ + if(NULL==x) \ + { \ + printf("InitStopWatch 1 failed\n"); \ + CleanUp(); \ + return 1; \ + } + + + #define CLEANUP_SW(x) {if(x) { FreeStopWatch(x); x=NULL; }} + void CleanUp(void) + { + CLEANUP_SW(sw_main); + } + #endif + + #ifdef DEBUG #define D(x) x + #define CLEANUP_SW(x) {if(x) { FreeStopWatch(x); x=NULL; }} #else // for debug-prints. Can be activated with -DDEBUG in Makefile #define D(x) + #define CLEANUP_SW(x) + #endif @@ -181,6 +207,8 @@ int main(int argc, char **argv) D(printf("Los...\n")); time_t StartZeit=time(NULL); + D(ALLOCSTOPWATCH(sw_main)); // AF + D(StartStopWatch(sw_main)); // AF #ifdef USESDL #ifndef __AMIGA__ @@ -323,6 +351,16 @@ int main(int argc, char **argv) return 1; } { + //AF STOPWATCH + D( + StopStopWatch(sw_main); + { + #define PRINT_STOPWATCH(x) printf("Dauer " #x " : %6lums, (%2.2f%%)\n",StopWatchGetTotalMilliSeconds(x), 100.0*StopWatchGetTotalMilliSeconds(x)/main_ms); + + unsigned long main_ms=StopWatchGetMilliSeconds(sw_main); + printf("Dauer main : %6lums\n",main_ms); + } + ) D(printf("Sound berechnung nach %lld Sekunden\n",time(NULL)-StartZeit)); extern int bufferpos; D(printf("%s(): BufferPos=%d\n",__FUNCTION__,bufferpos)); From 3dda249d717909bf5900ab58adb4a907236b8cb1 Mon Sep 17 00:00:00 2001 From: githubaf Date: Fri, 21 Dec 2018 09:32:57 +0100 Subject: [PATCH 34/62] inline Output. timeTable[5][8] : 12.3 seconds -> 10.7 seconds --- AF_readme | 5 +++++ Makefile.amiga | 2 +- src/render2.c | 39 +++++++++++++++++++++++++++++++++------ 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/AF_readme b/AF_readme index eb80900..9605eef 100644 --- a/AF_readme +++ b/AF_readme @@ -136,3 +136,8 @@ Resident geht jetzt. Vorschlag von Bebbo zum Weitergeben von A4 ueber np_Input b 21.12.2018 ---------- Stopwatch fuer genauere Zeitmessung + +inline von Output() bringt 1,4 Sekunden bei Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0 +timeTable[5][8] bringt nochmal 0,13 Sekunden + +-> 10,77 Sekunden diff --git a/Makefile.amiga b/Makefile.amiga index 20237d1..f1962ff 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -56,7 +56,7 @@ strip: sam sync render000.o: src/render2.c - $(CC) $(CFLAGS) -O3 -c $< -o render000.o # this one is compiled with -O2 as it is the time critical part + $(CC) $(CFLAGS) -O2 -c $< -o render000.o # this one is compiled with -O2 as it is the time critical part render020.o: src/render2.c $(CC) $(CFLAGS) -m68020 -O3 -c $< -o render020.o # this one is compiled with -O2 as it is the time critical part diff --git a/src/render2.c b/src/render2.c index 44de7ff..89854a3 100644 --- a/src/render2.c +++ b/src/render2.c @@ -91,7 +91,34 @@ extern char *buffer; extern unsigned char sampledConsonantFlag[256]; // tab44800 -void Output(int index, unsigned char A); +//timetable for more accurate c64 simulation +static int timetable[5][8] = +{ + {162, 167, 167, 127, 128,0,0,0}, + {226, 60, 60, 0, 0,0,0,0}, + {225, 60, 59, 0, 0,0,0,0}, + {200, 0, 0, 54, 55,0,0,0}, + {199, 0, 0, 54, 54,0,0,0} +}; + +inline void CPU(Output)(int index, unsigned char A) +{ + static unsigned oldtimetableindex = 0; +// int k; + int local_bufferpos; // much faster if we use a local copy here 30s --> 13s for sam -wav hello.wav Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0 + char *local_buffer_ptr; + bufferpos += timetable[oldtimetableindex][index]; + local_bufferpos=bufferpos/50; + local_buffer_ptr=&buffer[local_bufferpos]; + oldtimetableindex = index; + // write a little bit in advance +// for(k=0; k<5; k++) + *local_buffer_ptr++ = (A & 15)*16; // much faster if we use a local copy here + *local_buffer_ptr++ = (A & 15)*16; // much faster if we use a local copy here + *local_buffer_ptr++ = (A & 15)*16; // much faster if we use a local copy here + *local_buffer_ptr++ = (A & 15)*16; // much faster if we use a local copy here + *local_buffer_ptr++ = (A & 15)*16; // much faster if we use a local copy here +} // ------------------------------------------------------------------------- @@ -215,13 +242,13 @@ void CPU(RenderSample)(unsigned char *mem66) // 68000 or 68020 Version of this X = mem53; //mem[54296] = X; // output the byte - Output(1, X); + CPU(Output)(1, X); // if X != 0, exit loop if(X != 0) goto pos48296; } // output a 5 for the on bit - Output(2, 5); + CPU(Output)(2, 5); //48295: NOP pos48296: @@ -278,13 +305,13 @@ void CPU(RenderSample)(unsigned char *mem66) // 68000 or 68020 Version of this { // if bit set, output 26 X = 26; - Output(3, X); + CPU(Output)(3, X); } else { //timetable 4 // bit is not set, output a 6 X=6; - Output(4, X); + CPU(Output)(4, X); } mem56--; @@ -807,7 +834,7 @@ if (debug) //mem[54296] = A; // output the accumulated value - Output(0, A); + CPU(Output)(0, A); speedcounter--; if (speedcounter != 0) goto pos48155; Y++; //go to next amplitude From 98a7fd18b980391ccf37a148eded85fa04c4ec04 Mon Sep 17 00:00:00 2001 From: githubaf Date: Fri, 21 Dec 2018 10:41:28 +0100 Subject: [PATCH 35/62] speed up by inline asm div by 50 in OutPut -> 10,09 Seconds --- AF_readme | 3 +++ src/render2.c | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/AF_readme b/AF_readme index 9605eef..d613ac9 100644 --- a/AF_readme +++ b/AF_readme @@ -141,3 +141,6 @@ inline von Output() bringt 1,4 Sekunden bei Hello, my name is sam. 1 2 3 4 5 6 7 timeTable[5][8] bringt nochmal 0,13 Sekunden -> 10,77 Sekunden + +ASM-inline fuer SDivMod32 in OutPut 10,77 -> 10,09 Sekunden + diff --git a/src/render2.c b/src/render2.c index 89854a3..79435e9 100644 --- a/src/render2.c +++ b/src/render2.c @@ -103,12 +103,25 @@ static int timetable[5][8] = inline void CPU(Output)(int index, unsigned char A) { + extern struct UtilityBase *UtilityBase; static unsigned oldtimetableindex = 0; // int k; int local_bufferpos; // much faster if we use a local copy here 30s --> 13s for sam -wav hello.wav Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0 char *local_buffer_ptr; bufferpos += timetable[oldtimetableindex][index]; - local_bufferpos=bufferpos/50; +// local_bufferpos=bufferpos/50; + + asm( + " move.l %1,d0;" + " moveq #50,d1;" + " move.l %2,a0;" // UtilityBase + " jsr a0@(-150:W);" + " move.l d0,%0" + : "=r" (local_bufferpos) + : "r" (bufferpos), "r" (UtilityBase) + : "d0","d1", "a0" + ); + local_buffer_ptr=&buffer[local_bufferpos]; oldtimetableindex = index; // write a little bit in advance From 9c030a2a6158352cbb064213846ad5f6dd4d2593 Mon Sep 17 00:00:00 2001 From: githubaf Date: Fri, 21 Dec 2018 14:48:54 +0100 Subject: [PATCH 36/62] -O2 --- Makefile.amiga | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.amiga b/Makefile.amiga index f1962ff..0685feb 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -59,7 +59,7 @@ render000.o: src/render2.c $(CC) $(CFLAGS) -O2 -c $< -o render000.o # this one is compiled with -O2 as it is the time critical part render020.o: src/render2.c - $(CC) $(CFLAGS) -m68020 -O3 -c $< -o render020.o # this one is compiled with -O2 as it is the time critical part + $(CC) $(CFLAGS) -m68020 -O2 -c $< -o render020.o # this one is compiled with -O2 as it is the time critical part %.o: src/%.c $(CC) $(CFLAGS) -c $< From 33089a8644b670c8fd4a6839405474376099eb44 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Fri, 21 Dec 2018 23:33:58 +0100 Subject: [PATCH 37/62] free Stopwatch at the end again (close timerdevice) --- src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.c b/src/main.c index fbbc3f3..9955803 100644 --- a/src/main.c +++ b/src/main.c @@ -206,6 +206,7 @@ int main(int argc, char **argv) static char input[256]; // AF, save some stack D(printf("Los...\n")); + D(atexit(CleanUp)); // Stopuhr freigeben time_t StartZeit=time(NULL); D(ALLOCSTOPWATCH(sw_main)); // AF D(StartStopWatch(sw_main)); // AF From 3e25982fe1acd85fc64a8a73574ed829dac858cc Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Sat, 22 Dec 2018 02:54:25 +0100 Subject: [PATCH 38/62] speed up Output() by avoiding division by 50. Crash, if compiled resident with my debug timer-prints. --- AF_readme | 5 +++++ Makefile.amiga | 6 +++--- src/render2.c | 7 ++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/AF_readme b/AF_readme index d613ac9..9a86e7e 100644 --- a/AF_readme +++ b/AF_readme @@ -144,3 +144,8 @@ timeTable[5][8] bringt nochmal 0,13 Sekunden ASM-inline fuer SDivMod32 in OutPut 10,77 -> 10,09 Sekunden +22.Dec.2018 +----------- +*327>>14, also *327/16384 statt durch 50 in Output. Jetzt ca 7,5 Skunden! Deutlich besser als die ASM Variante. +-resident stuerzt ab, wenn mit meinem Debug-Define compiliert wird. Wird da was zu gross? Fehler im Compiler? + diff --git a/Makefile.amiga b/Makefile.amiga index 0685feb..5579f39 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -1,7 +1,7 @@ # All the o-Files in Link-Order OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o render.o render000.o render020.o main.o portaudio_ahidev.o portaudio.o subtask_support.o amiga_version.o stopwatch.o -COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_18Dec18 +COMPILER_INSTALL_DIR = /home/osboxes/opt/m68k-amigaos_19Dec18 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc STRIP = $(COMPILER_DIR)/m68k-amigaos-strip @@ -19,11 +19,11 @@ CFLAGS += $(CPUFLAGS) CFLAGS += -Os # all but render.c arecompiled for size. Only render.c will be compiled for speed CFLAGS += -Wall -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` -CFLAGS += -resident +#CFLAGS += -resident CFLAGS += -msmall-code LFLAGS = -g -noixemul $(CPUFLAGS) -Wl,-Map=sam.map,--trace -ldebug #-lSDL #`sdl-config --libs` -LFLAGS += -resident +#LFLAGS += -resident #coverage diff --git a/src/render2.c b/src/render2.c index 79435e9..504bafe 100644 --- a/src/render2.c +++ b/src/render2.c @@ -110,7 +110,12 @@ inline void CPU(Output)(int index, unsigned char A) char *local_buffer_ptr; bufferpos += timetable[oldtimetableindex][index]; // local_bufferpos=bufferpos/50; +local_bufferpos=((bufferpos*327)>>14); //16384); // Durch 50,1 mal 327 durch 16384 // das beste! +//local_bufferpos=((bufferpos*327)/16384); // Durch 50,1 mal 327 durch 16384 +// local_bufferpos=((bufferpos<<8)+(bufferpos<<6)+(bufferpos<<3)-bufferpos) >>14; + +/* asm( " move.l %1,d0;" " moveq #50,d1;" @@ -121,7 +126,7 @@ inline void CPU(Output)(int index, unsigned char A) : "r" (bufferpos), "r" (UtilityBase) : "d0","d1", "a0" ); - +*/ local_buffer_ptr=&buffer[local_bufferpos]; oldtimetableindex = index; // write a little bit in advance From 91455e78135c4675e4a91077b9d43ca0967ee8b6 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Sat, 22 Dec 2018 03:07:43 +0100 Subject: [PATCH 39/62] fixed readme --- AF_readme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AF_readme b/AF_readme index 9a86e7e..0202993 100644 --- a/AF_readme +++ b/AF_readme @@ -146,6 +146,6 @@ ASM-inline fuer SDivMod32 in OutPut 10,77 -> 10,09 Sekunden 22.Dec.2018 ----------- -*327>>14, also *327/16384 statt durch 50 in Output. Jetzt ca 7,5 Skunden! Deutlich besser als die ASM Variante. +*327>>14, also *327/16384 statt durch 50 in Output(). Jetzt ca 7,74 Skunden! Deutlich besser als die ASM Variante. -resident stuerzt ab, wenn mit meinem Debug-Define compiliert wird. Wird da was zu gross? Fehler im Compiler? From 6148e60469f4e9c433a7f0ffe263b09ce2b1a5c9 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Sat, 22 Dec 2018 03:34:11 +0100 Subject: [PATCH 40/62] 327U fuer laengere Texte. kein -msmall-code im Moment. --- AF_readme | 5 ++++- Makefile.amiga | 6 +++--- src/render2.c | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/AF_readme b/AF_readme index 0202993..a27203c 100644 --- a/AF_readme +++ b/AF_readme @@ -148,4 +148,7 @@ ASM-inline fuer SDivMod32 in OutPut 10,77 -> 10,09 Sekunden ----------- *327>>14, also *327/16384 statt durch 50 in Output(). Jetzt ca 7,74 Skunden! Deutlich besser als die ASM Variante. -resident stuerzt ab, wenn mit meinem Debug-Define compiliert wird. Wird da was zu gross? Fehler im Compiler? - +- Es scheint nicht resident zu sein, sondern -msmall-code, was zum Absturz fuehrt. +- 327U i der Multiplikation, sonst stuerzt sam bei langen Texten ab. +- Test fuer Linux und Amiga: sam Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0 0 9 8 7 6 5 4 3 2 1 +Damit dann auch nochmal A1200 testen und dort ev fiv lassen? Dort ev anders optimieren? diff --git a/Makefile.amiga b/Makefile.amiga index 5579f39..952ccdb 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -19,11 +19,11 @@ CFLAGS += $(CPUFLAGS) CFLAGS += -Os # all but render.c arecompiled for size. Only render.c will be compiled for speed CFLAGS += -Wall -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` -#CFLAGS += -resident -CFLAGS += -msmall-code +CFLAGS += -resident +#CFLAGS += -msmall-code LFLAGS = -g -noixemul $(CPUFLAGS) -Wl,-Map=sam.map,--trace -ldebug #-lSDL #`sdl-config --libs` -#LFLAGS += -resident +LFLAGS += -resident #coverage diff --git a/src/render2.c b/src/render2.c index 504bafe..031138f 100644 --- a/src/render2.c +++ b/src/render2.c @@ -110,8 +110,8 @@ inline void CPU(Output)(int index, unsigned char A) char *local_buffer_ptr; bufferpos += timetable[oldtimetableindex][index]; // local_bufferpos=bufferpos/50; -local_bufferpos=((bufferpos*327)>>14); //16384); // Durch 50,1 mal 327 durch 16384 // das beste! -//local_bufferpos=((bufferpos*327)/16384); // Durch 50,1 mal 327 durch 16384 +local_bufferpos=((bufferpos*327U)>>14); //16384); // Durch 50,1 mal 327 durch 16384 // das beste! +//local_bufferpos=((bufferpos*327U)/16384); // Durch 50,1 mal 327 durch 16384 // local_bufferpos=((bufferpos<<8)+(bufferpos<<6)+(bufferpos<<3)-bufferpos) >>14; From 8cfa97c43e405bfb5749c3e8074a0fbda5ad4687 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Thu, 27 Dec 2018 22:14:55 +0100 Subject: [PATCH 41/62] new compiler fixes -msmall-code issues --- Makefile.amiga | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index 952ccdb..3e773bb 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -1,7 +1,7 @@ # All the o-Files in Link-Order OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o render.o render000.o render020.o main.o portaudio_ahidev.o portaudio.o subtask_support.o amiga_version.o stopwatch.o -COMPILER_INSTALL_DIR = /home/osboxes/opt/m68k-amigaos_19Dec18 +COMPILER_INSTALL_DIR = /home/osboxes/opt/m68k-amigaos_23Dec18 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc STRIP = $(COMPILER_DIR)/m68k-amigaos-strip @@ -20,7 +20,7 @@ CFLAGS += -Os # all but render.c arecompiled for size. Only render.c will be co CFLAGS += -Wall -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` CFLAGS += -resident -#CFLAGS += -msmall-code +CFLAGS += -msmall-code LFLAGS = -g -noixemul $(CPUFLAGS) -Wl,-Map=sam.map,--trace -ldebug #-lSDL #`sdl-config --libs` LFLAGS += -resident From 7f8215da1bb12b92ebafb3824d0977dabd9e7e7c Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Fri, 28 Dec 2018 22:47:05 +0100 Subject: [PATCH 42/62] Aminet Release 1.1 --- AF_readme | 52 +++++++++++++++++++++++++++++++ Makefile.amiga | 2 +- src/amiga/version/amiga_version.c | 6 ++-- src/sam.c | 5 +++ 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/AF_readme b/AF_readme index a27203c..4f71427 100644 --- a/AF_readme +++ b/AF_readme @@ -152,3 +152,55 @@ ASM-inline fuer SDivMod32 in OutPut 10,77 -> 10,09 Sekunden - 327U i der Multiplikation, sonst stuerzt sam bei langen Texten ab. - Test fuer Linux und Amiga: sam Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0 0 9 8 7 6 5 4 3 2 1 Damit dann auch nochmal A1200 testen und dort ev fiv lassen? Dort ev anders optimieren? + +27.Dec.2018 +----------- +Der Code enthaelt viele globale Variablen, die ev. die Optimierung beeintraechtigen? + +Alle globalen Variablen finden + +~/opt/m68k-amigaos_23Dec18/bin/m68k-amigaos-gdb sam +info variables + +Dann die C-Files finden, in denen dieses Variablen benutzt werden. Manche koenen vielleicht zu lokalen Variablen gemacht werden. +z.B. finde alle Verwendungen von mem39 finden + +find src -name "*.c" -exec grep -nH "mem39[^(0-9)]" {} \; + + +28.Dec.28 +--------- +WinUAE +A1200 ohne FastRam: 1111ms (1286ms bei 68000-code) +A1200 mit FastRam: 423ms (474ms bei 68000-code) +Die 68020-Erkennung bringt also nicht wirklich viel... + +A500 ohne FastRam: 7572ms +A500 mit FastRam: 7569ms +Beim A500 spielt FastRam also keine Rolle. + +Sam Groesse: 49900 Bytes + +Aminet: +;http://aminet.net/util/arc/lha.run ; lha genommen: LhA 2.15 68000+ Jan 3 2011 +wget http://aminet.net/util/arc/lha.run + +in WinUAE: +protect demos_amiga/#? +s +protect sam +p +lha_68k a sam.lha sam sam.readme README.md +lha_68k a sam.lha demos_amiga/#? -r + +in Linux: +ftp -p # -p passive mode, falls ftp durch NAT +open main.aminet.net +Name (main.aminet.net:developer): anonymous +Password: selco@t-online.de +cd new +pwd +put sam.lha +put sam.readme # keine Verzeichnisse! also nicht z.B. amiga/espeak.readme! +quit + +Aminet Release 1.1 + diff --git a/Makefile.amiga b/Makefile.amiga index 3e773bb..b259600 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -13,7 +13,7 @@ CPUFLAGS=-m68000 CFLAGS = -DDATE="\"$(shell /bin/date +'%d.%m.%Y')\"" CFLAGS += -DPLATFORM_IS_BIG_ENDIAN -DSTATIC_FUNC= -DUSESDL CFLAGS += -DTOOLCHAIN_VER="\"$(TOOLCHAIN_VER)\"" -CFLAGS += -DDEBUG +#CFLAGS += -DDEBUG CFLAGS += -Iamiga/ -Iamiga/portaudio/ -I. -I$(COMPILER_INSTALL_DIR)/include/SDL CFLAGS += $(CPUFLAGS) CFLAGS += -Os # all but render.c arecompiled for size. Only render.c will be compiled for speed diff --git a/src/amiga/version/amiga_version.c b/src/amiga/version/amiga_version.c index f8d843a..18f9e17 100644 --- a/src/amiga/version/amiga_version.c +++ b/src/amiga/version/amiga_version.c @@ -43,11 +43,11 @@ #define REVISION "1" /* Revision always starts with 1 ! */ //#define DATE "15.07.2017" /* comes from make-command line as CXXFLAGS+=-DDATE=\\\"$(date +'%d.%m.%Y')\\\" */ #define PROGNAME "sam" -#define COMMENT "BETA-Version, Alexander Fritsch, selco, based on SAM C-conversion by Sebastian Macke" -//#define COMMENT "Alexander Fritsch, selco, based on SAM C-conversion by Sebastian Macke" +//#define COMMENT "BETA-Version, Alexander Fritsch, selco, based on SAM C-conversion by Sebastian Macke" +#define COMMENT "Alexander Fritsch, selco, based on SAM C-conversion by Sebastian Macke" #define VERS PROGNAME" " VERSION "." REVISION -#define VERSTAG "\0$VER: " PROGNAME " " VERSION "." REVISION " (" DATE ") " COMMENT ", compiled for " __CPU__ __FPU__ +#define VERSTAG "\0$VER: " PROGNAME " " VERSION "." REVISION " (" DATE ") " COMMENT //", compiled for " __CPU__ __FPU__ char versiontag[] = VERSTAG; diff --git a/src/sam.c b/src/sam.c index a2e3001..9865e50 100644 --- a/src/sam.c +++ b/src/sam.c @@ -93,6 +93,11 @@ void Init() bufferpos = 0; // TODO, check for free the memory, 10 seconds of output should be more than enough buffer = malloc(22050*10); + if(NULL==buffer) // AF + { + printf("Not enough memory to allocate 220500 bytes\n"); + exit(1); + } memset(buffer,128,22050*10); //AF: avoid "hiss" at the end of sound playback /* freq2data = &mem[45136]; From 0f097fe5363c148aec53a1228d1b29472f8bbc8b Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Sat, 29 Dec 2018 22:48:43 +0100 Subject: [PATCH 43/62] removes const from sinus und rectangle (comment from Gunther Nikl) --- AF_readme | 9 +++++++++ Makefile.amiga | 2 +- src/render2.c | 4 ++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/AF_readme b/AF_readme index 4f71427..77145aa 100644 --- a/AF_readme +++ b/AF_readme @@ -204,3 +204,12 @@ quit Aminet Release 1.1 +29.Dec.2018 +----------- +Kommentar von Gunther Nikl: +Anbei noch ein Patch für render2.c: Dort importierst Du sinus und +rectangle als "const". Diese sind in RenderTabs.h aber OHNE const +angelegt. + +--> const aus render2.c rausgenommen. 32 Bytes kleineres Programm. +Compiler vom 28.12.18 genommen. diff --git a/Makefile.amiga b/Makefile.amiga index b259600..19041ac 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -1,7 +1,7 @@ # All the o-Files in Link-Order OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o render.o render000.o render020.o main.o portaudio_ahidev.o portaudio.o subtask_support.o amiga_version.o stopwatch.o -COMPILER_INSTALL_DIR = /home/osboxes/opt/m68k-amigaos_23Dec18 +COMPILER_INSTALL_DIR = /home/osboxes/opt/m68k-amigaos_28Dec18 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc STRIP = $(COMPILER_DIR)/m68k-amigaos-strip diff --git a/src/render2.c b/src/render2.c index 031138f..7958815 100644 --- a/src/render2.c +++ b/src/render2.c @@ -42,8 +42,8 @@ extern unsigned char freq3data[80]; extern unsigned char ampl1data[80]; extern unsigned char ampl2data[80]; extern unsigned char ampl3data[80]; -extern unsigned char const sinus[256]; -extern unsigned char const rectangle[256]; +extern unsigned char sinus[256]; +extern unsigned char rectangle[256]; From 91cb3f56a5612b89843c49fbedfd344cbb17a1c8 Mon Sep 17 00:00:00 2001 From: Alexander Fritsch Date: Sun, 30 Dec 2018 21:57:19 +0100 Subject: [PATCH 44/62] experimenting in Mailefile.amiga --- Makefile.amiga | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index 19041ac..f1cc555 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -18,12 +18,13 @@ CFLAGS += -Iamiga/ -Iamiga/portaudio/ -I. -I$(COMPILER_INSTALL_DIR)/include/SDL CFLAGS += $(CPUFLAGS) CFLAGS += -Os # all but render.c arecompiled for size. Only render.c will be compiled for speed CFLAGS += -Wall -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` +#CFLAGS += -Wa,-adhln #produce nice Assemby output -CFLAGS += -resident +#CFLAGS += -resident CFLAGS += -msmall-code LFLAGS = -g -noixemul $(CPUFLAGS) -Wl,-Map=sam.map,--trace -ldebug #-lSDL #`sdl-config --libs` -LFLAGS += -resident +#LFLAGS += -resident #coverage @@ -56,12 +57,12 @@ strip: sam sync render000.o: src/render2.c - $(CC) $(CFLAGS) -O2 -c $< -o render000.o # this one is compiled with -O2 as it is the time critical part + $(CC) $(CFLAGS) -O2 -c $< -o render000.o # this one is compiled with -O2 as it is the time critical part render020.o: src/render2.c - $(CC) $(CFLAGS) -m68020 -O2 -c $< -o render020.o # this one is compiled with -O2 as it is the time critical part + $(CC) $(CFLAGS) -m68020 -O2 -c $< -o render020.o # this one is compiled with -O2 as it is the time critical part %.o: src/%.c - $(CC) $(CFLAGS) -c $< + $(CC) $(CFLAGS) -c $< package: tar -cvzf sam.tar.gz README.md Makefile sing src/ From 423d121e5da8501a55aaec6f1586f5e61d99d6e2 Mon Sep 17 00:00:00 2001 From: githubaf Date: Tue, 19 Feb 2019 08:40:23 +0100 Subject: [PATCH 45/62] newer Compiler --- Makefile.amiga | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index f1cc555..f63db5e 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -1,7 +1,23 @@ # All the o-Files in Link-Order OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o render.o render000.o render020.o main.o portaudio_ahidev.o portaudio.o subtask_support.o amiga_version.o stopwatch.o -COMPILER_INSTALL_DIR = /home/osboxes/opt/m68k-amigaos_28Dec18 +# 7.552 Seconds +# COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_23Dec18 + # 7.58 Seconds for 21Jan19 +# bad COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_21Jan19 +# ok COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_29Dec18 +# bad COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_14Jan19 +# bad COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_13Jan19 +# ok COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_09Jan19 +# OK --> COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_11Jan19 +# ok COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_06Jan19 +# bad, wird nicht fertig bei Coverage COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_10Feb19 +# ok COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_04Feb19 +# OK COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_07Feb19 +# OK COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_12Feb19 +# OK +COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_16Feb19 + COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc STRIP = $(COMPILER_DIR)/m68k-amigaos-strip @@ -13,25 +29,24 @@ CPUFLAGS=-m68000 CFLAGS = -DDATE="\"$(shell /bin/date +'%d.%m.%Y')\"" CFLAGS += -DPLATFORM_IS_BIG_ENDIAN -DSTATIC_FUNC= -DUSESDL CFLAGS += -DTOOLCHAIN_VER="\"$(TOOLCHAIN_VER)\"" -#CFLAGS += -DDEBUG +CFLAGS += -DDEBUG CFLAGS += -Iamiga/ -Iamiga/portaudio/ -I. -I$(COMPILER_INSTALL_DIR)/include/SDL CFLAGS += $(CPUFLAGS) CFLAGS += -Os # all but render.c arecompiled for size. Only render.c will be compiled for speed CFLAGS += -Wall -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` -#CFLAGS += -Wa,-adhln #produce nice Assemby output -#CFLAGS += -resident +CFLAGS += -resident CFLAGS += -msmall-code LFLAGS = -g -noixemul $(CPUFLAGS) -Wl,-Map=sam.map,--trace -ldebug #-lSDL #`sdl-config --libs` -#LFLAGS += -resident - +LFLAGS += -resident #coverage -#CFLAGS += -fprofile-generate=VBox:$(shell pwd | cut -c2-) # remove first "/" from pwd -> VBox:home/... -#CFLAGS += -ftest-coverage -#CFLAGS += -fprofile-arcs #-pg # Profiler -#LFLAGS += -lgcov + CFLAGS += -fprofile-generate=VBox:$(shell pwd | cut -c2-) # remove first "/" from pwd -> VBox:home/... + CFLAGS += -ftest-coverage + CFLAGS += -fprofile-arcs #-pg # Profiler + LFLAGS += -lgcov + #CFLAGS += -g -pg -fno-omit-frame-pointer #LFLAGS += -pg @@ -57,18 +72,18 @@ strip: sam sync render000.o: src/render2.c - $(CC) $(CFLAGS) -O2 -c $< -o render000.o # this one is compiled with -O2 as it is the time critical part + $(CC) $(CFLAGS) -O2 -c $< -o render000.o # this one is compiled with -O2 as it is the time critical part render020.o: src/render2.c - $(CC) $(CFLAGS) -m68020 -O2 -c $< -o render020.o # this one is compiled with -O2 as it is the time critical part + $(CC) $(CFLAGS) -m68020 -O2 -c $< -o render020.o # this one is compiled with -O2 as it is the time critical part %.o: src/%.c - $(CC) $(CFLAGS) -c $< + $(CC) $(CFLAGS) -c $< package: tar -cvzf sam.tar.gz README.md Makefile sing src/ clean: - rm -f *.o *.wav sam sam.map + rm -f *.o *.wav sam sam.map *.gcno *.gcda archive: rm -f sam_windows.zip From b259fcb9129c855f5c5ca97645a9f3e92eb9d560 Mon Sep 17 00:00:00 2001 From: githubaf Date: Wed, 20 Feb 2019 15:55:45 +0100 Subject: [PATCH 46/62] coverage als Malefile.amiga-target. Test auch gcno-Files noch nicht ganz OK. (geht erst beim 2. Mal) --- Makefile.amiga | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Makefile.amiga b/Makefile.amiga index f63db5e..b52b5a2 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -21,6 +21,7 @@ COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_16Feb19 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc STRIP = $(COMPILER_DIR)/m68k-amigaos-strip +GCOV = $(COMPILER_DIR)/m68k-amigaos-gcov TOOLCHAIN_VER=$(shell cat $(COMPILER_DIR)/toolchain_commit.txt) @@ -42,10 +43,12 @@ LFLAGS = -g -noixemul $(CPUFLAGS) -Wl,-Map=sam.map,--trace -ldebug #-lSDL #`sdl LFLAGS += -resident #coverage +ifneq ($(COVERAGE),) CFLAGS += -fprofile-generate=VBox:$(shell pwd | cut -c2-) # remove first "/" from pwd -> VBox:home/... CFLAGS += -ftest-coverage CFLAGS += -fprofile-arcs #-pg # Profiler LFLAGS += -lgcov +endif #CFLAGS += -g -pg -fno-omit-frame-pointer #LFLAGS += -pg @@ -88,3 +91,12 @@ clean: archive: rm -f sam_windows.zip cd ..; zip SAM/sam_windows.zip SAM/sam.exe SAM/SDL.dll SAM/README.md SAM/demos/*.bat + +coverage: + make -f Makefile.amiga COVERAGE=true + [ "15" = "$(shell ls *.gcno | wc --w)" ] # 15 gcno-Files should have been created + vamos -V VBox:/home/developer/ -- sam -wav hello.wav "Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0" # start sam + $(GCOV) main.c + # argument-loop must have been ececuted 3 times in our example + cat main.c.gcov | grep "while(i < argc)" | awk -F: '{if( $$1 >=3){ print "Coverage OK";} else{ print "Coverage failed!!!"; exit 1;}}' + From d9bfd05a755250292a4ea943e1a8c2da56474505 Mon Sep 17 00:00:00 2001 From: githubaf Date: Mon, 25 Feb 2019 12:09:18 +0100 Subject: [PATCH 47/62] coverage-target checks that exactly 15 gcno-Files are created. --- Makefile.amiga | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile.amiga b/Makefile.amiga index b52b5a2..54d5f6b 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -94,7 +94,9 @@ archive: coverage: make -f Makefile.amiga COVERAGE=true - [ "15" = "$(shell ls *.gcno | wc --w)" ] # 15 gcno-Files should have been created + find | grep gcno | wc --w > count.txt # 15 gcno-Files should have been created + echo Found $$(cat count.txt) gcno-Files. + [ $$(cat count.txt) = "15" ] || (echo Wrong number of gcno-Files!; exit 1) vamos -V VBox:/home/developer/ -- sam -wav hello.wav "Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0" # start sam $(GCOV) main.c # argument-loop must have been ececuted 3 times in our example From e83f96e5348f06d922527e7831f2e0d422e2550c Mon Sep 17 00:00:00 2001 From: githubaf Date: Tue, 26 Feb 2019 11:37:29 +0100 Subject: [PATCH 48/62] improved coverage target. colored output. better error checking. Newer Compiler --- Makefile.amiga | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index 54d5f6b..c226954 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -16,7 +16,8 @@ OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o r # OK COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_07Feb19 # OK COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_12Feb19 # OK -COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_16Feb19 +# OK COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_16Feb19 +COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_25Feb19 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc @@ -86,7 +87,7 @@ package: tar -cvzf sam.tar.gz README.md Makefile sing src/ clean: - rm -f *.o *.wav sam sam.map *.gcno *.gcda + rm -f *.o *.wav sam sam.map *.gcno *.gcda *.gcov coverage*.html archive: rm -f sam_windows.zip @@ -99,6 +100,6 @@ coverage: [ $$(cat count.txt) = "15" ] || (echo Wrong number of gcno-Files!; exit 1) vamos -V VBox:/home/developer/ -- sam -wav hello.wav "Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0" # start sam $(GCOV) main.c - # argument-loop must have been ececuted 3 times in our example - cat main.c.gcov | grep "while(i < argc)" | awk -F: '{if( $$1 >=3){ print "Coverage OK";} else{ print "Coverage failed!!!"; exit 1;}}' + # argument-loop must have been ececuted 3 times in our example. Red if string not found (|| nothing) or count <3, green if all OK + cat main.c.gcov | (grep "while(i < argc)" || echo nothing) | awk -F: '{if( strtonum($$1) >=3){ print "\033[92mCoverage OK\033[0m";} else{ print "\033[91mCoverage failed!!!\033[0m"; exit 1;}}' From a2ad5da92d792df493d780672043be39b49fab98 Mon Sep 17 00:00:00 2001 From: githubaf Date: Fri, 1 Mar 2019 17:24:57 +0100 Subject: [PATCH 49/62] readme --- AF_readme | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/AF_readme b/AF_readme index 77145aa..9d0520f 100644 --- a/AF_readme +++ b/AF_readme @@ -213,3 +213,16 @@ angelegt. --> const aus render2.c rausgenommen. 32 Bytes kleineres Programm. Compiler vom 28.12.18 genommen. + + +1.Mar.2019 +---------- +Der gcc kann jetzt auch mit +make update +make v date=2019-02-18 +make all PREFIX=/here/or/there + +aufgerufen werden. dann wird (in alle Projekten) )ausgechecked, was am 18.Feb.2019 gueltig war. (auch, wenn es z.B. am 12.Jan. das letzte checkin/push gab) + + + From 46af71367ec122f5dafa60640ece125188b37224 Mon Sep 17 00:00:00 2001 From: githubaf Date: Thu, 7 Mar 2019 11:52:34 +0100 Subject: [PATCH 50/62] Changed to COMPILER_INSTALL_DIR ?= ... as suggested by bebbo --- Makefile.amiga | 34 ++++++++++++++++++------------- src/amiga/version/amiga_version.c | 6 +++--- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index c226954..8e7d863 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -2,22 +2,28 @@ OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o render.o render000.o render020.o main.o portaudio_ahidev.o portaudio.o subtask_support.o amiga_version.o stopwatch.o # 7.552 Seconds -# COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_23Dec18 +# COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_23Dec18 # 7.58 Seconds for 21Jan19 -# bad COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_21Jan19 -# ok COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_29Dec18 -# bad COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_14Jan19 -# bad COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_13Jan19 -# ok COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_09Jan19 -# OK --> COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_11Jan19 -# ok COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_06Jan19 -# bad, wird nicht fertig bei Coverage COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_10Feb19 -# ok COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_04Feb19 -# OK COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_07Feb19 -# OK COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_12Feb19 +# bad COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_21Jan19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_29Dec18 +# bad COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_14Jan19 +# bad COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_13Jan19 +# ok COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_09Jan19 +# OK --> COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_11Jan19 +# ok COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_06Jan19 +# bad, wird nicht fertig bei Coverage COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_10Feb19 +# ok COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_04Feb19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_07Feb19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_12Feb19 # OK -# OK COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_16Feb19 -COMPILER_INSTALL_DIR = /home/developer/opt/m68k-amigaos_25Feb19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_16Feb19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_25Feb19 +# OK +COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_26Feb19 +# BAD, Linker Errors COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_28Feb19 +# bad coverage failed (vamos illegal memory access) COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_01Mar19 +# bad coverage failed (vamos illegal memory access) COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_02Mar19 +# bad coverage failed (vamos illegal memory access) COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_04Mar19 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc diff --git a/src/amiga/version/amiga_version.c b/src/amiga/version/amiga_version.c index 18f9e17..6df552d 100644 --- a/src/amiga/version/amiga_version.c +++ b/src/amiga/version/amiga_version.c @@ -40,11 +40,11 @@ #define VERSION "1" -#define REVISION "1" /* Revision always starts with 1 ! */ +#define REVISION "2" /* Revision always starts with 1 ! */ //#define DATE "15.07.2017" /* comes from make-command line as CXXFLAGS+=-DDATE=\\\"$(date +'%d.%m.%Y')\\\" */ #define PROGNAME "sam" -//#define COMMENT "BETA-Version, Alexander Fritsch, selco, based on SAM C-conversion by Sebastian Macke" -#define COMMENT "Alexander Fritsch, selco, based on SAM C-conversion by Sebastian Macke" +#define COMMENT "BETA-Version, Alexander Fritsch, selco, based on SAM C-conversion by Sebastian Macke" +//#define COMMENT "Alexander Fritsch, selco, based on SAM C-conversion by Sebastian Macke" #define VERS PROGNAME" " VERSION "." REVISION #define VERSTAG "\0$VER: " PROGNAME " " VERSION "." REVISION " (" DATE ") " COMMENT //", compiled for " __CPU__ __FPU__ From 8fe01535376496667aeb649b8c900afc1f97a99e Mon Sep 17 00:00:00 2001 From: githubaf Date: Wed, 13 Mar 2019 13:28:35 +0100 Subject: [PATCH 51/62] use newest compiler. coverage test passes again. --- Makefile.amiga | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index 8e7d863..d489067 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -18,12 +18,15 @@ OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o r # OK # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_16Feb19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_25Feb19 -# OK -COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_26Feb19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_26Feb19 # BAD, Linker Errors COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_28Feb19 # bad coverage failed (vamos illegal memory access) COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_01Mar19 # bad coverage failed (vamos illegal memory access) COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_02Mar19 # bad coverage failed (vamos illegal memory access) COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_04Mar19 +# bad coverage failed (vamos illegal memory access) COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_07Mar19 +# OK now again. Coverage works +COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_12Mar19 + COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc From f3e998069ea9ab8b102e4a7502549ea5ff9beb9a Mon Sep 17 00:00:00 2001 From: githubaf Date: Mon, 18 Mar 2019 15:43:13 +0100 Subject: [PATCH 52/62] tested new compilers --- Makefile.amiga | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index d489067..e8dabe4 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -25,8 +25,12 @@ OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o r # bad coverage failed (vamos illegal memory access) COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_04Mar19 # bad coverage failed (vamos illegal memory access) COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_07Mar19 # OK now again. Coverage works -COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_12Mar19 - +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_12Mar19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_13Mar19 +# OK +COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_15Mar19 +# BAD fatal error: SDL.h: No such file or directory COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_16Mar19 +# BAD fatal error: SDL.h: No such file or directory COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_17Mar19 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc From 406c266aa57e205c6e9fb312526571aab5d9c9c6 Mon Sep 17 00:00:00 2001 From: githubaf Date: Fri, 22 Mar 2019 10:29:39 +0100 Subject: [PATCH 53/62] neuer compiler --- Makefile.amiga | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index e8dabe4..69a09ac 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -27,10 +27,11 @@ OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o r # OK now again. Coverage works # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_12Mar19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_13Mar19 -# OK -COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_15Mar19 -# BAD fatal error: SDL.h: No such file or directory COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_16Mar19 -# BAD fatal error: SDL.h: No such file or directory COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_17Mar19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_15Mar19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_16Mar19 # changed include for SDL starting 16Mar19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_17Mar19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_18Mar19 +COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_21Mar19 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc @@ -45,7 +46,9 @@ CFLAGS = -DDATE="\"$(shell /bin/date +'%d.%m.%Y')\"" CFLAGS += -DPLATFORM_IS_BIG_ENDIAN -DSTATIC_FUNC= -DUSESDL CFLAGS += -DTOOLCHAIN_VER="\"$(TOOLCHAIN_VER)\"" CFLAGS += -DDEBUG -CFLAGS += -Iamiga/ -Iamiga/portaudio/ -I. -I$(COMPILER_INSTALL_DIR)/include/SDL +CFLAGS += -Iamiga/ -Iamiga/portaudio/ -I. +CFLAGS += -I$(COMPILER_INSTALL_DIR)/include/SDL # for toolchain up to 15Mar19 +CFLAGS += -I$(COMPILER_INSTALL_DIR)/m68k-amigaos/include/SDL # for toolchain starting 16Mar19 CFLAGS += $(CPUFLAGS) CFLAGS += -Os # all but render.c arecompiled for size. Only render.c will be compiled for speed CFLAGS += -Wall -fomit-frame-pointer -noixemul -g #`sdl-config --cflags` From 931d38114ec92e99bd76243cda36c4c100dc989d Mon Sep 17 00:00:00 2001 From: githubaf Date: Mon, 25 Mar 2019 11:33:59 +0100 Subject: [PATCH 54/62] new compiler --- Makefile.amiga | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.amiga b/Makefile.amiga index 69a09ac..5f281b5 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -31,7 +31,8 @@ OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o r # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_16Mar19 # changed include for SDL starting 16Mar19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_17Mar19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_18Mar19 -COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_21Mar19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_21Mar19 +COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_23Mar19 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc From b40e5087f5e4e707d1e0ce6b3f5de972fe97e05d Mon Sep 17 00:00:00 2001 From: githubaf Date: Mon, 29 Apr 2019 13:30:46 +0200 Subject: [PATCH 55/62] use Compiler from 29.4.19. Works again. --- Makefile.amiga | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index 5f281b5..067046f 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -15,7 +15,6 @@ OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o r # ok COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_04Feb19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_07Feb19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_12Feb19 -# OK # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_16Feb19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_25Feb19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_26Feb19 @@ -32,7 +31,19 @@ OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o r # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_17Mar19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_18Mar19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_21Mar19 -COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_23Mar19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_23Mar19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_02Apr19 +# BAD ld: internal error /home/developer/amiga-gcc_07Apr19/projects/binutils/ld/ldlang.c 6644 COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_07Apr19 +# BAD ld: internal error /home/developer/amiga-gcc_08Apr19/projects/binutils/ld/ldlang.c 6644 COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_08Apr19 +# BAD ld: internal error /home/developer/amiga-gcc_12Apr19/projects/binutils/ld/ldlang.c 6644 COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_12Apr19 +# BAD ld: internal error /home/developer/amiga-gcc_13Apr19/projects/binutils/ld/ldlang.c 6644 COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_13Apr19 +# BAD ld: internal error /home/developer/amiga-gcc_14Apr19/projects/binutils/ld/ldlang.c 6644COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_14Apr19 +# BAD machine: ERROR COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_15Apr19 +# BAD machine: ERROR COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_16Apr19 +# BAD machine: ERROR COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_23Apr19 +# OK +COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_28Apr19 + COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc From 7c4354bbeaf35eb65da58f6e5b0dcd9302116ea9 Mon Sep 17 00:00:00 2001 From: githubaf Date: Thu, 2 May 2019 09:27:53 +0200 Subject: [PATCH 56/62] Compiler from 1. May --- Makefile.amiga | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index 067046f..30f3369 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -41,9 +41,9 @@ OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o r # BAD machine: ERROR COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_15Apr19 # BAD machine: ERROR COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_16Apr19 # BAD machine: ERROR COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_23Apr19 -# OK -COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_28Apr19 - +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_28Apr19 +# OK +COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_01May19 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc From 2c0d05d46dcf92dadebfda4b178a29faf523709f Mon Sep 17 00:00:00 2001 From: githubaf Date: Mon, 20 May 2019 11:08:15 +0200 Subject: [PATCH 57/62] new compiler --- Makefile.amiga | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index 30f3369..5d8606d 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -42,8 +42,9 @@ OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o r # BAD machine: ERROR COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_16Apr19 # BAD machine: ERROR COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_23Apr19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_28Apr19 -# OK -COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_01May19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_01May19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_07May19 +COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_18May19 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc From 92227745d2cc686cdbebafdcab0b6ab5783c11df Mon Sep 17 00:00:00 2001 From: githubaf Date: Mon, 27 May 2019 10:19:14 +0200 Subject: [PATCH 58/62] new compiler --- Makefile.amiga | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile.amiga b/Makefile.amiga index 5d8606d..1b957de 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -44,7 +44,9 @@ OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o r # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_28Apr19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_01May19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_07May19 -COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_18May19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_18May19 +# OK +COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_26May19 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc @@ -132,3 +134,6 @@ coverage: # argument-loop must have been ececuted 3 times in our example. Red if string not found (|| nothing) or count <3, green if all OK cat main.c.gcov | (grep "while(i < argc)" || echo nothing) | awk -F: '{if( strtonum($$1) >=3){ print "\033[92mCoverage OK\033[0m";} else{ print "\033[91mCoverage failed!!!\033[0m"; exit 1;}}' + +test: sam + vamos -v -V VBox:/home/developer/ -- sam -wav hello.wav "Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0" # start sam From 5488cdb5473534cef0b75bc2f4870d2488fef6f3 Mon Sep 17 00:00:00 2001 From: githubaf Date: Mon, 1 Jul 2019 10:44:48 +0200 Subject: [PATCH 59/62] new Compiler 30.Juni 2019 --- Makefile.amiga | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index 1b957de..76fd39d 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -45,8 +45,9 @@ OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o r # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_01May19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_07May19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_18May19 -# OK -COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_26May19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_26May19 +#OK +COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_30Jun19 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc From 1887b8b4466c13e7181c175c2384c4528251cb7b Mon Sep 17 00:00:00 2001 From: githubaf Date: Mon, 12 Aug 2019 15:59:55 +0200 Subject: [PATCH 60/62] new compiler --- Makefile.amiga | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index 76fd39d..ff2dd85 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -46,8 +46,8 @@ OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o r # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_07May19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_18May19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_26May19 -#OK -COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_30Jun19 +# OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_30Jun19 +COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_07Aug19 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc From 00eaefd3d49f16a11d9bda709e8ec4af2e9a2753 Mon Sep 17 00:00:00 2001 From: githubaf Date: Thu, 15 Aug 2019 13:05:59 +0200 Subject: [PATCH 61/62] added make-target for profiling-test. --- .gitignore | 3 +++ AF_readme | 3 +++ Makefile.amiga | 31 ++++++++++++++++++++++--------- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 12b3b75..b1a3914 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ *.html *.lha *.map +render000.c +render020.c + diff --git a/AF_readme b/AF_readme index 9d0520f..3752c4a 100644 --- a/AF_readme +++ b/AF_readme @@ -225,4 +225,7 @@ make all PREFIX=/here/or/there aufgerufen werden. dann wird (in alle Projekten) )ausgechecked, was am 18.Feb.2019 gueltig war. (auch, wenn es z.B. am 12.Jan. das letzte checkin/push gab) +15.Aug.2019 +----------- +Neues Target fuer Profiling. Der Linker hat gemeckert doppelte definitionen angemeckert. Anscheinend wird beim Profiling eine Variable mit dem Quellfilenamen angelegt. Bei uns wurde zwei mal render2.c benutz (fuer 68000 und 68020), damit gab es die Variable wohl doppelt. Deshalb kopiert das Makefile jetzt render2.c nach render000.c und render020.c und compiliert diese beiden temporaeren Quellen. Sie werden anschliessend geloescht. In .gitignore sind sie auch eingetragen. diff --git a/Makefile.amiga b/Makefile.amiga index ff2dd85..7f9dd71 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -53,6 +53,7 @@ COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc STRIP = $(COMPILER_DIR)/m68k-amigaos-strip GCOV = $(COMPILER_DIR)/m68k-amigaos-gcov +GPROF = $(COMPILER_DIR)/m68k-amigaos-gprof TOOLCHAIN_VER=$(shell cat $(COMPILER_DIR)/toolchain_commit.txt) @@ -83,8 +84,14 @@ ifneq ($(COVERAGE),) LFLAGS += -lgcov endif -#CFLAGS += -g -pg -fno-omit-frame-pointer -#LFLAGS += -pg +#profiling +ifneq ($(PROFILE),) +# CFLAGS += -fprofile-generate=VBox:$(shell pwd | cut -c2-) # remove first "/" from pwd -> VBox:home/... +# CFLAGS += -fprofile-arcs +# LFLAGS += -lgcov + CFLAGS += -g -pg -fno-omit-frame-pointer + LFLAGS += -pg +endif vpath sdlwrapper.c src/amiga/ @@ -108,10 +115,15 @@ strip: sam sync render000.o: src/render2.c - $(CC) $(CFLAGS) -O2 -c $< -o render000.o # this one is compiled with -O2 as it is the time critical part + cp src/render2.c src/render000.c + $(CC) $(CFLAGS) -O2 -c src/render000.c -o render000.o # this one is compiled with -O2 as it is the time critical part + rm src/render000.c render020.o: src/render2.c - $(CC) $(CFLAGS) -m68020 -O2 -c $< -o render020.o # this one is compiled with -O2 as it is the time critical part + cp src/render2.c src/render020.c + $(CC) $(CFLAGS) -m68020 -O2 -c src/render020.c -o render020.o # this one is compiled with -O2 as it is the time critical part + rm src/render020.c + %.o: src/%.c $(CC) $(CFLAGS) -c $< @@ -119,11 +131,7 @@ package: tar -cvzf sam.tar.gz README.md Makefile sing src/ clean: - rm -f *.o *.wav sam sam.map *.gcno *.gcda *.gcov coverage*.html - -archive: - rm -f sam_windows.zip - cd ..; zip SAM/sam_windows.zip SAM/sam.exe SAM/SDL.dll SAM/README.md SAM/demos/*.bat + rm -f *.o *.wav sam sam.map *.gcno *.gcda *.gcov gmon.out coverage*.html src/render000.c src/render020.c coverage: make -f Makefile.amiga COVERAGE=true @@ -135,6 +143,11 @@ coverage: # argument-loop must have been ececuted 3 times in our example. Red if string not found (|| nothing) or count <3, green if all OK cat main.c.gcov | (grep "while(i < argc)" || echo nothing) | awk -F: '{if( strtonum($$1) >=3){ print "\033[92mCoverage OK\033[0m";} else{ print "\033[91mCoverage failed!!!\033[0m"; exit 1;}}' +profile: + make -f Makefile.amiga PROFILE=true + vamos -V VBox:/home/developer/ -- sam -wav hello.wav "Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0" # start sam + ls -la gmon.out # check gmon.out has been created + $(GPROF) sam | awk '/RenderSample_000$$/{Count=$$4; if( strtonum(Count) ==55){ print "\033[92mProfile OK\033[0m";} else{ print "\033[91mProfile failed!!!\033[0m"; exit 1;}}' # profile output ok? RenderSample_000() should be called 55 times test: sam vamos -v -V VBox:/home/developer/ -- sam -wav hello.wav "Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0" # start sam From c70fff7ad45346bb0b25989535f07a8eba9fad8f Mon Sep 17 00:00:00 2001 From: githubaf Date: Thu, 22 Aug 2019 16:44:35 +0200 Subject: [PATCH 62/62] new compiler, coverage-test --- Makefile.amiga | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile.amiga b/Makefile.amiga index 7f9dd71..44a8c67 100644 --- a/Makefile.amiga +++ b/Makefile.amiga @@ -47,7 +47,11 @@ OBJS_ORDERED = reciter.o sam.o debug.o endian.o sdlwrapper.o portaudio_audev.o r # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_18May19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_26May19 # OK COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_30Jun19 -COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_07Aug19 +#COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_07Aug19 +# BAD Coverage geht nicht mehr COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_15Aug19 +# BAD Coverage geht nicht mehr COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_18Aug19 +# BAD Coverage geht nicht mehr +COMPILER_INSTALL_DIR ?= /home/developer/opt/m68k-amigaos_20Aug19 COMPILER_DIR = $(COMPILER_INSTALL_DIR)/bin CC = $(COMPILER_DIR)/m68k-amigaos-gcc #gcc @@ -138,7 +142,7 @@ coverage: find | grep gcno | wc --w > count.txt # 15 gcno-Files should have been created echo Found $$(cat count.txt) gcno-Files. [ $$(cat count.txt) = "15" ] || (echo Wrong number of gcno-Files!; exit 1) - vamos -V VBox:/home/developer/ -- sam -wav hello.wav "Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0" # start sam + vamos -s 100 -V VBox:/home/developer/ -- sam -wav hello.wav "Hello, my name is sam. 1 2 3 4 5 6 7 8 9 0" # start sam, -s -> coverage needs more stack $(GCOV) main.c # argument-loop must have been ececuted 3 times in our example. Red if string not found (|| nothing) or count <3, green if all OK cat main.c.gcov | (grep "while(i < argc)" || echo nothing) | awk -F: '{if( strtonum($$1) >=3){ print "\033[92mCoverage OK\033[0m";} else{ print "\033[91mCoverage failed!!!\033[0m"; exit 1;}}'