Quick and dirty Howto: make && tv/osmotv --sdr-soapy --sdr-tx-gain 60 -r 15000000 -c 21 tx-fubk --sdr-tune-args "OFFSET=-3000000"pull/1/head
parent
a52c89800c
commit
496aff5a79
@ -1,3 +1,3 @@ |
||||
AUTOMAKE_OPTIONS = foreign
|
||||
SUBDIRS = common anetz bnetz cnetz nmt amps tacs jtacs r2000 test
|
||||
SUBDIRS = common anetz bnetz cnetz nmt amps tacs jtacs r2000 tv test
|
||||
|
||||
|
@ -0,0 +1,388 @@ |
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
#include <stdlib.h> |
||||
#include "img.h" |
||||
|
||||
int save_depth = 16; |
||||
|
||||
#ifdef WITH_MAGICK |
||||
#include <magick/api.h> |
||||
|
||||
/* load given image to memory. return short RGB values */ |
||||
unsigned short *load_img(int *width, int *height, const char *filename, int index) |
||||
{ |
||||
Image *image = NULL; |
||||
ImageInfo *imageinfo = NULL; |
||||
ExceptionInfo exception; |
||||
unsigned short *img = NULL; |
||||
|
||||
MagickCoreGenesis(NULL, MagickFalse); |
||||
// InitializeMagick(NULL);
|
||||
imageinfo = CloneImageInfo(0); |
||||
GetExceptionInfo(&exception); |
||||
|
||||
sprintf(imageinfo->filename, filename, index); |
||||
|
||||
image = ReadImage(imageinfo, &exception); |
||||
if (!image) { |
||||
// printf("failed to read image '%s' via *magick\n", filename);
|
||||
goto exit; |
||||
} |
||||
|
||||
*width = image->columns; |
||||
*height = image->rows; |
||||
|
||||
img = (unsigned short *)malloc((*width) * (*height) * 3 * 2); |
||||
if (!img) { |
||||
printf("%s:failed to allocate image data\n", __func__); |
||||
goto exit; |
||||
} |
||||
|
||||
ExportImagePixels(image, 0, 0, *width, *height, "RGB", ShortPixel, img, NULL); |
||||
// DispatchImage(image, 0, 0, *width, *height, "RGB", ShortPixel, img, NULL);
|
||||
|
||||
exit: |
||||
if (image) |
||||
DestroyImage(image); |
||||
|
||||
if (imageinfo) |
||||
DestroyImageInfo(imageinfo); |
||||
|
||||
MagickCoreTerminus(); |
||||
// DestroyMagick();
|
||||
|
||||
return img; |
||||
} |
||||
|
||||
/* save given image */ |
||||
int save_img(unsigned short *img, int width, int height, int alpha, const char *filename, int index) |
||||
{ |
||||
int rc = -1; |
||||
Image *image = NULL; |
||||
ImageInfo *imageinfo = NULL; |
||||
ExceptionInfo exception; |
||||
|
||||
MagickCoreGenesis(NULL, MagickFalse); |
||||
// InitializeMagick(NULL);
|
||||
imageinfo = CloneImageInfo(0); |
||||
GetExceptionInfo(&exception); |
||||
|
||||
imageinfo->quality = 100; |
||||
if (strlen(filename) >= 4 && !strcmp(filename + strlen(filename) - 4, ".png")) |
||||
imageinfo->quality = 1; |
||||
|
||||
image=ConstituteImage(width, height, (alpha)?"RGBA":"RGB", ShortPixel, img, &exception); |
||||
if (!image) { |
||||
printf("%s:failed to prepare to write image\n", __func__); |
||||
goto exit; |
||||
} |
||||
|
||||
/* store as 16 bit, if lib and format supports it */ |
||||
image->depth = save_depth; |
||||
|
||||
sprintf(image->filename, filename, index); /* ACHTUNG: nicht imageinfo!!! */ |
||||
if (!WriteImage(imageinfo, image)) { |
||||
printf("%s:failed to write image\n", __func__); |
||||
goto exit; |
||||
} |
||||
|
||||
rc = 0; |
||||
|
||||
exit: |
||||
if (image) |
||||
DestroyImage(image); |
||||
|
||||
if (imageinfo) |
||||
DestroyImageInfo(imageinfo); |
||||
|
||||
MagickCoreTerminus(); |
||||
// DestroyMagick();
|
||||
|
||||
return rc; |
||||
} |
||||
#else |
||||
|
||||
/* load given image to memory. return short RGB values */ |
||||
unsigned short *load_img(int *width, int *height, const char *filename, int index) |
||||
{ |
||||
FILE *fp = NULL; |
||||
unsigned short *img = NULL; |
||||
char line[256]; |
||||
int words, i; |
||||
|
||||
sprintf(line, filename, index); |
||||
// printf("reading image: %s\n", line);
|
||||
fp = fopen(line, "r"); |
||||
if (!fp) { |
||||
// printf("failed to read ppm image '%s'\n", filename);
|
||||
goto exit; |
||||
} |
||||
again1: |
||||
if (!fgets(line, sizeof(line), fp)) { |
||||
printf("%s:failed to read image depth\n", __func__); |
||||
goto exit; |
||||
} |
||||
line[sizeof(line)-1] = '\0'; |
||||
if (line[0]) line[strlen(line)-1] = '\0'; |
||||
if (line[0] == '#') |
||||
goto again1; |
||||
if (!!strcmp(line, "P6")) { |
||||
printf("%s:expecting image depth 'P6'\n", __func__); |
||||
goto exit; |
||||
} |
||||
again2: |
||||
if (!fgets(line, sizeof(line), fp)) { |
||||
printf("%s:failed to read image size\n", __func__); |
||||
goto exit; |
||||
} |
||||
line[sizeof(line)-1] = '\0'; |
||||
if (line[0]) line[strlen(line)-1] = '\0'; |
||||
if (line[0] == '#') |
||||
goto again2; |
||||
sscanf(line, "%d %d", width, height); |
||||
// printf("Image size: w=%d h=%d\n", *width, *height);
|
||||
again3: |
||||
if (!fgets(line, sizeof(line), fp)) { |
||||
printf("%s:failed to read line '255' or '65535'\n", __func__); |
||||
goto exit; |
||||
} |
||||
line[sizeof(line)-1] = '\0'; |
||||
if (line[0]) line[strlen(line)-1] = '\0'; |
||||
if (line[0] == '#') |
||||
goto again3; |
||||
if (!strcmp(line, "255")) { |
||||
words = 1; |
||||
} else |
||||
if (!strcmp(line, "65535")) { |
||||
words = 2; |
||||
} else { |
||||
printf("%s:expecting line '255' or '65535'\n", __func__); |
||||
goto exit; |
||||
} |
||||
|
||||
img = (unsigned short *)malloc((*width) * (*height) * 3 * 2); |
||||
if (!img) { |
||||
printf("%s:failed to allocate image data\n", __func__); |
||||
goto exit; |
||||
} |
||||
if (fread(img, (*width) * (*height) * 3 * words, 1, fp) != 1) { |
||||
printf("%s:failed to read image data\n", __func__); |
||||
goto exit; |
||||
} |
||||
|
||||
/* char to short (255 -> 65535) */ |
||||
if (words == 1) { |
||||
unsigned char *from = (unsigned char *)img, c; |
||||
for (i = (*width) * (*height) * 3 - 1; i >= 0; i--) { |
||||
c = from[i]; |
||||
img[i] = (c << 8) | c; |
||||
} |
||||
} else { |
||||
/* correct byte order */ |
||||
unsigned short v; |
||||
unsigned char *from = (unsigned char *)img; |
||||
for (i = 0; i < (*width) * (*height) * 3; i++) { |
||||
v = ((*from++) << 8); |
||||
v |= (*from++); |
||||
img[i] = v; |
||||
} |
||||
} |
||||
|
||||
exit: |
||||
if (fp) |
||||
fclose(fp); |
||||
|
||||
return img; |
||||
} |
||||
|
||||
/* save given image */ |
||||
int save_img(unsigned short *img, int width, int height, int alpha, const char *filename, int index) |
||||
{ |
||||
FILE *fp = NULL; |
||||
int rc = -1; |
||||
char line[256]; |
||||
int i; |
||||
unsigned short v; |
||||
unsigned char *to; |
||||
|
||||
if (alpha) { |
||||
printf("%s:cannot save alpha component with PPM support only\n", __func__); |
||||
alpha = 0; |
||||
goto exit; |
||||
} |
||||
|
||||
sprintf(line, filename, index); |
||||
// printf("writing image: %s\n", line);
|
||||
fp = fopen(line, "w"); |
||||
if (!fp) { |
||||
printf("%s:failed to write image\n", __func__); |
||||
goto exit; |
||||
} |
||||
fprintf(fp, "P6\n%d %d\n65535\n", width, height); |
||||
|
||||
/* correct byte order, write and restore byte order */ |
||||
to = (unsigned char *)img; |
||||
for (i = 0; i < width * height * 3; i++) { |
||||
v = img[i]; |
||||
if (i/100*i == i) { printf("%04x ", v); } |
||||
(*to++) = v >> 8; |
||||
(*to++) = v; |
||||
} |
||||
rc = fwrite(img, width * height * 3 * 2, 1, fp); |
||||
to = (unsigned char *)img; |
||||
for (i = 0; i < width * height * 3; i++) { |
||||
v = (*to++) << 8; |
||||
v |= (*to++); |
||||
img[i] = v; |
||||
} |
||||
if (rc != 1) { |
||||
printf("%s:failed to write image data\n", __func__); |
||||
goto exit; |
||||
} |
||||
|
||||
rc = 0; |
||||
|
||||
exit: |
||||
if (fp) |
||||
fclose(fp); |
||||
|
||||
return rc; |
||||
} |
||||
#endif |
||||
|
||||
int save_img_array(double *array, int width, int height, int alpha, const char *filename, int index) |
||||
{ |
||||
int rc = -1; |
||||
unsigned short *img = NULL; |
||||
int components; |
||||
|
||||
#ifndef WITH_MAGICK |
||||
if (alpha) { |
||||
printf("%s:warning, cannot save alpha component with PPM support only\n", __func__); |
||||
alpha = 0; |
||||
} |
||||
#endif |
||||
components = (alpha) ? 4 : 3; |
||||
|
||||
img = (unsigned short *)malloc(width * height * components * 2); |
||||
if (!img) { |
||||
printf("%s:failed to allocate image data\n", __func__); |
||||
goto exit; |
||||
} |
||||
|
||||
array2img_short(array, width, height, img, width, height, alpha); |
||||
|
||||
save_img(img, width, height, alpha, filename, index); |
||||
|
||||
rc = 0; |
||||
|
||||
exit: |
||||
if (img) |
||||
free(img); |
||||
|
||||
return rc; |
||||
} |
||||
|
||||
/* convert an image to a three dimensional array of double
|
||||
* the size is: width, height, 3 |
||||
*/ |
||||
void img2array_short(unsigned short *img, int iw, int ih, double *array, int aw, int ah) |
||||
{ |
||||
int x, y; |
||||
int channel; |
||||
double r, g, b; |
||||
|
||||
channel = aw * ah; |
||||
|
||||
for (y = 0; y < ih; y++) { |
||||
for (x = 0; x < iw; x++) { |
||||
r = img[(x+iw*y)*3] / 65535.0F; |
||||
g = img[(x+iw*y)*3+1] / 65535.0F; |
||||
b = img[(x+iw*y)*3+2] / 65535.0F; |
||||
array[x+aw*y] = r; |
||||
array[x+aw*y+channel] = g; |
||||
array[x+aw*y+channel+channel] = b; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* convert a three dimensional array of double to an image
|
||||
* the size is: width, height, 3 |
||||
*/ |
||||
void array2img_short(double *array, int aw, int ah, unsigned short *img, int iw, int ih, int alpha) |
||||
{ |
||||
int x, y, c; |
||||
int channel, components; |
||||
double r, g, b, a; |
||||
|
||||
channel = aw * ah; |
||||
components = (alpha) ? 4 : 3; |
||||
|
||||
for (y = 0; y < ih; y++) { |
||||
for (x = 0; x < iw; x++) { |
||||
r = array[x+aw*y]; |
||||
c = (r * 65535.0F + 0.5F); |
||||
if (c < 0) |
||||
c = 0; |
||||
else if (c > 65535) |
||||
c = 65535; |
||||
img[(x+iw*y)*components] = c; |
||||
g = array[x+aw*y+channel]; |
||||
c = (g * 65535.0F + 0.5F); |
||||
if (c < 0) |
||||
c = 0; |
||||
else if (c > 65535) |
||||
c = 65535; |
||||
img[(x+iw*y)*components+1] = c; |
||||
b = array[x+aw*y+channel+channel]; |
||||
c = (b * 65535.0F + 0.5F); |
||||
if (c < 0) |
||||
c = 0; |
||||
else if (c > 65535) |
||||
c = 65535; |
||||
img[(x+iw*y)*components+2] = c; |
||||
if (alpha) { |
||||
a = array[x+aw*y+channel+channel+channel]; |
||||
c = (a * 65535.0F + 0.5F); |
||||
if (c < 0) |
||||
c = 0; |
||||
else if (c > 65535) |
||||
c = 65535; |
||||
img[(x+iw*y)*components+3] = c; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/*
|
||||
* scale down image in img_buffer by calculating average |
||||
*/ |
||||
void scale_img(unsigned short *img, int width, int height, int scale) |
||||
{ |
||||
int w, h, i, j, x, y; |
||||
int r, g, b; |
||||
|
||||
if (scale == 1) |
||||
return; |
||||
|
||||
w = width / scale; |
||||
h = height / scale; |
||||
|
||||
for (i = 0; i < h; i++) { |
||||
for (j = 0; j < w; j++) { |
||||
r = g = b = 0; |
||||
for (y = 0; y < scale; y++) { |
||||
for (x = 0; x < scale; x++) { |
||||
r += img[((i*scale+y) * width + j*scale+x) * 3 + 0]; |
||||
g += img[((i*scale+y) * width + j*scale+x) * 3 + 1]; |
||||
b += img[((i*scale+y) * width + j*scale+x) * 3 + 2]; |
||||
} |
||||
} |
||||
img[(i * w + j)*3 + 0] = r / scale / scale; |
||||
img[(i * w + j)*3 + 1] = g / scale / scale; |
||||
img[(i * w + j)*3 + 2] = b / scale / scale; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
@ -0,0 +1,7 @@ |
||||
extern int save_depth; |
||||
unsigned short *load_img(int *width, int *height, const char *filename, int index); |
||||
int save_img(unsigned short *img, int width, int height, int alpha, const char *filename, int index); |
||||
int save_img_array(double *array, int width, int height, int alpha, const char *filename, int index); |
||||
void img2array_short(unsigned short *img, int iw, int ih, double *array, int aw, int ah); |
||||
void array2img_short(double *array, int aw, int ah, unsigned short *img, int iw, int ih, int alpha); |
||||
void scale_img(unsigned short *img, int width, int height, int scale); |
@ -0,0 +1,40 @@ |
||||
AM_CPPFLAGS = -Wall -Wextra -g $(all_includes) -fstack-check
|
||||
|
||||
bin_PROGRAMS = \
|
||||
osmotv
|
||||
|
||||
osmotv_SOURCES = \
|
||||
bas.c \
|
||||
fubk.c \
|
||||
font.c \
|
||||
vcr.c \
|
||||
image.c \
|
||||
tv_modulate.c \
|
||||
channels.c \
|
||||
main.c
|
||||
osmotv_LDADD = \
|
||||
$(COMMON_LA) \
|
||||
$(top_builddir)/src/common/libimage.a \
|
||||
$(top_builddir)/src/common/libcommon.a \
|
||||
$(ALSA_LIBS) \
|
||||
$(UHD_LIBS) \
|
||||
$(SOAPY_LIBS) \
|
||||
$(GRAPHICSMAGICK_LIBS) $(IMAGEMAGICK_LIBS) \
|
||||
-lm
|
||||
|
||||
if HAVE_SDR |
||||
AM_CPPFLAGS += -DHAVE_SDR
|
||||
endif |
||||
|
||||
if HAVE_UHD |
||||
AM_CPPFLAGS += -DHAVE_UHD
|
||||
endif |
||||
|
||||
if HAVE_SOAPY |
||||
AM_CPPFLAGS += -DHAVE_SOAPY
|
||||
endif |
||||
|
||||
if ENABLE_MAGICK |
||||
AM_CPPFLAGS += -DWITH_MAGICK
|
||||
endif |
||||
|
@ -0,0 +1,284 @@ |
||||
/* generate a BAS signal
|
||||
* |
||||
* (C) 2017 by Andreas Eversberg <jolly@eversberg.eu> |
||||
* All Rights Reserved |
||||
* |
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#include <string.h> |
||||
#include <stdint.h> |
||||
#include <math.h> |
||||
#include "../common/sample.h" |
||||
#include "../common/iir_filter.h" |
||||
#include "bas.h" |
||||
#include "vcr.h" |
||||
#include "fubk.h" |
||||
#include "image.h" |
||||
|
||||
#define WHITE_LEVEL 1.0 |
||||
#define BLACK_LEVEL 0.32 |
||||
#define PORCH_LEVEL 0.3 |
||||
#define SYNC_LEVEL 0.0 |
||||
|
||||
#define H_SYNC_START 0.0000015 |
||||
#define H_SYNC_STOP 0.0000062 |
||||
#define H_LINE_START 0.000012 |
||||
#define H_LINE_END 0.000064 |
||||
#define H_SYNC2_START (H_SYNC_START + H_LINE_END/2.0) |
||||
#define H_SYNC2_STOP (H_SYNC_STOP + H_LINE_END/2.0) |
||||
#define V_SYNC_STOP (H_SYNC2_START - (H_SYNC_STOP - H_SYNC_START)) |
||||
#define V_SYNC2_STOP (H_SYNC_START - (H_SYNC_STOP - H_SYNC_START) + H_LINE_END) // wraps, so we substract H_LINE_END
|
||||
#define SYNC_RAMP 0.0000003 |
||||
#define IMAGE_RAMP 0.0000002 |
||||
#define H_CBURST_START 0.0000068 |
||||
#define H_CBURST_STOP 0.0000094 |
||||
#define COLOR_CARRIER 4433618.75 |
||||
#define COLOR_OFFSET 0.0000004 |
||||
#define BURST_AMPLITUDE 0.15 |
||||
#define COLOR_FILTER_ITER 1 |
||||
|
||||
void bas_init(bas_t *bas, double samplerate, enum bas_type type, int fbas, double circle_radius, int color_bar, int grid_only, const char *station_id, unsigned short *img, int width, int height) |
||||
{ |
||||
memset(bas, 0, sizeof(*bas)); |
||||
bas->samplerate = samplerate; |
||||
bas->type = type; |
||||
bas->fbas = fbas; |
||||
bas->v_polarity = 1; |
||||
bas->circle_radius = circle_radius; |
||||
bas->color_bar = color_bar; |
||||
bas->grid_only = grid_only; |
||||
bas->station_id = station_id; |
||||
bas->img = img; |
||||
bas->img_width = width; |
||||
bas->img_height = height; |
||||
|
||||
/* filter color signal */ |
||||
iir_lowpass_init(&bas->lp_u, 1300000.0, samplerate, COLOR_FILTER_ITER); |
||||
iir_lowpass_init(&bas->lp_v, 1300000.0, samplerate, COLOR_FILTER_ITER); |
||||
/* filter final FBAS, so we prevent from beeing in the audio carrier spectrum */ |
||||
iir_lowpass_init(&bas->lp_y, 4500000.0, samplerate, COLOR_FILTER_ITER); |
||||
} |
||||
|
||||
static inline double ramp(double x) |
||||
{ |
||||
return 0.5 - 0.5 * cos(x * M_PI); |
||||
} |
||||
|
||||
int bas_generate(bas_t *bas, sample_t *sample) |
||||
{ |
||||
double step = 1.0 / bas->samplerate; |
||||
int total_i = 0, i, c, line, middlefield_line; |
||||
double x = 0, render_start, render_end; |
||||
int have_image; |
||||
sample_t color_u[(int)(bas->samplerate / 15625.0) + 10]; |
||||
sample_t color_v[(int)(bas->samplerate / 15625.0) + 10]; |
||||
double _sin, _cos; |
||||
double color_step = COLOR_CARRIER / bas->samplerate * 2 * M_PI; |
||||
/* the offset is specified by delaying Y signal by 0.4 uS. */ |
||||
// additianlly we compensate the delay caused by the color filter, that is 2 samples per iteration */
|
||||
int color_offset = (int)(bas->samplerate * COLOR_OFFSET); // + 2 * COLOR_FILTER_ITER;
|
||||
|
||||
for (line = 0; line < 625; line++) { |
||||
/* reset color */ |
||||
memset(color_u, 0, sizeof(color_u)); |
||||
memset(color_v, 0, sizeof(color_v)); |
||||
|
||||
/* render image interlaced */ |
||||
have_image = 1; |
||||
/* switch off to have black image */ |
||||
#if 1 |
||||
if (line >= 24-1 && line <= 310-1) |
||||
middlefield_line = (line - (24-1)) * 2 + 1; |
||||
else if (line >= 336-1 && line <= 622-1) |
||||
middlefield_line = (line - (336-1)) * 2; |
||||
else |
||||
have_image = 0; |
||||
if (have_image) { |
||||
switch (bas->type) { |
||||
case BAS_FUBK: |
||||
/* render FUBK test image */ |
||||
fubk_gen_line(sample, x, bas->samplerate, color_u, color_v, bas->v_polarity, H_LINE_START, H_LINE_END, middlefield_line, bas->circle_radius, bas->color_bar, bas->grid_only, bas->station_id); |
||||
break; |
||||
case BAS_IMAGE: { |
||||
/* 574 lines of image are to be rendered */ |
||||
int img_line = middlefield_line - (574 - bas->img_height) / 2; |
||||
if (img_line >= 0 && img_line < bas->img_height) { |
||||
/* render image data */ |
||||
image_gen_line(sample, x, bas->samplerate, color_u, color_v, bas->v_polarity, H_LINE_START, H_LINE_END, bas->img + bas->img_width * img_line * 3, bas->img_width); |
||||
} |
||||
} |
||||
break; |
||||
case BAS_VCR: |
||||
/* render VCR test image */ |
||||
vcr_gen_line(sample, x, bas->samplerate, color_u, color_v, bas->v_polarity, H_LINE_START, H_LINE_END, middlefield_line / 2); |
||||
break; |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
i = 0; |
||||
|
||||
/* porch before sync */ |
||||
render_start = H_SYNC_START - SYNC_RAMP / 2; |
||||
while (x < render_start) { |
||||
sample[i++] = PORCH_LEVEL; |
||||
x += step; |
||||
} |
||||
/* ramp to sync level */ |
||||
render_end = render_start + SYNC_RAMP; |
||||
while (x < render_end) { |
||||
sample[i++] = ramp((x - render_start) / SYNC_RAMP) * (SYNC_LEVEL - PORCH_LEVEL) + PORCH_LEVEL; |
||||
x += step; |
||||
} |
||||
/* sync (long sync for vertical blank) */ |
||||
if (line <= 3-1 || line == 314-1 || line == 315-1) |
||||
render_start = V_SYNC_STOP - SYNC_RAMP / 2; |
||||
else |
||||
render_start = H_SYNC_STOP - SYNC_RAMP / 2; |
||||
while (x < render_start) { |
||||
sample[i++] = SYNC_LEVEL; |
||||
x += step; |
||||
} |
||||
/* ramp to porch level */ |
||||
render_end = render_start + SYNC_RAMP; |
||||
while (x < render_end) { |
||||
sample[i++] = ramp((x - render_start) / SYNC_RAMP) * (PORCH_LEVEL - SYNC_LEVEL) + SYNC_LEVEL; |
||||
x += step; |
||||
} |
||||
if (have_image) { |
||||
/* porch after sync, before color burst */ |
||||
render_start = H_CBURST_START; |
||||
while (x < render_start) { |
||||
sample[i++] = PORCH_LEVEL; |
||||
x += step; |
||||
} |
||||
/* porch after sync, color burst */ |
||||
render_start = H_CBURST_STOP; |
||||
while (x < render_start) { |
||||
/* shift color burst to the right, it is shifted back when modulating */ |
||||
color_u[i+color_offset] = -0.5 * BURST_AMPLITUDE; /* - 180 degrees */ |
||||
color_v[i+color_offset] = 0.5 * BURST_AMPLITUDE * (double)bas->v_polarity; /* +- 90 degrees */ |
||||
sample[i++] = PORCH_LEVEL; |
||||
x += step; |
||||
} |
||||
/* porch after sync, after color burst */ |
||||
render_start = H_LINE_START; |
||||
while (x < render_start) { |
||||
sample[i++] = PORCH_LEVEL; |
||||
x += step; |
||||
} |
||||
/* ramp to image */ |
||||
render_end = render_start + IMAGE_RAMP; |
||||
while (x < render_end) { |
||||
/* scale level of image to range of BAS signal */ |
||||
sample[i] = sample[i] * (WHITE_LEVEL - BLACK_LEVEL) + BLACK_LEVEL; |
||||
/* ramp from porch level to image level */ |
||||
sample[i] = ramp((x - render_start) / IMAGE_RAMP) * (sample[i] - PORCH_LEVEL) + PORCH_LEVEL; |
||||
i++; |
||||
x += step; |
||||
} |
||||
/* image */ |
||||
render_start = H_LINE_END - IMAGE_RAMP; |
||||
while (x < render_start) { |
||||
/* scale level of image to range of BAS signal */ |
||||
sample[i] = sample[i] * (WHITE_LEVEL - BLACK_LEVEL) + BLACK_LEVEL; |
||||
i++; |
||||
x += step; |
||||
} |
||||
/* ramp to porch level */ |
||||
render_end = H_LINE_END; |
||||
while (x < render_end) { |
||||
/* scale level of image to range of BAS signal */ |
||||
sample[i] = sample[i] * (WHITE_LEVEL - BLACK_LEVEL) + BLACK_LEVEL; |
||||
/* ramp from image level to porch level */ |
||||
sample[i] = ramp((x - render_start) / IMAGE_RAMP) * (PORCH_LEVEL - sample[i]) + sample[i]; |
||||
i++; |
||||
x += step; |
||||
} |
||||
} else { |
||||
/* draw porch to second sync */ |
||||
if (line <= 5-1 || (line >= 311-1 && line <= 317-1) || line >= 623-1) { |
||||
/* porch before sync */ |
||||
render_start = H_SYNC2_START - SYNC_RAMP / 2; |
||||
while (x < render_start) { |
||||
sample[i++] = PORCH_LEVEL; |
||||
x += step; |
||||
} |
||||
/* ramp to sync level */ |
||||
render_end = render_start + SYNC_RAMP; |
||||
while (x < render_end) { |
||||
sample[i++] = ramp((x - render_start) / SYNC_RAMP) * (SYNC_LEVEL - PORCH_LEVEL) + PORCH_LEVEL; |
||||
x += step; |
||||
} |
||||
/* sync (long sync for vertical blank) */ |
||||
if (line <= 2-1 || line == 313-1 || line == 314-1 || line == 315-1) |
||||
render_start = V_SYNC2_STOP - SYNC_RAMP / 2; |
||||
else |
||||
render_start = H_SYNC2_STOP - SYNC_RAMP / 2; |
||||
while (x < render_start) { |
||||
sample[i++] = SYNC_LEVEL; |
||||
x += step; |
||||
} |
||||
/* ramp to porch level */ |
||||
render_end = render_start + SYNC_RAMP; |
||||
while (x < render_end) { |
||||
sample[i++] = ramp((x - render_start) / SYNC_RAMP) * (PORCH_LEVEL - SYNC_LEVEL) + SYNC_LEVEL; |
||||
x += step; |
||||
} |
||||
} |
||||
/* porch to end of line */ |
||||
render_end = H_LINE_END; |
||||
while (x < render_end) { |
||||
sample[i++] = PORCH_LEVEL; |
||||
x += step; |
||||
} |
||||
} |
||||
|
||||
if (bas->fbas) { |
||||
/* filter color carrier */ |
||||
iir_process(&bas->lp_u, color_u, i); |
||||
iir_process(&bas->lp_v, color_v, i); |
||||
|
||||
/* modulate color to sample */ |
||||
bas->color_phase = fmod(bas->color_phase + color_step * (double)color_offset, 2.0 * M_PI); |
||||
for (c = color_offset; c < i; c++) { |
||||
bas->color_phase += color_step; |
||||
if (bas->color_phase >= 2.0 * M_PI) |
||||
bas->color_phase -= 2.0 * M_PI; |
||||
_sin = sin(bas->color_phase); |
||||
_cos = cos(bas->color_phase); |
||||
sample[c-color_offset] += color_u[c] * _cos - color_v[c] * _sin; |
||||
sample[c-color_offset] += color_u[c] * _sin + color_v[c] * _cos; |
||||
// puts(debug_amplitude(sample[c-color_offset]));
|
||||
} |
||||
|
||||
/* filter bas signal */ |
||||
iir_process(&bas->lp_y, sample, i); |
||||
} |
||||
|
||||
/* flip polarity of V signal */ |
||||
bas->v_polarity = -bas->v_polarity; |
||||
|
||||
/* increment sample buffer to next line */ |
||||
sample += i; |
||||
/* return x */ |
||||
x -= H_LINE_END; |
||||
/* sum total i */ |
||||
total_i += i; |
||||
} |
||||
|
||||
return total_i; |
||||
} |
||||
|
@ -0,0 +1,25 @@ |
||||
|
||||
enum bas_type { |
||||
BAS_FUBK, |
||||
BAS_VCR, |
||||
BAS_IMAGE, |
||||
}; |
||||
|
||||
typedef struct bas { |
||||
double samplerate; |
||||
enum bas_type type; |
||||
int fbas; /* if color shall be added */ |
||||
double circle_radius; /* radius of circle in grid units */ |
||||
int color_bar; /* show only color bar on all lines */ |
||||
int grid_only; /* show only the grid */ |
||||
const char *station_id; /* text to display as station id */ |
||||
double color_phase; /* current phase of color carrier */ |
||||
int v_polarity; /* polarity of V color vector */ |
||||
unsigned short *img; /* image data, if it should be used */ |
||||
int img_width, img_height; /* size of image */ |
||||
iir_filter_t lp_y, lp_u, lp_v; /* low pass filters */ |
||||
} bas_t; |
||||
|
||||
void bas_init(bas_t *bas, double samplerate, enum bas_type type, int fbas, double circle_radius, int color_bar, int grid_only, const char *station_id, unsigned short *img, int width, int height); |
||||
int bas_generate(bas_t *bas, sample_t *sample); |
||||
|
@ -0,0 +1,94 @@ |
||||
#include <stdio.h> |
||||
|
||||
static struct tv_channels { |
||||
int channel; |
||||
double video_mhz; |
||||
double audio_mhz; |
||||
} tv_channels[] = { |
||||
{ 1, 41.25, 46.75 }, |
||||
{ 2, 48.25, 53.75 }, |
||||
{ 3, 55.25, 60.75 }, |
||||
{ 4, 62.25, 67.75 }, |
||||
{ 5, 175.25, 180.75 }, |
||||
{ 6, 182.25, 187.75 }, |
||||
{ 7, 189.25, 194.75 }, |
||||
{ 8, 196.25, 201.75 }, |
||||
{ 9, 203.25, 208.75 }, |
||||
{ 10, 210.25, 215.75 }, |
||||
{ 11, 217.25, 222.75 }, |
||||
{ 12, 224.25, 229.75 }, |
||||
{ 21, 471.25, 476.75 }, |
||||
{ 22, 479.25, 484.75 }, |
||||
{ 23, 487.25, 492.75 }, |
||||
{ 24, 495.25, 500.75 }, |
||||
{ 25, 503.25, 508.75 }, |
||||
{ 26, 511.25, 516.75 }, |
||||
{ 27, 519.25, 524.75 }, |
||||
{ 28, 527.25, 532.75 }, |
||||
{ 29, 535.25, 540.75 }, |
||||
{ 30, 543.25, 548.75 }, |
||||
{ 31, 551.25, 556.75 }, |
||||
{ 32, 559.25, 564.75 }, |
||||
{ 33, 567.25, 572.75 }, |
||||
{ 34, 575.25, 580.75 }, |
||||
{ 35, 583.25, 588.75 }, |
||||
{ 36, 591.25, 596.75 }, |
||||
{ 37, 599.25, 604.75 }, |
||||
{ 38, 607.25, 612.75 }, |
||||
{ 39, 615.25, 620.75 }, |
||||
{ 40, 623.25, 628.75 }, |
||||
{ 41, 631.25, 636.75 }, |
||||
{ 42, 639.25, 644.75 }, |
||||
{ 43, 647.25, 652.75 }, |
||||
{ 44, 655.25, 660.75 }, |
||||
{ 45, 663.25, 668.75 }, |
||||
{ 46, 671.25, 676.75 }, |
||||
{ 47, 679.25, 684.75 }, |
||||
{ 48, 687.25, 692.75 }, |
||||
{ 49, 695.25, 700.75 }, |
||||
{ 50, 703.25, 708.75 }, |
||||
{ 51, 711.25, 716.75 }, |
||||
{ 52, 719.25, 724.75 }, |
||||
{ 53, 727.25, 732.75 }, |
||||
{ 54, 735.25, 740.75 }, |
||||
{ 55, 743.25, 748.75 }, |
||||
{ 56, 751.25, 756.75 }, |
||||
{ 57, 759.25, 764.75 }, |
||||
{ 58, 767.25, 772.75 }, |
||||
{ 59, 775.25, 780.75 }, |
||||
{ 60, 783.25, 788.75 }, |
||||
{ 61, 791.25, 796.75 }, |
||||
{ 62, 799.25, 804.75 }, |
||||
{ 63, 807.25, 812.75 }, |
||||
{ 64, 815.25, 820.75 }, |
||||
{ 65, 823.25, 828.75 }, |
||||
{ 66, 831.25, 836.75 }, |
||||
{ 67, 839.25, 844.75 }, |
||||
{ 68, 847.25, 852.75 }, |
||||
{ 69, 855.25, 860.75 }, |
||||
{ 0, 0, 0, } |
||||
}; |
||||
|
||||
double get_tv_video_frequency(int channel) |
||||
{ |
||||
int i; |
||||
|
||||
for (i = 0; tv_channels[i].channel; i++) { |
||||
if (tv_channels[i].channel == channel) |
||||
return tv_channels[i].video_mhz * 1e6; |
||||
} |
||||
|
||||
return 0.0; |
||||
} |
||||
|
||||
void list_tv_channels(void) |
||||
{ |
||||
int i; |
||||
|
||||
printf("List of TV channels in MHz:\n\n"); |
||||
printf("Channel Video Audio\n"); |
||||
printf("------------------------\n"); |
||||
for (i = 0; tv_channels[i].channel; i++) { |
||||
printf("%d\t%.2f\t%.2f\n", tv_channels[i].channel, tv_channels[i].video_mhz, tv_channels[i].audio_mhz); |
||||
} |
||||
} |
@ -0,0 +1,4 @@ |
||||
|
||||
double get_tv_video_frequency(int channel); |
||||
void list_tv_channels(void); |
||||
|
@ -0,0 +1,877 @@ |
||||
#include <stdint.h> |
||||
#include "font.h" |
||||
|
||||
static const uint8_t font_c64_data[] = { |
||||
/* --- new character ' ' (32) */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '!' (33) */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x18, /* ...##... */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '"' (34) */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '#' (35) */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0xff, /* ######## */ |
||||
0x66, /* .##..##. */ |
||||
0xff, /* ######## */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '$' (36) */ |
||||
0x18, /* ...##... */ |
||||
0x3e, /* ..#####. */ |
||||
0x60, /* .##..... */ |
||||
0x3c, /* ..####.. */ |
||||
0x06, /* .....##. */ |
||||
0x7c, /* .#####.. */ |
||||
0x18, /* ...##... */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '%' (37) */ |
||||
0x62, /* .##...#. */ |
||||
0x66, /* .##..##. */ |
||||
0x0c, /* ....##.. */ |
||||
0x18, /* ...##... */ |
||||
0x30, /* ..##.... */ |
||||
0x66, /* .##..##. */ |
||||
0x46, /* .#...##. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '&' (38) */ |
||||
0x3c, /* ..####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x3c, /* ..####.. */ |
||||
0x38, /* ..###... */ |
||||
0x67, /* .##..### */ |
||||
0x66, /* .##..##. */ |
||||
0x3f, /* ..###### */ |
||||
0x00, /* ........ */ |
||||
/* --- new character ''' (39) */ |
||||
0x06, /* .....##. */ |
||||
0x0c, /* ....##.. */ |
||||
0x18, /* ...##... */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '(' (40) */ |
||||
0x0c, /* ....##.. */ |
||||
0x18, /* ...##... */ |
||||
0x30, /* ..##.... */ |
||||
0x30, /* ..##.... */ |
||||
0x30, /* ..##.... */ |
||||
0x18, /* ...##... */ |
||||
0x0c, /* ....##.. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character ')' (41) */ |
||||
0x30, /* ..##.... */ |
||||
0x18, /* ...##... */ |
||||
0x0c, /* ....##.. */ |
||||
0x0c, /* ....##.. */ |
||||
0x0c, /* ....##.. */ |
||||
0x18, /* ...##... */ |
||||
0x30, /* ..##.... */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '*' (42) */ |
||||
0x00, /* ........ */ |
||||
0x66, /* .##..##. */ |
||||
0x3c, /* ..####.. */ |
||||
0xff, /* ######## */ |
||||
0x3c, /* ..####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '+' (43) */ |
||||
0x00, /* ........ */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x7e, /* .######. */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
/* --- new character ',' (44) */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x30, /* ..##.... */ |
||||
/* --- new character '-' (45) */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x7e, /* .######. */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '.' (46) */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '/' (47) */ |
||||
0x00, /* ........ */ |
||||
0x03, /* ......## */ |
||||
0x06, /* .....##. */ |
||||
0x0c, /* ....##.. */ |
||||
0x18, /* ...##... */ |
||||
0x30, /* ..##.... */ |
||||
0x60, /* .##..... */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '0' (48) */ |
||||
0x3c, /* ..####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x6e, /* .##.###. */ |
||||
0x76, /* .###.##. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x3c, /* ..####.. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '1' (49) */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x38, /* ..###... */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x7e, /* .######. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '2' (50) */ |
||||
0x3c, /* ..####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x06, /* .....##. */ |
||||
0x0c, /* ....##.. */ |
||||
0x30, /* ..##.... */ |
||||
0x60, /* .##..... */ |
||||
0x7e, /* .######. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '3' (51) */ |
||||
0x3c, /* ..####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x06, /* .....##. */ |
||||
0x1c, /* ...###.. */ |
||||
0x06, /* .....##. */ |
||||
0x66, /* .##..##. */ |
||||
0x3c, /* ..####.. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '4' (52) */ |
||||
0x06, /* .....##. */ |
||||
0x0e, /* ....###. */ |
||||
0x1e, /* ...####. */ |
||||
0x66, /* .##..##. */ |
||||
0x7f, /* .####### */ |
||||
0x06, /* .....##. */ |
||||
0x06, /* .....##. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '5' (53) */ |
||||
0x7e, /* .######. */ |
||||
0x60, /* .##..... */ |
||||
0x7c, /* .#####.. */ |
||||
0x06, /* .....##. */ |
||||
0x06, /* .....##. */ |
||||
0x66, /* .##..##. */ |
||||
0x3c, /* ..####.. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '6' (54) */ |
||||
0x3c, /* ..####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x60, /* .##..... */ |
||||
0x7c, /* .#####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x3c, /* ..####.. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '7' (55) */ |
||||
0x7e, /* .######. */ |
||||
0x66, /* .##..##. */ |
||||
0x0c, /* ....##.. */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '8' (56) */ |
||||
0x3c, /* ..####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x3c, /* ..####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x3c, /* ..####.. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '9' (57) */ |
||||
0x3c, /* ..####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x3e, /* ..#####. */ |
||||
0x06, /* .....##. */ |
||||
0x66, /* .##..##. */ |
||||
0x3c, /* ..####.. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character ':' (58) */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x18, /* ...##... */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x18, /* ...##... */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
/* --- new character ';' (59) */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x18, /* ...##... */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x30, /* ..##.... */ |
||||
/* --- new character '<' (60) */ |
||||
0x0e, /* ....###. */ |
||||
0x18, /* ...##... */ |
||||
0x30, /* ..##.... */ |
||||
0x60, /* .##..... */ |
||||
0x30, /* ..##.... */ |
||||
0x18, /* ...##... */ |
||||
0x0e, /* ....###. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '=' (61) */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x7e, /* .######. */ |
||||
0x00, /* ........ */ |
||||
0x7e, /* .######. */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '>' (62) */ |
||||
0x70, /* .###.... */ |
||||
0x18, /* ...##... */ |
||||
0x0c, /* ....##.. */ |
||||
0x06, /* .....##. */ |
||||
0x0c, /* ....##.. */ |
||||
0x18, /* ...##... */ |
||||
0x70, /* .###.... */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '?' (63) */ |
||||
0x3c, /* ..####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x06, /* .....##. */ |
||||
0x0c, /* ....##.. */ |
||||
0x18, /* ...##... */ |
||||
0x00, /* ........ */ |
||||
0x18, /* ...##... */ |
||||
0x00, /* ........ */ |
||||
/* --- new character '@' (64) */ |
||||
0x3c, /* ..####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x6e, /* .##.###. */ |
||||
0x6e, /* .##.###. */ |
||||
0x60, /* .##..... */ |
||||
0x62, /* .##...#. */ |
||||
0x3c, /* ..####.. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character 'A' (65) */ |
||||
0x18, /* ...##... */ |
||||
0x3c, /* ..####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x7e, /* .######. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character 'B' (66) */ |
||||
0x7c, /* .#####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x7c, /* .#####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x7c, /* .#####.. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character 'C' (67) */ |
||||
0x3c, /* ..####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x60, /* .##..... */ |
||||
0x60, /* .##..... */ |
||||
0x60, /* .##..... */ |
||||
0x66, /* .##..##. */ |
||||
0x3c, /* ..####.. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character 'D' (68) */ |
||||
0x78, /* .####... */ |
||||
0x6c, /* .##.##.. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x6c, /* .##.##.. */ |
||||
0x78, /* .####... */ |
||||
0x00, /* ........ */ |
||||
/* --- new character 'E' (69) */ |
||||
0x7e, /* .######. */ |
||||
0x60, /* .##..... */ |
||||
0x60, /* .##..... */ |
||||
0x78, /* .####... */ |
||||
0x60, /* .##..... */ |
||||
0x60, /* .##..... */ |
||||
0x7e, /* .######. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character 'F' (70) */ |
||||
0x7e, /* .######. */ |
||||
0x60, /* .##..... */ |
||||
0x60, /* .##..... */ |
||||
0x78, /* .####... */ |
||||
0x60, /* .##..... */ |
||||
0x60, /* .##..... */ |
||||
0x60, /* .##..... */ |
||||
0x00, /* ........ */ |
||||
/* --- new character 'G' (71) */ |
||||
0x3c, /* ..####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x60, /* .##..... */ |
||||
0x6e, /* .##.###. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x3c, /* ..####.. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character 'H' (72) */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x7e, /* .######. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character 'I' (73) */ |
||||
0x3c, /* ..####.. */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x18, /* ...##... */ |
||||
0x3c, /* ..####.. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character 'J' (74) */ |
||||
0x1e, /* ...####. */ |
||||
0x0c, /* ....##.. */ |
||||
0x0c, /* ....##.. */ |
||||
0x0c, /* ....##.. */ |
||||
0x0c, /* ....##.. */ |
||||
0x6c, /* .##.##.. */ |
||||
0x38, /* ..###... */ |
||||
0x00, /* ........ */ |
||||
/* --- new character 'K' (75) */ |
||||
0x66, /* .##..##. */ |
||||
0x6c, /* .##.##.. */ |
||||
0x78, /* .####... */ |
||||
0x70, /* .###.... */ |
||||
0x78, /* .####... */ |
||||
0x6c, /* .##.##.. */ |
||||
0x66, /* .##..##. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character 'L' (76) */ |
||||
0x60, /* .##..... */ |
||||
0x60, /* .##..... */ |
||||
0x60, /* .##..... */ |
||||
0x60, /* .##..... */ |
||||
0x60, /* .##..... */ |
||||
0x60, /* .##..... */ |
||||
0x7e, /* .######. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character 'M' (77) */ |
||||
0x63, /* .##...## */ |
||||
0x77, /* .###.### */ |
||||
0x7f, /* .####### */ |
||||
0x6b, /* .##.#.## */ |
||||
0x63, /* .##...## */ |
||||
0x63, /* .##...## */ |
||||
0x63, /* .##...## */ |
||||
0x00, /* ........ */ |
||||
/* --- new character 'N' (78) */ |
||||
0x66, /* .##..##. */ |
||||
0x76, /* .###.##. */ |
||||
0x7e, /* .######. */ |
||||
0x7e, /* .######. */ |
||||
0x6e, /* .##.###. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character 'O' (79) */ |
||||
0x3c, /* ..####.. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x66, /* .##..##. */ |
||||
0x3c, /* ..####.. */ |
||||
0x00, /* ........ */ |
||||
/* --- new character 'P' (80) */ |
||||