pax_global_header00006660000000000000000000000064133757747040014533gustar00rootroot0000000000000052 comment=8d572e6f8ef72b78191c6c3fbb5ae296e6dea3d9 rem-0.6.0/000077500000000000000000000000001337577470400123215ustar00rootroot00000000000000rem-0.6.0/.gitignore000066400000000000000000000000671337577470400143140ustar00rootroot00000000000000build* test* librem.a librem.dylib librem.pc librem.so rem-0.6.0/.travis.yml000066400000000000000000000005551337577470400144370ustar00rootroot00000000000000language: c before_install: - sudo apt-get -qq update - sudo apt-get -y install libssl-dev install: - git clone https://github.com/creytiv/re.git - cd re && make && sudo make install && cd .. - sudo ldconfig - wget "https://github.com/alfredh/pytools/raw/master/ccheck.py" script: - make EXTRA_CFLAGS=-Werror - python2 ccheck.py rem-0.6.0/Makefile000066400000000000000000000063721337577470400137710ustar00rootroot00000000000000# # Makefile # # Copyright (C) 2010 Creytiv.com # # Master version number VER_MAJOR := 0 VER_MINOR := 6 VER_PATCH := 0 PROJECT := rem VERSION := $(VER_MAJOR).$(VER_MINOR).$(VER_PATCH) OPT_SPEED := 1 LIBRE_MK := $(shell [ -f ../re/mk/re.mk ] && \ echo "../re/mk/re.mk") ifeq ($(LIBRE_MK),) LIBRE_MK := $(shell [ -f /usr/share/re/re.mk ] && \ echo "/usr/share/re/re.mk") endif ifeq ($(LIBRE_MK),) LIBRE_MK := $(shell [ -f /usr/local/share/re/re.mk ] && \ echo "/usr/local/share/re/re.mk") endif include $(LIBRE_MK) # List of modules MODULES += fir goertzel MODULES += g711 MODULES += aubuf aufile auresamp autone dtmf MODULES += au auconv ifneq ($(HAVE_LIBPTHREAD),) MODULES += aumix vidmix endif MODULES += vid vidconv MODULES += avc LIBS += -lm INSTALL := install ifeq ($(DESTDIR),) PREFIX := /usr/local else PREFIX := /usr endif ifeq ($(LIBDIR),) LIBDIR := $(PREFIX)/lib endif INCDIR := $(PREFIX)/include/rem CFLAGS += -I$(LIBRE_INC) -Iinclude # XXX ifneq ($(HAVE_ARMV6),) CFLAGS += -DHAVE_ARMV6=1 endif ifneq ($(HAVE_NEON),) CFLAGS += -DHAVE_NEON=1 endif MODMKS := $(patsubst %,src/%/mod.mk,$(MODULES)) SHARED := librem$(LIB_SUFFIX) STATIC := librem.a include $(MODMKS) OBJS ?= $(patsubst %.c,$(BUILD)/%.o,$(filter %.c,$(SRCS))) OBJS += $(patsubst %.S,$(BUILD)/%.o,$(filter %.S,$(SRCS))) all: $(SHARED) $(STATIC) -include $(OBJS:.o=.d) $(SHARED): $(OBJS) @echo " LD $@" @$(LD) $(LFLAGS) $(SH_LFLAGS) $^ -L$(LIBRE_SO) -lre $(LIBS) -o $@ $(STATIC): $(OBJS) @echo " AR $@" @$(AR) $(AFLAGS) $@ $^ ifneq ($(RANLIB),) @$(RANLIB) $@ endif librem.pc: @echo 'prefix='$(PREFIX) > librem.pc @echo 'exec_prefix=$${prefix}' >> librem.pc @echo 'libdir=$${prefix}/lib' >> librem.pc @echo 'includedir=$${prefix}/include/rem' >> librem.pc @echo '' >> librem.pc @echo 'Name: librem' >> librem.pc @echo 'Description: Audio and video processing media library' \ >> librem.pc @echo 'Version: '$(VERSION) >> librem.pc @echo 'URL: http://creytiv.com/rem.html' >> librem.pc @echo 'Libs: -L$${libdir} -lrem -lre' >> librem.pc @echo 'Cflags: -I$${includedir}' >> librem.pc $(BUILD)/%.o: src/%.c $(BUILD) Makefile $(MK) $(MODMKS) @echo " CC $@" @$(CC) $(CFLAGS) -c $< -o $@ $(DFLAGS) $(BUILD)/%.o: src/%.S $(BUILD) Makefile $(MK) $(MODMKS) @echo " AS $@" @$(CC) $(CFLAGS) -c $< -o $@ $(DFLAGS) $(BUILD): Makefile $(MK) $(MODMKS) @mkdir -p $(patsubst %,$(BUILD)/%,$(sort $(dir $(SRCS)))) @touch $@ .PHONY: clean clean: @rm -rf $(SHARED) $(STATIC) librem.pc test.d test.o test $(BUILD) install: $(SHARED) $(STATIC) librem.pc @mkdir -p $(DESTDIR)$(LIBDIR) $(DESTDIR)$(LIBDIR)/pkgconfig \ $(DESTDIR)$(INCDIR) $(INSTALL) -m 0644 $(shell find include -name "*.h") \ $(DESTDIR)$(INCDIR) $(INSTALL) -m 0755 $(SHARED) $(DESTDIR)$(LIBDIR) $(INSTALL) -m 0755 $(STATIC) $(DESTDIR)$(LIBDIR) $(INSTALL) -m 0644 librem.pc $(DESTDIR)$(LIBDIR)/pkgconfig .PHONY: uninstall uninstall: @rm -rf $(DESTDIR)$(INCDIR) @rm -f $(DESTDIR)$(LIBDIR)/$(SHARED) @rm -f $(DESTDIR)$(LIBDIR)/$(STATIC) @rm -f $(DESTDIR)$(LIBDIR)/pkgconfig/librem.pc -include test.d test.o: test.c @echo " CC $@" @$(CC) $(CFLAGS) -c $< -o $@ $(DFLAGS) test$(BIN_SUFFIX): test.o $(SHARED) $(STATIC) @echo " LD $@" @$(LD) $(LFLAGS) $< -L. -lrem -lre $(LIBS) -o $@ rem-0.6.0/README.md000066400000000000000000000047451337577470400136120ustar00rootroot00000000000000librem README ============= librem is a Audio and video processing media library Copyright (C) 2010 - 2018 Creytiv.com [![Build Status](https://travis-ci.org/creytiv/rem.svg?branch=master)](https://travis-ci.org/creytiv/rem) ## Features * Audio buffer * Audio sample format conversion * Audio file reader/writer * Audio mixer * Audio resampler * Audio tone generator * Audio codec (G.711) * DTMF decoder * Video mixer * Video pixel converter * FIR-filter ## Building librem is using GNU makefiles, and [libre](https://github.com/creytiv/re) must be installed before building. ### Build with default options ``` $ make $ sudo make install $ sudo ldconfig ``` ## Documentation The online documentation generated with doxygen is available in the main [website](http://creytiv.com/doxygen/rem-dox/html/) ## License The librem project is using the BSD license. ## Contributing Patches can sent via Github [Pull-Requests](https://github.com/creytiv/rem/pulls) or to the RE devel [mailing-list](http://lists.creytiv.com/mailman/listinfo/re-devel). Currently we only accept small patches. Please send private feedback to libre [at] creytiv.com ## Modules ``` Audio Modules: name: status: description: * au testing Base audio types * aubuf testing Audio buffer * auconv unstable Audio sample format conversion * aufile testing Audio file reader/writer * aumix unstable Audio mixer * auresamp unstable Audio resampler * autone testing Tone/DTMF generator * dtmf unstable DTMF decoder * g711 stable G.711 audio codec Video Modules: name: status: description: * avc unstable Advanced Video Coding (AVC) * vid testing Base video types * vidconv testing Colorspace conversion and scaling * vidmix unstable Video mixer Generic modules: * dsp testing DSP routines * flv unstable Flash Video File Format * fir unstable FIR (Finite Impulse Response) filter * goertzel unstable Goertzel Algorithm ``` ## Specifications: * ITU-T G.711 Appendix I and Appendix II ## Supported platforms Same as [libre](https://github.com/creytiv/re) ## Related projects * [libre](https://github.com/creytiv/re) * [retest](https://github.com/creytiv/retest) * [baresip](https://github.com/alfredh/baresip) ## References http://creytiv.com/rem.html https://github.com/creytiv/rem http://lists.creytiv.com/mailman/listinfo/re-devel rem-0.6.0/debian/000077500000000000000000000000001337577470400135435ustar00rootroot00000000000000rem-0.6.0/debian/changelog000066400000000000000000000045301337577470400154170ustar00rootroot00000000000000librem (0.6.0) unstable; urgency=medium * version 0.6.0 -- Alfred E. Heggestad Sat, 24 Nov 2018 10:00:00 +0100 librem (0.5.3) unstable; urgency=medium * version 0.5.3 -- Alfred E. Heggestad Fri, 20 Apr 2018 16:00:00 +0200 librem (0.5.2) unstable; urgency=medium * version 0.5.2 -- Alfred E. Heggestad Sat, 23 Sep 2017 12:00:00 +0200 librem (0.5.1) unstable; urgency=medium * version 0.5.1 -- Alfred E. Heggestad Sat, 8 Apr 2017 12:00:00 +0200 librem (0.5.0) unstable; urgency=medium * version 0.5.0 -- Alfred E. Heggestad Fri, 2 Dec 2016 20:00:00 +0100 librem (0.4.7) unstable; urgency=low * version 0.4.7 -- Alfred E. Heggestad Sun, 13 Dec 2016 16:00:00 +0100 librem (0.4.6-4) unstable; urgency=low * version 0.4.6-4 -- Richard Aas Tue, 2 Sep 2015 13:56:00 +0100 librem (0.4.6-3) unstable; urgency=low * version 0.4.6-3 -- Richard Aas Tue, 18 Aug 2015 08:55:00 +0100 librem (0.4.6-2) unstable; urgency=low * version 0.4.6-2 -- Richard Aas Tue, 13 Jan 2015 13:24:00 +0100 librem (0.4.6-1) unstable; urgency=low * version 0.4.6-1 -- Richard Aas Mon, 17 Nov 2014 09:09:00 +0100 librem (0.4.6) unstable; urgency=low * version 0.4.6 -- Alfred E. Heggestad Sun, 18 May 2014 16:00:00 +0100 librem (0.4.5) unstable; urgency=low * version 0.4.5 -- Alfred E. Heggestad Mon, 6 Jan 2014 16:00:00 +0100 librem (0.4.4) unstable; urgency=low * version 0.4.4 -- Alfred E. Heggestad Thu, 3 Oct 2013 20:00:00 +0100 librem (0.4.3) unstable; urgency=low * version 0.4.3 -- Alfred E. Heggestad Sun, 5 May 2013 15:00:00 +0100 librem (0.4.2) unstable; urgency=low * version 0.4.2 -- Alfred E. Heggestad Sun, 9 Sept 2012 09:09:00 +0100 librem (0.4.1) unstable; urgency=low * version 0.4.1 -- Alfred E. Heggestad Sat, 21 Apr 2012 21:04:00 +0100 librem (0.4.0) unstable; urgency=low * version 0.4.0 -- Alfred E. Heggestad Sun, 25 Dec 2011 12:25:00 +0100 librem (0.3.0) unstable; urgency=low * version 0.3.0 -- Alfred E. Heggestad Wed, 7 Sept 2011 07:11:00 +0100 rem-0.6.0/debian/compat000066400000000000000000000000021337577470400147410ustar00rootroot000000000000009 rem-0.6.0/debian/control000066400000000000000000000012741337577470400151520ustar00rootroot00000000000000Source: librem Section: comm Priority: optional Maintainer: Alfred E. Heggestad Standards-Version: 3.9.5 Build-Depends: debhelper (>= 9.20120311), libre-dev (>= 0.6.0) Homepage: http://www.creytiv.com/ Package: librem Architecture: any Section: libs Depends: libre (>= 0.6.0), ${shlibs:Depends}, ${misc:Depends} Description: Audio and video processing media library Audio mixer, resampler, tone generator, G.711 codec Video mixer, pixel converter Package: librem-dev Architecture: any Section: libdevel Depends: librem (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: Audio and video processing media library (development files) Development package for librem rem-0.6.0/debian/copyright000066400000000000000000000031611337577470400154770ustar00rootroot00000000000000This package was debianized by Alfred E. Heggestad It was downloaded from http://www.creytiv.com/ Copyright (c) 2010 - 2014, Alfred E. Heggestad Copyright (c) 2010 - 2014, Richard Aas Copyright (c) 2010 - 2014, Creytiv.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the Creytiv.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. rem-0.6.0/debian/docs000066400000000000000000000000121337577470400144070ustar00rootroot00000000000000README.md rem-0.6.0/debian/librem-dev.dirs000066400000000000000000000000241337577470400164500ustar00rootroot00000000000000usr/include usr/lib rem-0.6.0/debian/librem-dev.files000066400000000000000000000000351337577470400166130ustar00rootroot00000000000000usr/include usr/lib/librem.a rem-0.6.0/debian/librem.dirs000066400000000000000000000000101337577470400156670ustar00rootroot00000000000000usr/lib rem-0.6.0/debian/librem.files000066400000000000000000000000231337577470400160340ustar00rootroot00000000000000/usr/lib/librem.so rem-0.6.0/debian/rules000077500000000000000000000037751337577470400146370ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 EXTRA_CFLAGS:="$(shell dpkg-buildflags --get CFLAGS | sed -e 's/-O2//')" EXTRA_LFLAGS:="$(shell dpkg-buildflags --get LDFLAGS) -Wl,-soname,librem.so" configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. touch configure-stamp build: build-stamp build-stamp: configure-stamp dh_testdir # Add here commands to compile the package. $(MAKE) RELEASE=1 \ EXTRA_CFLAGS=$(EXTRA_CFLAGS) \ EXTRA_LFLAGS=$(EXTRA_LFLAGS) touch $@ clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp # Add here commands to clean up after the build process. $(MAKE) clean dh_clean install: build dh_testdir dh_testroot dh_prep dh_installdirs # Add here commands to install the package into debian/tmp mkdir $(CURDIR)/debian/tmp $(MAKE) install DESTDIR=$(CURDIR)/debian/tmp dh_movefiles # Build architecture-independent files here. binary-indep: build install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: build install dh_testdir dh_testroot dh_installchangelogs dh_installdocs dh_installexamples # dh_install # dh_installmenu # dh_installdebconf # dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_installinit # dh_installcron # dh_installinfo dh_installman dh_link dh_strip dh_compress dh_fixperms # dh_perl # dh_python # dh_makeshlibs dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb build-arch: build build-indep: build binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure rem-0.6.0/docs/000077500000000000000000000000001337577470400132515ustar00rootroot00000000000000rem-0.6.0/docs/COPYING000066400000000000000000000027771337577470400143210ustar00rootroot00000000000000Copyright (c) 2010 - 2018, Alfred E. Heggestad Copyright (c) 2010 - 2018, Richard Aas Copyright (c) 2010 - 2018, Creytiv.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the Creytiv.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. rem-0.6.0/docs/ChangeLog000066400000000000000000000072531337577470400150320ustar00rootroot000000000000002018-11-24 Alfred E. Heggestad * Version 0.6.0 * Project URL: https://github.com/creytiv/rem * avc: new module for Advanced Video Coding (AVC) * flv: new module for Flash Video File format (FLV) 2018-04-20 Alfred E. Heggestad * Version 0.5.3 * Project URL: https://github.com/creytiv/rem * auresamp: avoid FIR filtering if ouput sample rate equals input (#15) * build: Update Windows project (#18) (thanks Encamy) * vid: vidframe_draw_point: correct endian for RGB32 (#16) 2017-09-23 Alfred E. Heggestad * Version 0.5.2 * Project URL: https://github.com/creytiv/rem * build: Updated MSVS projects to vs2015 (thanks Mikhail Barg) * goertzel: new module for Goertzel Algorithm * dtmf: new module for DTMF decoder 2017-04-08 Alfred E. Heggestad * Version 0.5.1 * Project URL: https://github.com/creytiv/rem * vid: add YUV444P to vidframe functions add NV12/21 to vidframe_copy * vidconv: add RGB32 to/from YUV444P add NV12/21 to RGB32 (thanks Harald Gutmann) 2016-12-02 Alfred E. Heggestad * Version 0.5.0 * Project URL: https://github.com/creytiv/rem * build: remove support for Symbian OS * vid: add support for YUV444P pixel format * vidconv: fix yuv420p <-> nv12 conversion added vidconv YUV420P to NV12 2015-12-13 Alfred E. Heggestad * Version 0.4.7 * build: add pkg-config file (thanks to William King) * auconv: new module for audio sample format conversion (thanks to Ola Palm for testing) * aumix: close file on sleep * vid: added vidframe_copy() * vidmix: pthread_rwlockattr_setkind_np for linux and glibc (patch copied from openwrt repo) 2014-05-18 Alfred E. Heggestad * Version 0.4.6 * debian: update package * include: use quotes to include header files * vidmix: use full picture for 2 participants 2014-01-06 Alfred E. Heggestad * Version 0.4.5 * debian: fix dependency to libre (patch from Juha) * auresamp: improved audio resampler better low-pass FIR-filter coefficients * fir: improved channels-agnostic FIR-filter * vid: vidframe_draw_point() make API take RGB-values handle VID_FMT_ARGB format in all vid-functions vidframe_fill() fix swapped RGB/BGR values 2013-10-03 Alfred E. Heggestad * Version 0.4.4 * debian: fix dependency to libre (patch from Juha) * vid: change type of width/height to 'unsigned' * vidframe: added basic drawing functions 2013-05-05 Alfred E. Heggestad * Version 0.4.3 * aubuf: added API for 16-bit samples * vidconv: added support for NV21 to YUV420P * vidmix: various improvements 2012-09-09 Alfred E. Heggestad * Version 0.4.2 * aubuf: fix bug in aubuf_append() * aumix: change sample type to int16_t * auresamp: change sample API to array of int16_t * vid: change signature of vidframe_size() * vidconv: fix pixel alignment bug * vidmix: enhance API 2012-04-21 Alfred E. Heggestad * Version 0.4.1 * updated doxygen comments * aufile: new module for audio file reading/writing * aumix: various improvements, add aumix_playfile() add function to enable/disable sources added aumix_source_flush() * vidconv: add support for YUV420P to RGB555 fix warning of casting to unaligned access * vidmix: various improvements add function to enable/disable sources 2011-12-25 Alfred E. Heggestad * Version 0.4.0 * vidconv: add support for YUV420P to RGB565 2011-09-07 Alfred E. Heggestad * Version 0.3.0 * Initial Release rem-0.6.0/include/000077500000000000000000000000001337577470400137445ustar00rootroot00000000000000rem-0.6.0/include/rem.h000066400000000000000000000004411337577470400146770ustar00rootroot00000000000000/** * @file rem.h Wrapper for librem headers * * Copyright (C) 2010 Creytiv.com */ #ifndef REM_H__ #define REM_H__ #ifdef __cplusplus extern "C" { #endif #include "rem_audio.h" #include "rem_video.h" #include "rem_dsp.h" #include "rem_flv.h" #ifdef __cplusplus } #endif #endif rem-0.6.0/include/rem_au.h000066400000000000000000000007211337577470400153650ustar00rootroot00000000000000/** * @file rem_au.h Basic audio types * * Copyright (C) 2010 Creytiv.com */ /** Audio formats */ enum aufmt { AUFMT_S16LE, /**< Signed 16-bit PCM */ AUFMT_PCMA, /**< G.711 A-law */ AUFMT_PCMU, /**< G.711 U-law */ AUFMT_FLOAT, /**< Float 32 bit (CPU endian) */ AUFMT_S24_3LE,/**< Signed 24bit Little Endian in 3bytes format */ }; size_t aufmt_sample_size(enum aufmt fmt); const char *aufmt_name(enum aufmt fmt); rem-0.6.0/include/rem_aubuf.h000066400000000000000000000020071337577470400160610ustar00rootroot00000000000000/** * @file rem_aubuf.h Audio Buffer * * Copyright (C) 2010 Creytiv.com */ struct aubuf; int aubuf_alloc(struct aubuf **abp, size_t min_sz, size_t max_sz); int aubuf_append(struct aubuf *ab, struct mbuf *mb); int aubuf_write(struct aubuf *ab, const uint8_t *p, size_t sz); void aubuf_read(struct aubuf *ab, uint8_t *p, size_t sz); int aubuf_get(struct aubuf *ab, uint32_t ptime, uint8_t *p, size_t sz); void aubuf_flush(struct aubuf *ab); int aubuf_debug(struct re_printf *pf, const struct aubuf *ab); size_t aubuf_cur_size(const struct aubuf *ab); static inline int aubuf_write_samp(struct aubuf *ab, const int16_t *sampv, size_t sampc) { return aubuf_write(ab, (const uint8_t *)sampv, sampc * 2); } static inline void aubuf_read_samp(struct aubuf *ab, int16_t *sampv, size_t sampc) { aubuf_read(ab, (uint8_t *)sampv, sampc * 2); } static inline int aubuf_get_samp(struct aubuf *ab, uint32_t ptime, int16_t *sampv, size_t sampc) { return aubuf_get(ab, ptime, (uint8_t *)sampv, sampc * 2); } rem-0.6.0/include/rem_auconv.h000066400000000000000000000004561337577470400162600ustar00rootroot00000000000000/** * @file rem_auconv.h Audio sample format conversion * * Copyright (C) 2010 Creytiv.com */ void auconv_from_s16(enum aufmt dst_fmt, void *dst_sampv, const int16_t *src_sampv, size_t sampc); void auconv_to_s16(int16_t *dst_sampv, enum aufmt src_fmt, void *src_sampv, size_t sampc); rem-0.6.0/include/rem_audio.h000066400000000000000000000005471337577470400160670ustar00rootroot00000000000000/** * @file rem_audio.h Wrapper for all Audio header files * * Copyright (C) 2010 Creytiv.com */ #include "rem_au.h" #include "rem_aubuf.h" #include "rem_auconv.h" #include "rem_aufile.h" #include "rem_autone.h" #include "rem_aumix.h" #include "rem_dtmf.h" #include "rem_fir.h" #include "rem_goertzel.h" #include "rem_auresamp.h" #include "rem_g711.h" rem-0.6.0/include/rem_aufile.h000066400000000000000000000010121337577470400162170ustar00rootroot00000000000000/** * @file rem_aufile.h Audio File interface * * Copyright (C) 2010 Creytiv.com */ /** Audio file mode */ enum aufile_mode { AUFILE_READ, AUFILE_WRITE, }; /** Audio file parameters */ struct aufile_prm { uint32_t srate; uint8_t channels; enum aufmt fmt; }; struct aufile; int aufile_open(struct aufile **afp, struct aufile_prm *prm, const char *filename, enum aufile_mode mode); int aufile_read(struct aufile *af, uint8_t *p, size_t *sz); int aufile_write(struct aufile *af, const uint8_t *p, size_t sz); rem-0.6.0/include/rem_aumix.h000066400000000000000000000015241337577470400161050ustar00rootroot00000000000000/** * @file rem_aumix.h Audio Mixer * * Copyright (C) 2010 Creytiv.com */ struct aumix; struct aumix_source; /** * Audio mixer frame handler * * @param buf Buffer with audio samples * @param sz Number of bytes * @param arg Handler argument */ typedef void (aumix_frame_h)(const int16_t *sampv, size_t sampc, void *arg); int aumix_alloc(struct aumix **mixp, uint32_t srate, uint8_t ch, uint32_t ptime); int aumix_playfile(struct aumix *mix, const char *filepath); uint32_t aumix_source_count(const struct aumix *mix); int aumix_source_alloc(struct aumix_source **srcp, struct aumix *mix, aumix_frame_h *fh, void *arg); void aumix_source_enable(struct aumix_source *src, bool enable); int aumix_source_put(struct aumix_source *src, const int16_t *sampv, size_t sampc); void aumix_source_flush(struct aumix_source *src); rem-0.6.0/include/rem_auresamp.h000066400000000000000000000021011337577470400165670ustar00rootroot00000000000000/** * @file rem_auresamp.h Audio Resampling * * Copyright (C) 2010 Creytiv.com */ /** * Defines the audio resampler handler * * @param outv Output samples * @param inv Input samples * @param inc Number of input samples * @param ratio Resample ratio */ typedef void (auresamp_h)(int16_t *outv, const int16_t *inv, size_t inc, unsigned ratio); /** Defines the resampler state */ struct auresamp { struct fir fir; /**< FIR filter state */ auresamp_h *resample; /**< Resample handler */ const int16_t *tapv; /**< FIR filter taps */ size_t tapc; /**< FIR filter tap count */ uint32_t orate, irate; /**< Input/output sample rate */ unsigned och, ich; /**< Input/output channel count */ unsigned ratio; /**< Resample ratio */ bool up; /**< Up/down sample flag */ }; void auresamp_init(struct auresamp *rs); int auresamp_setup(struct auresamp *rs, uint32_t irate, unsigned ich, uint32_t orate, unsigned och); int auresamp(struct auresamp *rs, int16_t *outv, size_t *outc, const int16_t *inv, size_t inc); rem-0.6.0/include/rem_autone.h000066400000000000000000000003541337577470400162550ustar00rootroot00000000000000/** * @file rem_autone.h Audio Tones * * Copyright (C) 2010 Creytiv.com */ int autone_sine(struct mbuf *mb, uint32_t srate, uint32_t f1, int l1, uint32_t f2, int l2); int autone_dtmf(struct mbuf *mb, uint32_t srate, int digit); rem-0.6.0/include/rem_avc.h000066400000000000000000000010221337577470400155240ustar00rootroot00000000000000/** * @file rem_avc.h Advanced Video Coding * * Copyright (C) 2010 Creytiv.com */ struct avc_config { uint8_t profile_ind; uint8_t profile_compat; uint8_t level_ind; uint16_t sps_len; uint8_t sps[256]; uint16_t pps_len; uint8_t pps[64]; }; int avc_config_encode(struct mbuf *mb, uint8_t profile_ind, uint8_t profile_compat, uint8_t level_ind, uint16_t sps_length, const uint8_t *sps, uint16_t pps_length, const uint8_t *pps); int avc_config_decode(struct avc_config *conf, struct mbuf *mb); rem-0.6.0/include/rem_dsp.h000066400000000000000000000042641337577470400155540ustar00rootroot00000000000000/** * @file rem_dsp.h DSP routines * * Copyright (C) 2010 Creytiv.com */ #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #define INT15_MAX 0x3fff #define INT15_MIN (-INT15_MAX - 1) #ifndef INT16_MAX #define INT16_MAX 0x7fff #endif #ifndef INT16_MIN #define INT16_MIN (-INT16_MAX - 1) #endif /* todo: check which preprocessor macros to use */ #if defined (HAVE_ARMV6) || defined (HAVE_NEON) static inline uint8_t saturate_u8(int32_t a) { uint8_t r; __asm__ __volatile__ ("usat %0, #8, %1" : "=r"(r) : "r"(a)); return r; } static inline int16_t saturate_s15(int32_t a) { __asm__ __volatile__ ("ssat %0, #15, %1 \n\t" : "+r"(a) : "r"(a) ); return a; } static inline int16_t saturate_s16(int32_t a) { __asm__ __volatile__ ("ssat %0, #16, %1 \n\t" : "+r"(a) : "r"(a) ); return a; } static inline int16_t saturate_add16(int32_t a, int32_t b) { __asm__ __volatile__ ("add %0, %1, %2 \n\t" "ssat %0, #16, %0 \n\t" :"+r"(a) :"r"(a), "r"(b) ); return a; } static inline int16_t saturate_sub16(int32_t a, int32_t b) { __asm__ __volatile__ ("sub %0, %1, %2 \n\t" "ssat %0, #16, %0 \n\t" :"+r"(a) :"r"(a), "r"(b) ); return a; } #else static inline uint8_t saturate_u8(int32_t a) { return (a > (int32_t)UINT8_MAX) ? UINT8_MAX : ((a < 0) ? 0 : a); } static inline int16_t saturate_s15(int32_t a) { if (a > INT15_MAX) return INT15_MAX; else if (a < INT15_MIN) return INT15_MIN; else return a; } static inline int16_t saturate_s16(int32_t a) { if (a > INT16_MAX) return INT16_MAX; else if (a < INT16_MIN) return INT16_MIN; else return a; } static inline int16_t saturate_add16(int32_t a, int32_t b) { return saturate_s16(a + b); } static inline int16_t saturate_sub16(int32_t a, int32_t b) { return saturate_s16(a - b); } #endif #ifdef HAVE_NEON static inline int ABS32(int a) { int r; __asm__ __volatile__ ("vmov.s32 d0[0], %1 \t\n" "vabs.s32 d0, d0 \t\n" "vmov.s32 %0, d0[0] \t\n" : "=r"(r) : "r"(a) ); return a; } #else static inline int ABS32(int a) { return a > 0 ? a : -a; } #endif rem-0.6.0/include/rem_dtmf.h000066400000000000000000000010141337577470400157060ustar00rootroot00000000000000/** * @file rem_dtmf.h DTMF Decoder * * Copyright (C) 2010 Creytiv.com */ struct dtmf_dec; /** * Defines the DTMF decode handler * * @param digit Decoded DTMF digit * @param arg Handler argument */ typedef void (dtmf_dec_h)(char digit, void *arg); int dtmf_dec_alloc(struct dtmf_dec **decp, unsigned srate, unsigned ch, dtmf_dec_h *dech, void *arg); void dtmf_dec_reset(struct dtmf_dec *dec, unsigned srate, unsigned ch); void dtmf_dec_probe(struct dtmf_dec *dec, const int16_t *sampv, size_t sampc); rem-0.6.0/include/rem_fir.h000066400000000000000000000006401337577470400155400ustar00rootroot00000000000000/** * @file rem_fir.h Finite Impulse Response (FIR) functions * * Copyright (C) 2010 Creytiv.com */ /** Defines the fir filter state */ struct fir { int16_t history[256]; /**< Previous samples */ unsigned index; /**< Sample index */ }; void fir_reset(struct fir *fir); void fir_filter(struct fir *fir, int16_t *outv, const int16_t *inv, size_t inc, unsigned ch, const int16_t *tapv, size_t tapc); rem-0.6.0/include/rem_flv.h000066400000000000000000000015351337577470400155530ustar00rootroot00000000000000/** * @file rem_flv.h Flash Video File Format * * Copyright (C) 2010 Creytiv.com */ /* * Audio */ enum flv_aucodec { FLV_AUCODEC_PCM = 0, FLV_AUCODEC_ALAW = 7, FLV_AUCODEC_ULAW = 8, FLV_AUCODEC_AAC = 10, }; enum flv_srate { FLV_SRATE_5500HZ = 0, FLV_SRATE_11000HZ = 1, FLV_SRATE_22000HZ = 2, FLV_SRATE_44000HZ = 3, }; enum flv_aac_packet_type { FLV_AAC_SEQUENCE_HEADER = 0, FLV_AAC_RAW = 1, }; /* * Video */ enum flv_vidframe { FLV_VIDFRAME_KEY = 1, FLV_VIDFRAME_INTER = 2, FLV_VIDFRAME_DISP_INTER = 3, FLV_VIDFRAME_GENERATED_KEY = 4, FLV_VIDFRAME_VIDEO_INFO_CMD = 5, }; enum flv_vidcodec { FLV_VIDCODEC_H263 = 2, FLV_VIDCODEC_H264 = 7, FLV_VIDCODEC_MPEG4 = 9, }; enum flv_avc_packet_type { FLV_AVC_SEQUENCE = 0, FLV_AVC_NALU = 1, FLV_AVC_EOS = 2, }; rem-0.6.0/include/rem_g711.h000066400000000000000000000022641337577470400154430ustar00rootroot00000000000000/** * @file rem_g711.h Interface to G.711 codec * * Copyright (C) 2010 Creytiv.com */ extern const uint8_t g711_l2u[4096]; extern const uint8_t g711_l2A[2048]; extern const int16_t g711_u2l[256]; extern const int16_t g711_A2l[256]; /** * Encode one 16-bit PCM sample to U-law format * * @param l Signed PCM sample * * @return U-law byte */ static inline uint8_t g711_pcm2ulaw(int16_t l) { const uint8_t mask = (l < 0) ? 0x7f : 0xff; if (l < 0) l = -l; if (l < 4) return 0xff & mask; l -= 4; l >>= 3; return g711_l2u[l] & mask; } /** * Encode one 16-bit PCM sample to A-law format * * @param l Signed PCM sample * * @return A-law byte */ static inline uint8_t g711_pcm2alaw(int16_t l) { const uint8_t mask = (l < 0) ? 0x7f : 0xff; if (l < 0) l = -l; l >>= 4; return g711_l2A[l] & mask; } /** * Decode one U-law sample to 16-bit PCM sample * * @param u U-law byte * * @return Signed PCM sample */ static inline int16_t g711_ulaw2pcm(uint8_t u) { return g711_u2l[u]; } /** * Decode one A-law sample to 16-bit PCM sample * * @param A A-law byte * * @return Signed PCM sample */ static inline int16_t g711_alaw2pcm(uint8_t a) { return g711_A2l[a]; } rem-0.6.0/include/rem_goertzel.h000066400000000000000000000012271337577470400166150ustar00rootroot00000000000000/** * @file rem_goertzel.h Goertzel algorithm * * Copyright (C) 2010 Creytiv.com */ /** Defines the goertzel algorithm state */ struct goertzel { double q1; /**< current state */ double q2; /**< previous state */ double coef; /**< coefficient */ }; void goertzel_init(struct goertzel *g, double freq, unsigned srate); void goertzel_reset(struct goertzel *g); double goertzel_result(struct goertzel *g); /** * Process sample * * @param g Goertzel state * @param samp Sample value */ static inline void goertzel_update(struct goertzel *g, int16_t samp) { double q0 = g->coef*g->q1 - g->q2 + (double)samp; g->q2 = g->q1; g->q1 = q0; } rem-0.6.0/include/rem_vid.h000066400000000000000000000075231337577470400155510ustar00rootroot00000000000000/** * @file rem_vid.h Basic video types * * Copyright (C) 2010 Creytiv.com */ /** Pixel format */ enum vidfmt { VID_FMT_YUV420P = 0, /* planar YUV 4:2:0 12bpp */ VID_FMT_YUYV422, /* packed YUV 4:2:2 16bpp */ VID_FMT_UYVY422, /* packed YUV 4:2:2 16bpp */ VID_FMT_RGB32, /* packed RGBA 8:8:8:8 32bpp (native endian) */ VID_FMT_ARGB, /* packed RGBA 8:8:8:8 32bpp (big endian) */ VID_FMT_RGB565, /* packed RGB 5:6:5 16bpp (native endian) */ VID_FMT_RGB555, /* packed RGB 5:5:5 16bpp (native endian) */ VID_FMT_NV12, /* planar YUV 4:2:0 12bpp UV interleaved */ VID_FMT_NV21, /* planar YUV 4:2:0 12bpp VU interleaved */ VID_FMT_YUV444P, /* planar YUV 4:4:4 24bpp */ /* marker */ VID_FMT_N }; /** Video pixel format component description */ struct vidfmt_compdesc { unsigned plane_index:2; unsigned step:3; }; /** Video pixel format description */ struct vidfmt_desc { const char *name; uint8_t planes; uint8_t compn; struct vidfmt_compdesc compv[4]; }; /** Video orientation */ enum vidorient { VIDORIENT_PORTRAIT, VIDORIENT_PORTRAIT_UPSIDEDOWN, VIDORIENT_LANDSCAPE_LEFT, VIDORIENT_LANDSCAPE_RIGHT, }; /** Video size */ struct vidsz { unsigned w; /**< Width */ unsigned h; /**< Height */ }; /** Video frame */ struct vidframe { uint8_t *data[4]; /**< Video planes */ uint16_t linesize[4]; /**< Array of line-sizes */ struct vidsz size; /**< Frame resolution */ enum vidfmt fmt; /**< Video pixel format */ }; /** Video point */ struct vidpt { unsigned x; /**< X position */ unsigned y; /**< Y position */ }; /** Video rectangle */ struct vidrect { unsigned x; /**< X position */ unsigned y; /**< Y position */ unsigned w; /**< Width */ unsigned h; /**< Height */ }; static inline bool vidsz_cmp(const struct vidsz *a, const struct vidsz *b) { if (!a || !b) return false; if (a == b) return true; return a->w == b->w && a->h == b->h; } static inline bool vidrect_cmp(const struct vidrect *a, const struct vidrect *b) { if (!a || !b) return false; if (a == b) return true; return a->x == b->x && a->y == b->y && a->w == b->w && a->h == b->h; } static inline int rgb2y(uint8_t r, uint8_t g, uint8_t b) { return ((66 * r + 129 * g + 25 * b + 128) >> 8) + 16; } static inline int rgb2u(uint8_t r, uint8_t g, uint8_t b) { return ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128; } static inline int rgb2v(uint8_t r, uint8_t g, uint8_t b) { return ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128; } size_t vidframe_size(enum vidfmt fmt, const struct vidsz *sz); void vidframe_init(struct vidframe *vf, enum vidfmt fmt, const struct vidsz *sz, void *data[4], unsigned linesize[4]); void vidframe_init_buf(struct vidframe *vf, enum vidfmt fmt, const struct vidsz *sz, uint8_t *buf); int vidframe_alloc(struct vidframe **vfp, enum vidfmt fmt, const struct vidsz *sz); void vidframe_fill(struct vidframe *vf, uint32_t r, uint32_t g, uint32_t b); void vidframe_copy(struct vidframe *dst, const struct vidframe *src); const char *vidfmt_name(enum vidfmt fmt); static inline bool vidframe_isvalid(const struct vidframe *f) { return f ? f->data[0] != NULL : false; } extern const struct vidfmt_desc vidfmt_descv[VID_FMT_N]; /* draw */ void vidframe_draw_point(struct vidframe *f, unsigned x, unsigned y, uint8_t r, uint8_t g, uint8_t b); void vidframe_draw_hline(struct vidframe *f, unsigned x0, unsigned y0, unsigned w, uint8_t r, uint8_t g, uint8_t b); void vidframe_draw_vline(struct vidframe *f, unsigned x0, unsigned y0, unsigned h, uint8_t r, uint8_t g, uint8_t b); void vidframe_draw_rect(struct vidframe *f, unsigned x0, unsigned y0, unsigned w, unsigned h, uint8_t r, uint8_t g, uint8_t b); rem-0.6.0/include/rem_vidconv.h000066400000000000000000000004341337577470400164310ustar00rootroot00000000000000/** * @file rem_vidconv.h Video colorspace conversion * * Copyright (C) 2010 Creytiv.com */ void vidconv(struct vidframe *dst, const struct vidframe *src, struct vidrect *r); void vidconv_aspect(struct vidframe *dst, const struct vidframe *src, struct vidrect *r); rem-0.6.0/include/rem_video.h000066400000000000000000000003031337577470400160620ustar00rootroot00000000000000/** * @file rem_video.h Wrapper for all Video header files * * Copyright (C) 2010 Creytiv.com */ #include "rem_vid.h" #include "rem_vidmix.h" #include "rem_vidconv.h" #include "rem_avc.h" rem-0.6.0/include/rem_vidmix.h000066400000000000000000000027261337577470400162670ustar00rootroot00000000000000/** * @file rem_vidmix.h Video Mixer * * Copyright (C) 2010 Creytiv.com */ struct vidmix; struct vidmix_source; /** * Video mixer frame handler * * @param ts Timestamp * @param frame Video frame * @param arg Handler argument */ typedef void (vidmix_frame_h)(uint32_t ts, const struct vidframe *frame, void *arg); int vidmix_alloc(struct vidmix **mixp); int vidmix_source_alloc(struct vidmix_source **srcp, struct vidmix *mix, const struct vidsz *sz, unsigned fps, bool content, vidmix_frame_h *fh, void *arg); bool vidmix_source_isenabled(const struct vidmix_source *src); bool vidmix_source_isrunning(const struct vidmix_source *src); void *vidmix_source_get_focus(const struct vidmix_source *src); void vidmix_source_enable(struct vidmix_source *src, bool enable); int vidmix_source_start(struct vidmix_source *src); void vidmix_source_stop(struct vidmix_source *src); int vidmix_source_set_size(struct vidmix_source *src, const struct vidsz *sz); void vidmix_source_set_rate(struct vidmix_source *src, unsigned fps); void vidmix_source_set_content_hide(struct vidmix_source *src, bool hide); void vidmix_source_toggle_selfview(struct vidmix_source *src); void vidmix_source_set_focus(struct vidmix_source *src, const struct vidmix_source *focus_src, bool focus_full); void vidmix_source_set_focus_idx(struct vidmix_source *src, unsigned pidx); void vidmix_source_put(struct vidmix_source *src, const struct vidframe *frame); rem-0.6.0/mk/000077500000000000000000000000001337577470400127305ustar00rootroot00000000000000rem-0.6.0/mk/Doxyfile000066400000000000000000000212441337577470400144410ustar00rootroot00000000000000# Doxyfile 1.4.7 #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- PROJECT_NAME = librem PROJECT_NUMBER = 0.4.0 OUTPUT_DIRECTORY = ../rem-dox CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English #USE_WINDOWS_ENCODING = NO BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = NO STRIP_FROM_PATH = STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = YES MULTILINE_CPP_IS_BRIEF = NO #DETAILS_AT_TOP = NO INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 8 ALIASES = OPTIMIZE_OUTPUT_FOR_C = YES OPTIMIZE_OUTPUT_JAVA = NO #BUILTIN_STL_SUPPORT = NO DISTRIBUTE_GROUP_DOC = NO SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = NO EXTRACT_PRIVATE = NO EXTRACT_STATIC = NO EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_METHODS = NO HIDE_UNDOC_MEMBERS = YES HIDE_UNDOC_CLASSES = YES HIDE_FRIEND_COMPOUNDS = NO HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES INLINE_INFO = YES SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- QUIET = YES WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = YES WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = include src FILE_PATTERNS = *.c \ *.h \ *.dox RECURSIVE = YES EXCLUDE = test.c EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = */.svn/* EXAMPLE_PATH = EXAMPLE_PATTERNS = * EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_PATTERNS = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = YES INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = YES REFERENCES_RELATION = YES #REFERENCES_LINK_SOURCE = YES #USE_HTAGS = NO VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = YES COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = GENERATE_HTMLHELP = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO BINARY_TOC = NO TOC_EXPAND = NO DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NO TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = NO LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = PDF_HYPERLINKS = NO USE_PDFLATEX = NO LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- GENERATE_XML = NO XML_OUTPUT = xml XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = YES SEARCH_INCLUDES = YES INCLUDE_PATH = include INCLUDE_FILE_PATTERNS = PREDEFINED = HAVE_INTTYPES_H HAVE_INET6 HAVE_STDBOOL_H EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES HIDE_UNDOC_RELATIONS = YES HAVE_DOT = YES CLASS_GRAPH = YES COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = NO TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES #CALL_GRAPH = YES todo: disabled to run faster #CALLER_GRAPH = YES GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png DOT_PATH = DOTFILE_DIRS = #MAX_DOT_GRAPH_WIDTH = 1024 #MAX_DOT_GRAPH_HEIGHT = 1024 #MAX_DOT_GRAPH_DEPTH = 1000 DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO rem-0.6.0/mk/win32/000077500000000000000000000000001337577470400136725ustar00rootroot00000000000000rem-0.6.0/mk/win32/rem.vcxproj000066400000000000000000000147521337577470400161030ustar00rootroot00000000000000 Debug Win32 Release Win32 rem-win32 {3E767371-A72B-4F5C-A695-8F844B0889C5} Win32Proj 8.1 StaticLibrary v140 MultiByte StaticLibrary v140 MultiByte <_ProjectFileVersion>14.0.25123.0 ..\..\$(Platform)\$(Configuration)\bin\ ..\..\$(Platform)\$(Configuration)\tmp\mk\win32\ ..\..\$(Platform)\$(Configuration)\bin\ ..\..\$(Platform)\$(Configuration)\tmp\mk\win32\ Disabled Default ..\..\include;..\..\..\re\include;..\..\..\misc;%(AdditionalIncludeDirectories) WIN32;_CONSOLE;HAVE_SELECT;HAVE_IO_H;_CRT_SECURE_NO_DEPRECATE;FD_SETSIZE=1024;_DEBUG;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebug Level3 EditAndContinue 4142;%(DisableSpecificWarnings) $(IntDir)%(RelativeDir)%(Filename).obj Iphlpapi.lib %(AdditionalOptions) ..\..\include;..\..\..\re\include;..\..\..\misc;%(AdditionalIncludeDirectories) WIN32;_CONSOLE;HAVE_SELECT;HAVE_IO_H;_CRT_SECURE_NO_DEPRECATE;FD_SETSIZE=1024;NDEBUG;%(PreprocessorDefinitions) MultiThreadedDLL Level3 ProgramDatabase 4142;%(DisableSpecificWarnings) $(IntDir)%(RelativeDir)%(Filename).obj rem-0.6.0/mk/win32/rem.vcxproj.filters000066400000000000000000000116021337577470400175410ustar00rootroot00000000000000 {454100a0-69da-46b8-87a7-362e0e8ded12} {9de4f7c5-e0f0-48ec-88ee-bba0a84f11cd} {30b5c2c3-53a1-471f-a0b6-91dbcdec1f31} {646189bc-fc6d-42f7-8587-cd24d2c6cf36} {ed1f97e2-4513-4599-84e5-914231538638} {12c26b7e-15a4-4696-90d6-3342ace2ff42} {d6c04be0-d9f9-4796-83b7-11b819928979} {d2756e24-f5c6-4ac8-8744-9c1bc718bcd4} {ab229de2-80fe-4d81-8a80-1fa6e481e483} {488ee2c6-c3ae-4c94-b00e-6fafad186f06} {8f5e0c83-eccb-4c39-8064-796c2da69de9} {68ad1019-ff82-4811-a9df-cfe0eabeea34} include include include include include include include include include include include include include include include include src\aufile src\au src\aubuf src\auconv src\aufile src\aufile src\auresamp src\autone src\fir src\g711 src\vid src\vid src\vid src\vidconv rem-0.6.0/rpm/000077500000000000000000000000001337577470400131175ustar00rootroot00000000000000rem-0.6.0/rpm/rem.spec000066400000000000000000000020671337577470400145630ustar00rootroot00000000000000%define name rem %define ver 0.6.0 %define rel 1 Summary: Audio and Video processing media library Name: %name Version: %ver Release: %rel License: BSD Group: Applications/Devel Source0: file://%{name}-%{version}.tar.gz URL: http://www.creytiv.com/ Vendor: Creytiv Packager: Alfred E. Heggestad BuildRoot: /var/tmp/%{name}-build-root BuildRequires: re-devel %description Audio and Video processing media library %package devel Summary: librem development files Group: Development/Libraries Requires: %{name} = %{version} %description devel librem development files. %prep %setup %build make RELEASE=1 %install rm -rf $RPM_BUILD_ROOT make DESTDIR=$RPM_BUILD_ROOT install \ %ifarch x86_64 LIBDIR=/usr/lib64 %endif %clean rm -rf $RPM_BUILD_ROOT %post -p /sbin/ldconfig %postun -p /sbin/ldconfig %files %defattr(644,root,root,755) %attr(755,root,root) %{_libdir}/librem*.so* %files devel %defattr(644,root,root,755) %{_includedir}/rem/*.h %{_libdir}/librem*.a %changelog * Wed Sep 7 2011 Alfred E. Heggestad - - Initial build. rem-0.6.0/src/000077500000000000000000000000001337577470400131105ustar00rootroot00000000000000rem-0.6.0/src/au/000077500000000000000000000000001337577470400135155ustar00rootroot00000000000000rem-0.6.0/src/au/fmt.c000066400000000000000000000013071337577470400144500ustar00rootroot00000000000000/** * @file au/fmt.c Audio formats * * Copyright (C) 2010 Creytiv.com */ #include #include /* Number of bytes per sample */ size_t aufmt_sample_size(enum aufmt fmt) { switch (fmt) { case AUFMT_S16LE: return sizeof(int16_t); case AUFMT_PCMA: return 1; case AUFMT_PCMU: return 1; case AUFMT_FLOAT: return sizeof(float); case AUFMT_S24_3LE: return 3; default: return 0; } } const char *aufmt_name(enum aufmt fmt) { switch (fmt) { case AUFMT_S16LE: return "S16LE"; case AUFMT_PCMA: return "PCMA"; case AUFMT_PCMU: return "PCMU"; case AUFMT_FLOAT: return "FLOAT"; case AUFMT_S24_3LE: return "S24_3LE"; default: return "???"; } } rem-0.6.0/src/au/mod.mk000066400000000000000000000001021337577470400146160ustar00rootroot00000000000000# # mod.mk # # Copyright (C) 2010 Creytiv.com # SRCS += au/fmt.c rem-0.6.0/src/aubuf/000077500000000000000000000000001337577470400142125ustar00rootroot00000000000000rem-0.6.0/src/aubuf/aubuf.c000066400000000000000000000126441337577470400154670ustar00rootroot00000000000000/** * @file aubuf.c Audio Buffer * * Copyright (C) 2010 Creytiv.com */ #include #include #include #define AUBUF_DEBUG 0 /** Locked audio-buffer with almost zero-copy */ struct aubuf { struct list afl; struct lock *lock; size_t wish_sz; size_t cur_sz; size_t max_sz; bool filling; uint64_t ts; #if AUBUF_DEBUG struct { size_t or; size_t ur; } stats; #endif }; struct auframe { struct le le; struct mbuf *mb; }; static void auframe_destructor(void *arg) { struct auframe *af = arg; list_unlink(&af->le); mem_deref(af->mb); } static void aubuf_destructor(void *arg) { struct aubuf *ab = arg; list_flush(&ab->afl); mem_deref(ab->lock); } /** * Allocate a new audio buffer * * @param abp Pointer to allocated audio buffer * @param min_sz Minimum buffer size * @param max_sz Maximum buffer size (0 for no max size) * * @return 0 for success, otherwise error code */ int aubuf_alloc(struct aubuf **abp, size_t min_sz, size_t max_sz) { struct aubuf *ab; int err; if (!abp || !min_sz) return EINVAL; ab = mem_zalloc(sizeof(*ab), aubuf_destructor); if (!ab) return ENOMEM; err = lock_alloc(&ab->lock); if (err) goto out; ab->wish_sz = min_sz; ab->max_sz = max_sz; ab->filling = true; out: if (err) mem_deref(ab); else *abp = ab; return err; } /** * Append a PCM-buffer to the end of the audio buffer * * @param ab Audio buffer * @param mb Mbuffer with PCM samples * * @return 0 for success, otherwise error code */ int aubuf_append(struct aubuf *ab, struct mbuf *mb) { struct auframe *af; if (!ab || !mb) return EINVAL; af = mem_zalloc(sizeof(*af), auframe_destructor); if (!af) return ENOMEM; af->mb = mem_ref(mb); lock_write_get(ab->lock); list_append(&ab->afl, &af->le, af); ab->cur_sz += mbuf_get_left(mb); if (ab->max_sz && ab->cur_sz > ab->max_sz) { #if AUBUF_DEBUG ++ab->stats.or; (void)re_printf("aubuf: %p overrun (cur=%zu)\n", ab, ab->cur_sz); #endif af = list_ledata(ab->afl.head); if (af) { ab->cur_sz -= mbuf_get_left(af->mb); mem_deref(af); } } lock_rel(ab->lock); return 0; } /** * Write PCM samples to the audio buffer * * @param ab Audio buffer * @param p Pointer to PCM data * @param sz Number of bytes to write * * @return 0 for success, otherwise error code */ int aubuf_write(struct aubuf *ab, const uint8_t *p, size_t sz) { struct mbuf *mb = mbuf_alloc(sz); int err; if (!mb) return ENOMEM; (void)mbuf_write_mem(mb, p, sz); mb->pos = 0; err = aubuf_append(ab, mb); mem_deref(mb); return err; } /** * Read PCM samples from the audio buffer. If there is not enough data * in the audio buffer, silence will be read. * * @param ab Audio buffer * @param p Buffer where PCM samples are read into * @param sz Number of bytes to read */ void aubuf_read(struct aubuf *ab, uint8_t *p, size_t sz) { struct le *le; if (!ab || !p || !sz) return; lock_write_get(ab->lock); if (ab->cur_sz < (ab->filling ? ab->wish_sz : sz)) { #if AUBUF_DEBUG if (!ab->filling) { ++ab->stats.ur; (void)re_printf("aubuf: %p underrun (cur=%zu)\n", ab, ab->cur_sz); } #endif ab->filling = true; memset(p, 0, sz); goto out; } ab->filling = false; le = ab->afl.head; while (le) { struct auframe *af = le->data; size_t n; le = le->next; n = min(mbuf_get_left(af->mb), sz); (void)mbuf_read_mem(af->mb, p, n); ab->cur_sz -= n; if (!mbuf_get_left(af->mb)) mem_deref(af); if (n == sz) break; p += n; sz -= n; } out: lock_rel(ab->lock); } /** * Timed read PCM samples from the audio buffer. If there is not enough data * in the audio buffer, silence will be read. * * @param ab Audio buffer * @param ptime Packet time in [ms] * @param p Buffer where PCM samples are read into * @param sz Number of bytes to read * * @note This does the same as aubuf_read() except that it also takes * timing into consideration. * * @return 0 if valid PCM was read, ETIMEDOUT if no PCM is ready yet */ int aubuf_get(struct aubuf *ab, uint32_t ptime, uint8_t *p, size_t sz) { uint64_t now; int err = 0; if (!ab || !ptime) return EINVAL; lock_write_get(ab->lock); now = tmr_jiffies(); if (!ab->ts) ab->ts = now; if (now < ab->ts) { err = ETIMEDOUT; goto out; } ab->ts += ptime; out: lock_rel(ab->lock); if (!err) aubuf_read(ab, p, sz); return err; } /** * Flush the audio buffer * * @param ab Audio buffer */ void aubuf_flush(struct aubuf *ab) { if (!ab) return; lock_write_get(ab->lock); list_flush(&ab->afl); ab->filling = true; ab->cur_sz = 0; ab->ts = 0; lock_rel(ab->lock); } /** * Audio buffer debug handler, use with fmt %H * * @param pf Print function * @param ab Audio buffer * * @return 0 if success, otherwise errorcode */ int aubuf_debug(struct re_printf *pf, const struct aubuf *ab) { int err; if (!ab) return 0; lock_read_get(ab->lock); err = re_hprintf(pf, "wish_sz=%zu cur_sz=%zu filling=%d", ab->wish_sz, ab->cur_sz, ab->filling); #if AUBUF_DEBUG err |= re_hprintf(pf, " [overrun=%zu underrun=%zu]", ab->stats.or, ab->stats.ur); #endif lock_rel(ab->lock); return err; } /** * Get the current number of bytes in the audio buffer * * @param ab Audio buffer * * @return Number of bytes in the audio buffer */ size_t aubuf_cur_size(const struct aubuf *ab) { size_t sz; if (!ab) return 0; lock_read_get(ab->lock); sz = ab->cur_sz; lock_rel(ab->lock); return sz; } rem-0.6.0/src/aubuf/mod.mk000066400000000000000000000001071337577470400153200ustar00rootroot00000000000000# # mod.mk # # Copyright (C) 2010 Creytiv.com # SRCS += aubuf/aubuf.c rem-0.6.0/src/auconv/000077500000000000000000000000001337577470400144035ustar00rootroot00000000000000rem-0.6.0/src/auconv/auconv.c000066400000000000000000000035161337577470400160470ustar00rootroot00000000000000/** * @file auconv.c Audio sample format converter * * Copyright (C) 2010 Creytiv.com */ #include #include #include #include static inline float ausamp_short2float(int16_t in) { float out; out = (float) (in / (1.0 * 0x8000)); return out; } static inline int16_t ausamp_float2short(float in) { double value; int16_t out; value = in * (8.0 * 0x10000000); if (value >= (1.0 * 0x7fffffff)) { out = 32767; } else if (value <= (-8.0 * 0x10000000)) { out = -32768; } else out = (short) (lrint (value) >> 16); return out; } void auconv_from_s16(enum aufmt dst_fmt, void *dst_sampv, const int16_t *src_sampv, size_t sampc) { float *f; uint8_t *b; size_t i; if (!dst_sampv || !src_sampv || !sampc) return; switch (dst_fmt) { case AUFMT_FLOAT: f = dst_sampv; for (i=0; i> 8; b[3*i+1] = s & 0xff; b[3*i+0] = 0; } break; default: (void)re_fprintf(stderr, "auconv: sample format %d (%s)" " not supported\n", dst_fmt, aufmt_name(dst_fmt)); return; } } void auconv_to_s16(int16_t *dst_sampv, enum aufmt src_fmt, void *src_sampv, size_t sampc) { float *f; uint8_t *b; size_t i; if (!dst_sampv || !src_sampv || !sampc) return; switch (src_fmt) { case AUFMT_FLOAT: f = src_sampv; for (i=0; i #include #include #include #include "aufile.h" /** Audio file state */ struct aufile { struct aufile_prm prm; enum aufile_mode mode; size_t datasize; size_t nread; size_t nwritten; FILE *f; }; static int wavfmt_to_aufmt(enum wavfmt fmt, uint16_t bps) { switch (fmt) { case WAVE_FMT_PCM: if (bps != 16) return -1; return AUFMT_S16LE; case WAVE_FMT_ALAW: if (bps != 8) return -1; return AUFMT_PCMA; case WAVE_FMT_ULAW: if (bps != 8) return -1; return AUFMT_PCMU; default: return -1; } } static enum wavfmt aufmt_to_wavfmt(enum aufmt fmt) { switch (fmt) { case AUFMT_S16LE: return WAVE_FMT_PCM; case AUFMT_PCMA: return WAVE_FMT_ALAW; case AUFMT_PCMU: return WAVE_FMT_ULAW; default: return -1; } } static uint16_t aufmt_to_bps(enum aufmt fmt) { switch (fmt) { case AUFMT_S16LE: return 16; case AUFMT_PCMA: return 8; case AUFMT_PCMU: return 8; default: return 0; } } static void destructor(void *arg) { struct aufile *af = arg; if (!af->f) return; /* Update WAV header in write-mode */ if (af->mode == AUFILE_WRITE && af->nwritten > 0) { rewind(af->f); (void)wav_header_encode(af->f, aufmt_to_wavfmt(af->prm.fmt), af->prm.channels, af->prm.srate, aufmt_to_bps(af->prm.fmt), af->nwritten); } (void)fclose(af->f); } /** * Open a WAVE file for reading or writing * * Supported formats: 16-bit PCM, A-law, U-law * * @param afp Pointer to allocated Audio file * @param prm Audio format of the file * @param filename Filename of the WAV-file to load * @param mode Read or write mode * * @return 0 if success, otherwise errorcode */ int aufile_open(struct aufile **afp, struct aufile_prm *prm, const char *filename, enum aufile_mode mode) { struct wav_fmt fmt; struct aufile *af; int aufmt; int err; if (!afp || !filename || (mode == AUFILE_WRITE && !prm)) return EINVAL; af = mem_zalloc(sizeof(*af), destructor); if (!af) return ENOMEM; af->mode = mode; af->f = fopen(filename, mode == AUFILE_READ ? "rb" : "wb"); if (!af->f) { err = errno; goto out; } switch (mode) { case AUFILE_READ: err = wav_header_decode(&fmt, &af->datasize, af->f); if (err) goto out; aufmt = wavfmt_to_aufmt(fmt.format, fmt.bps); if (aufmt < 0) { err = ENOSYS; goto out; } if (prm) { prm->srate = fmt.srate; prm->channels = (uint8_t)fmt.channels; prm->fmt = aufmt; } break; case AUFILE_WRITE: af->prm = *prm; err = wav_header_encode(af->f, aufmt_to_wavfmt(prm->fmt), prm->channels, prm->srate, aufmt_to_bps(prm->fmt), 0); break; default: err = ENOSYS; break; } out: if (err) mem_deref(af); else *afp = af; return err; } /** * Read PCM-samples from a WAV file * * @param af Audio-file * @param p Read buffer * @param sz Size of buffer, on return contains actual read * * @return 0 if success, otherwise errorcode */ int aufile_read(struct aufile *af, uint8_t *p, size_t *sz) { size_t n; if (!af || !p || !sz || af->mode != AUFILE_READ) return EINVAL; if (af->nread >= af->datasize) { *sz = 0; return 0; } n = min(*sz, af->datasize - af->nread); n = fread(p, 1, n, af->f); if (ferror(af->f)) return errno; *sz = n; af->nread += n; return 0; } /** * Write PCM-samples to a WAV file * * @param af Audio-file * @param p Write buffer * @param sz Size of buffer * * @return 0 if success, otherwise errorcode */ int aufile_write(struct aufile *af, const uint8_t *p, size_t sz) { if (!af || !p || !sz || af->mode != AUFILE_WRITE) return EINVAL; if (1 != fwrite(p, sz, 1, af->f)) return ferror(af->f); af->nwritten += sz; return 0; } rem-0.6.0/src/aufile/aufile.h000066400000000000000000000010631337577470400157730ustar00rootroot00000000000000/** * @file aufile.h Audio File -- internal API * * Copyright (C) 2010 Creytiv.com */ enum wavfmt { WAVE_FMT_PCM = 0x0001, WAVE_FMT_ALAW = 0x0006, WAVE_FMT_ULAW = 0x0007, }; /** WAVE format sub-chunk */ struct wav_fmt { uint16_t format; uint16_t channels; uint32_t srate; uint32_t byterate; uint16_t block_align; uint16_t bps; uint16_t extra; }; int wav_header_encode(FILE *f, uint16_t format, uint16_t channels, uint32_t srate, uint16_t bps, size_t bytes); int wav_header_decode(struct wav_fmt *fmt, size_t *datasize, FILE *f); rem-0.6.0/src/aufile/mod.mk000066400000000000000000000001371337577470400154660ustar00rootroot00000000000000# # mod.mk # # Copyright (C) 2010 Creytiv.com # SRCS += aufile/aufile.c SRCS += aufile/wave.c rem-0.6.0/src/aufile/wave.c000066400000000000000000000070271337577470400154710ustar00rootroot00000000000000/** * @file wave.c WAVE format encoding and decoding * * Copyright (C) 2010 Creytiv.com */ #include #include #include #include #include "aufile.h" enum { WAVE_FMT_SIZE = 16 }; /** WAV-file chunk */ struct wav_chunk { uint8_t id[4]; uint32_t size; }; static int write_u16(FILE *f, uint16_t v) { v = sys_htols(v); if (1 != fwrite(&v, sizeof(v), 1, f)) return ferror(f); return 0; } static int write_u32(FILE *f, uint32_t v) { v = sys_htoll(v); if (1 != fwrite(&v, sizeof(v), 1, f)) return ferror(f); return 0; } static int read_u16(FILE *f, uint16_t *v) { uint16_t vle; if (1 != fread(&vle, sizeof(vle), 1, f)) return ferror(f); *v = sys_ltohs(vle); return 0; } static int read_u32(FILE *f, uint32_t *v) { uint32_t vle; if (1 != fread(&vle, sizeof(vle), 1, f)) return ferror(f); *v = sys_ltohl(vle); return 0; } static int chunk_encode(FILE *f, const char *id, size_t sz) { if (1 != fwrite(id, 4, 1, f)) return ferror(f); return write_u32(f, (uint32_t)sz); } static int chunk_decode(struct wav_chunk *chunk, FILE *f) { if (1 != fread(chunk->id, sizeof(chunk->id), 1, f)) return ferror(f); return read_u32(f, &chunk->size); } int wav_header_encode(FILE *f, uint16_t format, uint16_t channels, uint32_t srate, uint16_t bps, size_t bytes) { int err; err = chunk_encode(f, "RIFF", 36 + bytes); if (err) return err; if (1 != fwrite("WAVE", 4, 1, f)) return ferror(f); err = chunk_encode(f, "fmt ", WAVE_FMT_SIZE); if (err) return err; err = write_u16(f, format); err |= write_u16(f, channels); err |= write_u32(f, srate); err |= write_u32(f, srate * channels * bps / 8); err |= write_u16(f, channels * bps / 8); err |= write_u16(f, bps); if (err) return err; return chunk_encode(f, "data", bytes); } int wav_header_decode(struct wav_fmt *fmt, size_t *datasize, FILE *f) { struct wav_chunk header, format, chunk; uint8_t rifftype[4]; /* "WAVE" */ int err = 0; err = chunk_decode(&header, f); if (err) return err; if (memcmp(header.id, "RIFF", 4)) { (void)re_fprintf(stderr, "aufile: expected RIFF (%b)\n", header.id, sizeof(header.id)); return EBADMSG; } if (1 != fread(rifftype, sizeof(rifftype), 1, f)) return ferror(f); if (memcmp(rifftype, "WAVE", 4)) { (void)re_fprintf(stderr, "aufile: expected WAVE (%b)\n", rifftype, sizeof(rifftype)); return EBADMSG; } err = chunk_decode(&format, f); if (err) return err; if (memcmp(format.id, "fmt ", 4)) { (void)re_fprintf(stderr, "aufile: expected fmt (%b)\n", format.id, sizeof(format.id)); return EBADMSG; } if (format.size < WAVE_FMT_SIZE) return EBADMSG; err = read_u16(f, &fmt->format); err |= read_u16(f, &fmt->channels); err |= read_u32(f, &fmt->srate); err |= read_u32(f, &fmt->byterate); err |= read_u16(f, &fmt->block_align); err |= read_u16(f, &fmt->bps); if (err) return err; /* skip any extra bytes */ if (format.size >= (WAVE_FMT_SIZE + 2)) { err = read_u16(f, &fmt->extra); if (err) return err; if (fmt->extra > 0) { if (fseek(f, fmt->extra, SEEK_CUR)) return errno; } } /* fast forward to "data" chunk */ for (;;) { err = chunk_decode(&chunk, f); if (err) return err; if (chunk.size > header.size) { (void)re_fprintf(stderr, "chunk size too large" " (%u > %u)\n", chunk.size, header.size); return EBADMSG; } if (0 == memcmp(chunk.id, "data", 4)) { *datasize = chunk.size; break; } if (fseek(f, chunk.size, SEEK_CUR) < 0) return errno; } return 0; } rem-0.6.0/src/aumix/000077500000000000000000000000001337577470400142335ustar00rootroot00000000000000rem-0.6.0/src/aumix/aumix.c000066400000000000000000000160331337577470400155250ustar00rootroot00000000000000/** * @file aumix.c Audio Mixer * * Copyright (C) 2010 Creytiv.com */ #define _BSD_SOURCE 1 #define _DEFAULT_SOURCE 1 #include #include #include #include #include #include #include #include /** Defines an Audio mixer */ struct aumix { pthread_mutex_t mutex; pthread_cond_t cond; struct list srcl; pthread_t thread; struct aufile *af; uint32_t ptime; uint32_t frame_size; uint32_t srate; uint8_t ch; bool run; }; /** Defines an Audio mixer source */ struct aumix_source { struct le le; int16_t *frame; struct aubuf *aubuf; struct aumix *mix; aumix_frame_h *fh; void *arg; }; static void dummy_frame_handler(const int16_t *sampv, size_t sampc, void *arg) { (void)sampv; (void)sampc; (void)arg; } static void destructor(void *arg) { struct aumix *mix = arg; if (mix->run) { pthread_mutex_lock(&mix->mutex); mix->run = false; pthread_cond_signal(&mix->cond); pthread_mutex_unlock(&mix->mutex); pthread_join(mix->thread, NULL); } mem_deref(mix->af); } static void source_destructor(void *arg) { struct aumix_source *src = arg; if (src->le.list) { pthread_mutex_lock(&src->mix->mutex); list_unlink(&src->le); pthread_mutex_unlock(&src->mix->mutex); } mem_deref(src->aubuf); mem_deref(src->frame); mem_deref(src->mix); } static void *aumix_thread(void *arg) { uint8_t *silence, *frame, *base_frame; struct aumix *mix = arg; int16_t *mix_frame; uint64_t ts = 0; silence = mem_zalloc(mix->frame_size*2, NULL); frame = mem_alloc(mix->frame_size*2, NULL); mix_frame = mem_alloc(mix->frame_size*2, NULL); if (!silence || !frame || !mix_frame) goto out; pthread_mutex_lock(&mix->mutex); while (mix->run) { struct le *le; uint64_t now; if (!mix->srcl.head) { mix->af = mem_deref(mix->af); pthread_cond_wait(&mix->cond, &mix->mutex); ts = 0; } else { pthread_mutex_unlock(&mix->mutex); (void)usleep(4000); pthread_mutex_lock(&mix->mutex); } now = tmr_jiffies(); if (!ts) ts = now; if (ts > now) continue; if (mix->af) { size_t n = mix->frame_size*2; if (aufile_read(mix->af, frame, &n) || n == 0) { mix->af = mem_deref(mix->af); base_frame = silence; } else if (n < mix->frame_size*2) { memset(frame + n, 0, mix->frame_size*2 - n); mix->af = mem_deref(mix->af); base_frame = frame; } else { base_frame = frame; } } else { base_frame = silence; } for (le=mix->srcl.head; le; le=le->next) { struct aumix_source *src = le->data; aubuf_read_samp(src->aubuf, src->frame, mix->frame_size); } for (le=mix->srcl.head; le; le=le->next) { struct aumix_source *src = le->data; struct le *cle; memcpy(mix_frame, base_frame, mix->frame_size*2); for (cle=mix->srcl.head; cle; cle=cle->next) { struct aumix_source *csrc = cle->data; size_t i; #if 1 /* skip self */ if (csrc == src) continue; #endif for (i=0; iframe_size; i++) mix_frame[i] += csrc->frame[i]; } src->fh(mix_frame, mix->frame_size, src->arg); } ts += mix->ptime; } pthread_mutex_unlock(&mix->mutex); out: mem_deref(mix_frame); mem_deref(silence); mem_deref(frame); return NULL; } /** * Allocate a new Audio mixer * * @param mixp Pointer to allocated audio mixer * @param srate Sample rate in [Hz] * @param ch Number of channels * @param ptime Packet time in [ms] * * @return 0 for success, otherwise error code */ int aumix_alloc(struct aumix **mixp, uint32_t srate, uint8_t ch, uint32_t ptime) { struct aumix *mix; int err; if (!mixp || !srate || !ch || !ptime) return EINVAL; mix = mem_zalloc(sizeof(*mix), destructor); if (!mix) return ENOMEM; mix->ptime = ptime; mix->frame_size = srate * ch * ptime / 1000; mix->srate = srate; mix->ch = ch; err = pthread_mutex_init(&mix->mutex, NULL); if (err) goto out; err = pthread_cond_init(&mix->cond, NULL); if (err) goto out; mix->run = true; err = pthread_create(&mix->thread, NULL, aumix_thread, mix); if (err) { mix->run = false; goto out; } out: if (err) mem_deref(mix); else *mixp = mix; return err; } /** * Load audio file for mixer announcements * * @param mix Audio mixer * @param filepath Filename of audio file with complete path * * @return 0 for success, otherwise error code */ int aumix_playfile(struct aumix *mix, const char *filepath) { struct aufile_prm prm; struct aufile *af; int err; if (!mix || !filepath) return EINVAL; err = aufile_open(&af, &prm, filepath, AUFILE_READ); if (err) return err; if (prm.fmt != AUFMT_S16LE || prm.srate != mix->srate || prm.channels != mix->ch) { mem_deref(af); return EINVAL; } pthread_mutex_lock(&mix->mutex); mem_deref(mix->af); mix->af = af; pthread_mutex_unlock(&mix->mutex); return 0; } /** * Count number of audio sources in the audio mixer * * @param mix Audio mixer * * @return Number of audio sources */ uint32_t aumix_source_count(const struct aumix *mix) { if (!mix) return 0; return list_count(&mix->srcl); } /** * Allocate an audio mixer source * * @param srcp Pointer to allocated audio source * @param mix Audio mixer * @param fh Mixer frame handler * @param arg Handler argument * * @return 0 for success, otherwise error code */ int aumix_source_alloc(struct aumix_source **srcp, struct aumix *mix, aumix_frame_h *fh, void *arg) { struct aumix_source *src; size_t sz; int err; if (!srcp || !mix) return EINVAL; src = mem_zalloc(sizeof(*src), source_destructor); if (!src) return ENOMEM; src->mix = mem_ref(mix); src->fh = fh ? fh : dummy_frame_handler; src->arg = arg; sz = mix->frame_size*2; src->frame = mem_alloc(sz, NULL); if (!src->frame) { err = ENOMEM; goto out; } err = aubuf_alloc(&src->aubuf, sz * 6, sz * 12); if (err) goto out; out: if (err) mem_deref(src); else *srcp = src; return err; } /** * Enable/disable aumix source * * @param src Audio mixer source * @param enable True to enable, false to disable */ void aumix_source_enable(struct aumix_source *src, bool enable) { struct aumix *mix; if (!src) return; if (src->le.list && enable) return; if (!src->le.list && !enable) return; mix = src->mix; pthread_mutex_lock(&mix->mutex); if (enable) { list_append(&mix->srcl, &src->le, src); pthread_cond_signal(&mix->cond); } else { list_unlink(&src->le); } pthread_mutex_unlock(&mix->mutex); } /** * Write PCM samples for a given source to the audio mixer * * @param src Audio mixer source * @param sampv PCM samples * @param sampc Number of samples * * @return 0 for success, otherwise error code */ int aumix_source_put(struct aumix_source *src, const int16_t *sampv, size_t sampc) { if (!src || !sampv) return EINVAL; return aubuf_write_samp(src->aubuf, sampv, sampc); } /** * Flush the audio buffer of a given audio mixer source * * @param src Audio mixer source */ void aumix_source_flush(struct aumix_source *src) { if (!src) return; aubuf_flush(src->aubuf); } rem-0.6.0/src/aumix/mod.mk000066400000000000000000000001071337577470400153410ustar00rootroot00000000000000# # mod.mk # # Copyright (C) 2010 Creytiv.com # SRCS += aumix/aumix.c rem-0.6.0/src/auresamp/000077500000000000000000000000001337577470400147255ustar00rootroot00000000000000rem-0.6.0/src/auresamp/mod.mk000066400000000000000000000001131337577470400160300ustar00rootroot00000000000000# # mod.mk # # Copyright (C) 2010 Creytiv.com # SRCS += auresamp/resamp.c rem-0.6.0/src/auresamp/resamp.c000066400000000000000000000136341337577470400163670ustar00rootroot00000000000000/** * @file resamp.c Audio Resampler * * Copyright (C) 2010 Creytiv.com */ #include #include #include #include /* 48kHz sample-rate, 4kHz cutoff (pass 0-3kHz, stop 5-24kHz) */ static const int16_t fir_48_4[] = { 62, -176, -329, -556, -802, -1005, -1090, -985, -636, -23, 826, 1837, 2894, 3859, 4595, 4994, 4994, 4595, 3859, 2894, 1837, 826, -23, -636, -985, -1090, -1005, -802, -556, -329, -176, 62 }; /* 48kHz sample-rate, 8kHz cutoff (pass 0-7kHz, stop 9-24kHz) */ static const int16_t fir_48_8[] = { 238, 198, -123, -738, -1268, -1204, -380, 714, 1164, 376, -1220, -2206, -1105, 2395, 6909, 10069, 10069, 6909, 2395, -1105, -2206, -1220, 376, 1164, 714, -380, -1204, -1268, -738, -123, 198, 238 }; static void upsample_mono2mono(int16_t *outv, const int16_t *inv, size_t inc, unsigned ratio) { unsigned i; while (inc >= 1) { for (i=0; i= 1) { for (i=0; i= 2) { const int16_t s = inv[0]/2 + inv[1]/2; for (i=0; i= 2) { for (i=0; i= ratio) { *outv++ = *inv; inv += ratio; inc -= ratio; } } static void downsample_mono2stereo(int16_t *outv, const int16_t *inv, size_t inc, unsigned ratio) { while (inc >= ratio) { *outv++ = *inv; *outv++ = *inv; inv += ratio; inc -= ratio; } } static void downsample_stereo2mono(int16_t *outv, const int16_t *inv, size_t inc, unsigned ratio) { ratio *= 2; while (inc >= ratio) { *outv++ = inv[0]/2 + inv[1]/2; inv += ratio; inc -= ratio; } } static void downsample_stereo2stereo(int16_t *outv, const int16_t *inv, size_t inc, unsigned ratio) { ratio *= 2; while (inc >= ratio) { *outv++ = inv[0]; *outv++ = inv[1]; inv += ratio; inc -= ratio; } } /** * Initialize a resampler object * * @param rs Resampler to initialize */ void auresamp_init(struct auresamp *rs) { if (!rs) return; memset(rs, 0, sizeof(*rs)); fir_reset(&rs->fir); } /** * Configure a resampler object * * @note The sample rate ratio must be an integer * * @param rs Resampler * @param irate Input sample rate * @param ich Input channel count * @param orate Output sample rate * @param och Output channel count * * @return 0 if success, otherwise error code */ int auresamp_setup(struct auresamp *rs, uint32_t irate, unsigned ich, uint32_t orate, unsigned och) { if (!rs || !irate || !ich || !orate || !och) return EINVAL; if (orate == irate && och == ich) { auresamp_init(rs); return 0; } if (orate >= irate) { if (orate % irate) return ENOTSUP; if (ich == 1 && och == 1) rs->resample = upsample_mono2mono; else if (ich == 1 && och == 2) rs->resample = upsample_mono2stereo; else if (ich == 2 && och == 1) rs->resample = upsample_stereo2mono; else if (ich == 2 && och == 2) rs->resample = upsample_stereo2stereo; else return ENOTSUP; if (!rs->up || orate != rs->orate || och != rs->och) fir_reset(&rs->fir); rs->ratio = orate / irate; rs->up = true; if (orate == irate) { rs->tapv = NULL; rs->tapc = 0; } else if (orate == 48000 && irate == 16000) { rs->tapv = fir_48_8; rs->tapc = ARRAY_SIZE(fir_48_8); } else { rs->tapv = fir_48_4; rs->tapc = ARRAY_SIZE(fir_48_4); } } else { if (irate % orate) return ENOTSUP; if (ich == 1 && och == 1) rs->resample = downsample_mono2mono; else if (ich == 1 && och == 2) rs->resample = downsample_mono2stereo; else if (ich == 2 && och == 1) rs->resample = downsample_stereo2mono; else if (ich == 2 && och == 2) rs->resample = downsample_stereo2stereo; else return ENOTSUP; if (rs->up || irate != rs->irate || ich != rs->ich) fir_reset(&rs->fir); rs->ratio = irate / orate; rs->up = false; if (irate == 48000 && orate == 16000) { rs->tapv = fir_48_8; rs->tapc = ARRAY_SIZE(fir_48_8); } else { rs->tapv = fir_48_4; rs->tapc = ARRAY_SIZE(fir_48_4); } } rs->orate = orate; rs->och = och; rs->irate = irate; rs->ich = ich; return 0; } /** * Resample * * @note When downsampling, the input count must be divisible by rate ratio * * @param rs Resampler * @param outv Output samples * @param outc Output sample count (in/out) * @param inv Input samples * @param inc Input sample count * * @return 0 if success, otherwise error code */ int auresamp(struct auresamp *rs, int16_t *outv, size_t *outc, const int16_t *inv, size_t inc) { size_t incc, outcc; if (!rs || !rs->resample || !outv || !outc || !inv) return EINVAL; incc = inc / rs->ich; if (rs->up) { outcc = incc * rs->ratio; if (*outc < outcc * rs->och) return ENOMEM; rs->resample(outv, inv, inc, rs->ratio); *outc = outcc * rs->och; if (rs->tapv) fir_filter(&rs->fir, outv, outv, *outc, rs->och, rs->tapv, rs->tapc); } else { outcc = incc / rs->ratio; if (*outc < outcc * rs->och || *outc < inc) return ENOMEM; fir_filter(&rs->fir, outv, inv, inc, rs->ich, rs->tapv, rs->tapc); rs->resample(outv, outv, inc, rs->ratio); *outc = outcc * rs->och; } return 0; } rem-0.6.0/src/autone/000077500000000000000000000000001337577470400144035ustar00rootroot00000000000000rem-0.6.0/src/autone/mod.mk000066400000000000000000000001071337577470400155110ustar00rootroot00000000000000# # mod.mk # # Copyright (C) 2010 Creytiv.com # SRCS += autone/tone.c rem-0.6.0/src/autone/tone.c000066400000000000000000000040611337577470400155150ustar00rootroot00000000000000/** * @file tone.c Audio Tones * * Copyright (C) 2010 Creytiv.com */ #include #include #include #include #define SCALE (32767) #define DTMF_AMP (5) #if !defined (M_PI) #define M_PI 3.14159265358979323846264338327 #endif static inline uint32_t digit2lo(int digit) { switch (digit) { case '1': case '2': case '3': case 'A': return 697; case '4': case '5': case '6': case 'B': return 770; case '7': case '8': case '9': case 'C': return 852; case '*': case '0': case '#': case 'D': return 941; default: return 0; } } static inline uint32_t digit2hi(int digit) { switch (digit) { case '1': case '4': case '7': case '*': return 1209; case '2': case '5': case '8': case '0': return 1336; case '3': case '6': case '9': case '#': return 1477; case 'A': case 'B': case 'C': case 'D': return 1633; default: return 0; } } /** * Generate a dual-tone sine wave into a PCM buffer * * @param mb Buffer for PCM samples * @param srate Sample rate in [Hz] * @param f1 Frequency number one * @param l1 Level of f1 from 0-100 * @param f2 Frequency number two * @param l2 Level of f2 from 0-100 * * @return 0 for success, otherwise error code */ int autone_sine(struct mbuf *mb, uint32_t srate, uint32_t f1, int l1, uint32_t f2, int l2) { double d1, d2; uint32_t i; int err = 0; if (!mb || !srate) return EINVAL; d1 = 1.0f * f1 / srate; d2 = 1.0f * f2 / srate; for (i=0; i #include #include #include #include #include #include #define AVC_CONFIG_VERSION 1 #define SPS_MASK 0xe0 int avc_config_encode(struct mbuf *mb, uint8_t profile_ind, uint8_t profile_compat, uint8_t level_ind, uint16_t sps_length, const uint8_t *sps, uint16_t pps_length, const uint8_t *pps) { int err; if (!mb || !sps || !pps) return EINVAL; err = mbuf_write_u8(mb, AVC_CONFIG_VERSION); err |= mbuf_write_u8(mb, profile_ind); err |= mbuf_write_u8(mb, profile_compat); err |= mbuf_write_u8(mb, level_ind); err |= mbuf_write_u8(mb, 0xfc | (4-1)); /* SPS */ err |= mbuf_write_u8(mb, SPS_MASK | 1); err |= mbuf_write_u16(mb, htons(sps_length)); err |= mbuf_write_mem(mb, sps, sps_length); /* PPS */ err |= mbuf_write_u8(mb, 1); err |= mbuf_write_u16(mb, htons(pps_length)); err |= mbuf_write_mem(mb, pps, pps_length); return err; } int avc_config_decode(struct avc_config *conf, struct mbuf *mb) { uint8_t version, length_size, count; if (!conf || !mb) return EINVAL; if (mbuf_get_left(mb) < 5) return EBADMSG; version = mbuf_read_u8(mb); conf->profile_ind = mbuf_read_u8(mb); conf->profile_compat = mbuf_read_u8(mb); conf->level_ind = mbuf_read_u8(mb); length_size = mbuf_read_u8(mb) & 0x03; if (version != AVC_CONFIG_VERSION || length_size != 3) return EPROTO; /* SPS */ if (mbuf_get_left(mb) < 3) return EBADMSG; count = mbuf_read_u8(mb) & 0x1f; conf->sps_len = ntohs(mbuf_read_u16(mb)); if (count != 1 || conf->sps_len > sizeof(conf->sps)) return EOVERFLOW; if (mbuf_get_left(mb) < conf->sps_len) return EBADMSG; mbuf_read_mem(mb, conf->sps, conf->sps_len); /* PPS */ if (mbuf_get_left(mb) < 3) return EBADMSG; count = mbuf_read_u8(mb); conf->pps_len = ntohs(mbuf_read_u16(mb)); if (count != 1 || conf->pps_len > sizeof(conf->pps)) return EOVERFLOW; if (mbuf_get_left(mb) < conf->pps_len) return EBADMSG; mbuf_read_mem(mb, conf->pps, conf->pps_len); return 0; } rem-0.6.0/src/avc/mod.mk000066400000000000000000000001061337577470400147660ustar00rootroot00000000000000# # mod.mk # # Copyright (C) 2010 Creytiv.com # SRCS += avc/config.c rem-0.6.0/src/dtmf/000077500000000000000000000000001337577470400140425ustar00rootroot00000000000000rem-0.6.0/src/dtmf/dec.c000066400000000000000000000071031337577470400147420ustar00rootroot00000000000000/** * @file dtmf/dec.c DTMF Decoder * * Copyright (C) 2010 Creytiv.com */ #include #include #include #define BLOCK_SIZE 102 /* At 8kHz sample rate */ #define THRESHOLD 16439.10631 /* -42dBm0 / bsize^2 */ #define NORMAL_TWIST 6.309573 /* 8dB */ #define REVERSE_TWIST 2.511886 /* 4dB */ #define RELATIVE_KEY 6.309573 /* 8dB */ #define RELATIVE_SUM 0.822243 /* -0.85dB */ static const double fx[4] = { 1209.0, 1336.0, 1477.0, 1633.0 }; static const double fy[4] = { 697.0, 770.0, 852.0, 941.0 }; static const char keyv[4][4] = {{'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'}}; struct dtmf_dec { struct goertzel gx[4], gy[4]; dtmf_dec_h *dech; void *arg; double threshold; double energy; double efac; unsigned bsize; unsigned bidx; char digit, digit1; }; static char decode_digit(struct dtmf_dec *dec) { unsigned i, x = 0, y = 0; double ex[4], ey[4]; for (i=0; i<4; i++) { ex[i] = goertzel_result(&dec->gx[i]); ey[i] = goertzel_result(&dec->gy[i]); if (ex[i] > ex[x]) x = i; if (ey[i] > ey[y]) y = i; } if (ex[x] < dec->threshold || ey[y] < dec->threshold) return 0; if (ex[x] > ey[y] * NORMAL_TWIST || ey[y] > ex[x] * REVERSE_TWIST) return 0; for (i=0; i<4; i++) { if ((i != x && ex[i] * RELATIVE_KEY > ex[x]) || (i != y && ey[i] * RELATIVE_KEY > ey[y])) return 0; } if ((ex[x] + ey[y]) < dec->efac * dec->energy) return 0; return keyv[y][x]; } /** * Allocate a DTMF decoder instance * * @param decp Pointer to allocated decoder * @param srate Sample rate * @param ch Number of channels * @param dech Decode handler * @param arg Handler argument * * @return 0 if success, otherwise errorcode */ int dtmf_dec_alloc(struct dtmf_dec **decp, unsigned srate, unsigned ch, dtmf_dec_h *dech, void *arg) { struct dtmf_dec *dec; if (!decp || !dech || !srate || !ch) return EINVAL; dec = mem_zalloc(sizeof(*dec), NULL); if (!dec) return ENOMEM; dtmf_dec_reset(dec, srate, ch); dec->dech = dech; dec->arg = arg; *decp = dec; return 0; } /** * Reset and configure DTMF decoder state * * @param dec DTMF decoder * @param srate Sample rate * @param ch Number of channels */ void dtmf_dec_reset(struct dtmf_dec *dec, unsigned srate, unsigned ch) { unsigned i; if (!dec || !srate || !ch) return; srate *= ch; for (i=0; i<4; i++) { goertzel_init(&dec->gx[i], fx[i], srate); goertzel_init(&dec->gy[i], fy[i], srate); } dec->bsize = (BLOCK_SIZE * srate) / 8000; dec->threshold = THRESHOLD * dec->bsize * dec->bsize; dec->efac = RELATIVE_SUM * dec->bsize; dec->energy = 0.0; dec->bidx = 0; dec->digit = 0; dec->digit1 = 0; } /** * Decode DTMF from input audio samples * * @param dec DTMF decoder * @param sampv Buffer with audio samples * @param sampc Number of samples */ void dtmf_dec_probe(struct dtmf_dec *dec, const int16_t *sampv, size_t sampc) { size_t i; if (!dec || !sampv) return; for (i=0; igx[j], sampv[i]); goertzel_update(&dec->gy[j], sampv[i]); } dec->energy += sampv[i] * sampv[i]; if (++dec->bidx < dec->bsize) continue; digit0 = decode_digit(dec); if (digit0 != dec->digit && dec->digit1 != dec->digit) { dec->digit = digit0; if (digit0 != dec->digit1) dec->digit = 0; if (dec->digit) dec->dech(dec->digit, dec->arg); } dec->digit1 = digit0; dec->energy = 0.0; dec->bidx = 0; } } rem-0.6.0/src/dtmf/mod.mk000066400000000000000000000001041337577470400151450ustar00rootroot00000000000000# # mod.mk # # Copyright (C) 2011 Creytiv.com # SRCS += dtmf/dec.c rem-0.6.0/src/fir/000077500000000000000000000000001337577470400136705ustar00rootroot00000000000000rem-0.6.0/src/fir/fir.c000066400000000000000000000024131337577470400146140ustar00rootroot00000000000000/** * @file fir.c FIR -- Finite Impulse Response * * Copyright (C) 2010 Creytiv.com */ #include #include #include /** * Reset the FIR-filter * * @param fir FIR-filter state */ void fir_reset(struct fir *fir) { if (!fir) return; memset(fir, 0, sizeof(*fir)); } /** * Process samples with the FIR filter * * @note product of channel and tap-count must be power of two * * @param fir FIR filter * @param outv Output samples * @param inv Input samples * @param inc Number of samples * @param ch Number of channels * @param tapv Filter taps * @param tapc Number of taps */ void fir_filter(struct fir *fir, int16_t *outv, const int16_t *inv, size_t inc, unsigned ch, const int16_t *tapv, size_t tapc) { const unsigned hmask = (ch * (unsigned)tapc) - 1; if (!fir || !outv || !inv || !ch || !tapv || !tapc) return; if (hmask >= ARRAY_SIZE(fir->history) || hmask & (hmask+1)) return; while (inc--) { int64_t acc = 0; unsigned i, j; fir->history[fir->index & hmask] = *inv++; for (i=0, j=fir->index++; ihistory[j & hmask] * tapv[i]; if (acc > 0x3fffffff) acc = 0x3fffffff; else if (acc < -0x40000000) acc = -0x40000000; *outv++ = (int16_t)(acc>>15); } } rem-0.6.0/src/fir/mod.mk000066400000000000000000000001031337577470400147720ustar00rootroot00000000000000# # mod.mk # # Copyright (C) 2011 Creytiv.com # SRCS += fir/fir.c rem-0.6.0/src/g711/000077500000000000000000000000001337577470400135675ustar00rootroot00000000000000rem-0.6.0/src/g711/g711.c000066400000000000000000001212111337577470400144100ustar00rootroot00000000000000/** * @file g711.c G.711 codec * * Copyright (C) 2010 Creytiv.com */ #include #include const uint8_t g711_l2u[4096] = { 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, 0xef, 0xef, 0xee, 0xee, 0xed, 0xed, 0xec, 0xec, 0xeb, 0xeb, 0xea, 0xea, 0xe9, 0xe9, 0xe8, 0xe8, 0xe7, 0xe7, 0xe6, 0xe6, 0xe5, 0xe5, 0xe4, 0xe4, 0xe3, 0xe3, 0xe2, 0xe2, 0xe1, 0xe1, 0xe0, 0xe0, 0xdf, 0xdf, 0xdf, 0xdf, 0xde, 0xde, 0xde, 0xde, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xdb, 0xdb, 0xdb, 0xdb, 0xda, 0xda, 0xda, 0xda, 0xd9, 0xd9, 0xd9, 0xd9, 0xd8, 0xd8, 0xd8, 0xd8, 0xd7, 0xd7, 0xd7, 0xd7, 0xd6, 0xd6, 0xd6, 0xd6, 0xd5, 0xd5, 0xd5, 0xd5, 0xd4, 0xd4, 0xd4, 0xd4, 0xd3, 0xd3, 0xd3, 0xd3, 0xd2, 0xd2, 0xd2, 0xd2, 0xd1, 0xd1, 0xd1, 0xd1, 0xd0, 0xd0, 0xd0, 0xd0, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 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, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, }; const uint8_t g711_l2A[2048] = { 0xd5, 0xd4, 0xd7, 0xd6, 0xd1, 0xd0, 0xd3, 0xd2, 0xdd, 0xdc, 0xdf, 0xde, 0xd9, 0xd8, 0xdb, 0xda, 0xc5, 0xc4, 0xc7, 0xc6, 0xc1, 0xc0, 0xc3, 0xc2, 0xcd, 0xcc, 0xcf, 0xce, 0xc9, 0xc8, 0xcb, 0xca, 0xf5, 0xf5, 0xf4, 0xf4, 0xf7, 0xf7, 0xf6, 0xf6, 0xf1, 0xf1, 0xf0, 0xf0, 0xf3, 0xf3, 0xf2, 0xf2, 0xfd, 0xfd, 0xfc, 0xfc, 0xff, 0xff, 0xfe, 0xfe, 0xf9, 0xf9, 0xf8, 0xf8, 0xfb, 0xfb, 0xfa, 0xfa, 0xe5, 0xe5, 0xe5, 0xe5, 0xe4, 0xe4, 0xe4, 0xe4, 0xe7, 0xe7, 0xe7, 0xe7, 0xe6, 0xe6, 0xe6, 0xe6, 0xe1, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2, 0xed, 0xed, 0xed, 0xed, 0xec, 0xec, 0xec, 0xec, 0xef, 0xef, 0xef, 0xef, 0xee, 0xee, 0xee, 0xee, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8, 0xe8, 0xe8, 0xe8, 0xeb, 0xeb, 0xeb, 0xeb, 0xea, 0xea, 0xea, 0xea, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, }; const int16_t g711_u2l[256] = { -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956, -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764, -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412, -11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316, -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, -876, -844, -812, -780, -748, -716, -684, -652, -620, -588, -556, -524, -492, -460, -428, -396, -372, -356, -340, -324, -308, -292, -276, -260, -244, -228, -212, -196, -180, -164, -148, -132, -120, -112, -104, -96, -88, -80, -72, -64, -56, -48, -40, -32, -24, -16, -8, -2, 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, 876, 844, 812, 780, 748, 716, 684, 652, 620, 588, 556, 524, 492, 460, 428, 396, 372, 356, 340, 324, 308, 292, 276, 260, 244, 228, 212, 196, 180, 164, 148, 132, 120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 2, }; const int16_t g711_A2l[256] = { -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, -22016,-20992,-24064,-23040,-17920,-16896,-19968,-18944, -30208,-29184,-32256,-31232,-26112,-25088,-28160,-27136, -11008,-10496,-12032,-11520, -8960, -8448, -9984, -9472, -15104,-14592,-16128,-15616,-13056,-12544,-14080,-13568, -344, -328, -376, -360, -280, -264, -312, -296, -472, -456, -504, -488, -408, -392, -440, -424, -88, -72, -120, -104, -24, -8, -56, -40, -216, -200, -248, -232, -152, -136, -184, -168, -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, -688, -656, -752, -720, -560, -528, -624, -592, -944, -912, -1008, -976, -816, -784, -880, -848, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848, }; rem-0.6.0/src/g711/mod.mk000066400000000000000000000001051337577470400146730ustar00rootroot00000000000000# # mod.mk # # Copyright (C) 2010 Creytiv.com # SRCS += g711/g711.c rem-0.6.0/src/goertzel/000077500000000000000000000000001337577470400147435ustar00rootroot00000000000000rem-0.6.0/src/goertzel/goertzel.c000066400000000000000000000016121337577470400167420ustar00rootroot00000000000000/** * @file goertzel.c Goertzel algorithm * * Copyright (C) 2010 Creytiv.com */ #include #include #include #define PI 3.14159265358979323846264338327 /** * Initialize goertzel state * * @param g Goertzel state * @param freq Target frequency * @param srate Sample rate */ void goertzel_init(struct goertzel *g, double freq, unsigned srate) { g->q1 = 0.0; g->q2 = 0.0; g->coef = 2.0 * cos(2.0 * PI * (freq/(double)srate)); } /** * Reset goertzel state * * @param g Goertzel state */ void goertzel_reset(struct goertzel *g) { g->q1 = 0.0; g->q2 = 0.0; } /** * Calculate result and reset state * * @param g Goertzel state * * @return Result value */ double goertzel_result(struct goertzel *g) { double res; goertzel_update(g, 0); res = g->q1*g->q1 + g->q2*g->q2 - g->q1*g->q2*g->coef; goertzel_reset(g); return res * 2.0; } rem-0.6.0/src/goertzel/mod.mk000066400000000000000000000001151337577470400160500ustar00rootroot00000000000000# # mod.mk # # Copyright (C) 2011 Creytiv.com # SRCS += goertzel/goertzel.c rem-0.6.0/src/vid/000077500000000000000000000000001337577470400136725ustar00rootroot00000000000000rem-0.6.0/src/vid/draw.c000066400000000000000000000071171337577470400150010ustar00rootroot00000000000000/** * @file draw.c Video Frame primitive drawing routines * * Copyright (C) 2010 Creytiv.com */ #include #include #include /** * Draw a pixel to a video frame * * @param f Video frame * @param x Pixel X-position * @param y Pixel Y-position * @param r Red color component * @param g Green color component * @param b Blue color component */ void vidframe_draw_point(struct vidframe *f, unsigned x, unsigned y, uint8_t r, uint8_t g, uint8_t b) { uint8_t *yp, *up, *vp; uint32_t *p; if (!f) return; if (x >= f->size.w || y >= f->size.h) return; switch (f->fmt) { case VID_FMT_YUV420P: yp = f->data[0] + f->linesize[0] * y + x; up = f->data[1] + f->linesize[1] * (y/2) + x/2; vp = f->data[2] + f->linesize[2] * (y/2) + x/2; yp[0] = rgb2y(r, g, b); up[0] = rgb2u(r, g, b); vp[0] = rgb2v(r, g, b); break; case VID_FMT_YUV444P: yp = f->data[0] + f->linesize[0] * y + x; up = f->data[1] + f->linesize[1] * y + x; vp = f->data[2] + f->linesize[2] * y + x; yp[0] = rgb2y(r, g, b); up[0] = rgb2u(r, g, b); vp[0] = rgb2v(r, g, b); break; case VID_FMT_RGB32: p = (void *)(f->data[0] + f->linesize[0] * y + x*4); *p = (uint32_t)r << 16 | (uint32_t)g << 8 | b; break; default: (void)re_fprintf(stderr, "vidframe_draw_point:" " unsupported format %s\n", vidfmt_name(f->fmt)); break; } } /** * Draw a horizontal line * * @param f Video frame * @param x0 Origin X-position * @param y0 Origin Y-position * @param w Line width * @param r Red color component * @param g Green color component * @param b Blue color component */ void vidframe_draw_hline(struct vidframe *f, unsigned x0, unsigned y0, unsigned w, uint8_t r, uint8_t g, uint8_t b) { uint8_t y, u, v; if (!f) return; if (x0 >= f->size.w || y0 >= f->size.h) return; w = min(w, f->size.w-x0); y = rgb2y(r, g, b); u = rgb2u(r, g, b); v = rgb2v(r, g, b); switch (f->fmt) { case VID_FMT_YUV420P: memset(f->data[0] + y0 *f->linesize[0] + x0, y, w); memset(f->data[1] + (y0/2)*f->linesize[1] + x0/2, u, w/2); memset(f->data[2] + (y0/2)*f->linesize[2] + x0/2, v, w/2); break; case VID_FMT_YUV444P: memset(f->data[0] + y0*f->linesize[0] + x0, y, w); memset(f->data[1] + y0*f->linesize[1] + x0, u, w); memset(f->data[2] + y0*f->linesize[2] + x0, v, w); break; default: (void)re_fprintf(stderr, "vidframe_draw_hline:" " unsupported format %s\n", vidfmt_name(f->fmt)); break; } } /** * Draw a vertical line * * @param f Video frame * @param x0 Origin X-position * @param y0 Origin Y-position * @param h Line height * @param r Red color component * @param g Green color component * @param b Blue color component */ void vidframe_draw_vline(struct vidframe *f, unsigned x0, unsigned y0, unsigned h, uint8_t r, uint8_t g, uint8_t b) { if (!f) return; while (h--) { vidframe_draw_point(f, x0, y0++, r, g, b); } } /** * Draw a rectangle * * @param f Video frame * @param x0 Origin X-position * @param y0 Origin Y-position * @param w Rectangle width * @param h Rectangle height * @param r Red color component * @param g Green color component * @param b Blue color component */ void vidframe_draw_rect(struct vidframe *f, unsigned x0, unsigned y0, unsigned w, unsigned h, uint8_t r, uint8_t g, uint8_t b) { if (!f) return; vidframe_draw_hline(f, x0, y0, w, r, g, b); vidframe_draw_hline(f, x0, y0+h-1, w, r, g, b); vidframe_draw_vline(f, x0, y0, h, r, g, b); vidframe_draw_vline(f, x0+w-1, y0, h, r, g, b); } rem-0.6.0/src/vid/fmt.c000066400000000000000000000017651337577470400146350ustar00rootroot00000000000000/** * @file vid/fmt.c Video Formats * * Copyright (C) 2010 Creytiv.com */ #include #include /** Video format description table */ const struct vidfmt_desc vidfmt_descv[VID_FMT_N] = { {"yuv420p", 3, 3, { {0, 1}, {1, 1}, {2, 1}, {0, 0} } }, {"yuyv422", 1, 3, { {0, 2}, {0, 4}, {0, 4}, {0, 0} } }, {"uyvy422", 1, 3, { {0, 2}, {0, 4}, {0, 4}, {0, 0} } }, {"rgb32", 1, 4, { {0, 4}, {0, 4}, {0, 4}, {0, 4} } }, {"argb", 1, 4, { {0, 4}, {0, 4}, {0, 4}, {0, 4} } }, {"rgb565", 1, 3, { {0, 2}, {0, 2}, {0, 2}, {0, 0} } }, {"rgb555", 1, 3, { {0, 2}, {0, 2}, {0, 2}, {0, 0} } }, {"nv12", 3, 2, { {0, 1}, {1, 2}, {1, 2}, {0, 0} } }, {"nv21", 3, 2, { {0, 1}, {1, 2}, {1, 2}, {0, 0} } }, {"yuv444p", 3, 3, { {0, 1}, {1, 1}, {2, 1}, {0, 0} } }, }; /** * Get the name of a video format * * @param fmt Video format * * @return Name of the video format */ const char *vidfmt_name(enum vidfmt fmt) { if (fmt >= VID_FMT_N) return "???"; return vidfmt_descv[fmt].name; } rem-0.6.0/src/vid/frame.c000066400000000000000000000147241337577470400151400ustar00rootroot00000000000000/** * @file frame.c Video Frame * * Copyright (C) 2010 Creytiv.com */ #include #include #include /** * Get video frame buffer size * * @param fmt Video pixel format * @param sz Size of video frame * * @return Number of bytes */ size_t vidframe_size(enum vidfmt fmt, const struct vidsz *sz) { if (!sz) return 0; switch (fmt) { case VID_FMT_YUV420P: return sz->w * sz->h * 3 / 2; case VID_FMT_YUYV422: return sz->w * sz->h * 2; case VID_FMT_UYVY422: return sz->w * sz->h * 2; case VID_FMT_RGB32: return sz->w * sz->h * 4; case VID_FMT_ARGB: return sz->w * sz->h * 4; case VID_FMT_RGB565: return sz->w * sz->h * 2; case VID_FMT_RGB555: return sz->w * sz->h * 2; case VID_FMT_NV12: return sz->w * sz->h * 3 / 2; case VID_FMT_NV21: return sz->w * sz->h * 3 / 2; case VID_FMT_YUV444P: return sz->w * sz->h * 3; default: return 0; } } /** * Initialize a video frame * * @param vf Video frame * @param fmt Video pixel format * @param sz Size of video frame * @param data Pointer to video planes * @param linesize Pointer to linesizes */ void vidframe_init(struct vidframe *vf, enum vidfmt fmt, const struct vidsz *sz, void *data[4], unsigned linesize[4]) { int i; if (!vf || !sz || !data || !linesize) return; for (i=0; i<4; i++) { vf->data[i] = data[i]; vf->linesize[i] = linesize[i]; } vf->size = *sz; vf->fmt = fmt; } /** * Initialize a video frame from a buffer * * @param vf Video frame * @param fmt Video pixel format * @param sz Size of video frame * @param buf Frame buffer */ void vidframe_init_buf(struct vidframe *vf, enum vidfmt fmt, const struct vidsz *sz, uint8_t *buf) { unsigned w, h; if (!vf || !sz || !buf) return; w = (sz->w + 1) >> 1; h = (sz->h + 1) >> 1; memset(vf->linesize, 0, sizeof(vf->linesize)); memset(vf->data, 0, sizeof(vf->data)); switch (fmt) { case VID_FMT_YUV420P: vf->linesize[0] = sz->w; vf->linesize[1] = w; vf->linesize[2] = w; vf->data[0] = buf; vf->data[1] = vf->data[0] + vf->linesize[0] * sz->h; vf->data[2] = vf->data[1] + vf->linesize[1] * h; break; case VID_FMT_YUYV422: case VID_FMT_UYVY422: vf->linesize[0] = sz->w * 2; vf->data[0] = buf; break; case VID_FMT_RGB32: case VID_FMT_ARGB: vf->linesize[0] = sz->w * 4; vf->data[0] = buf; break; case VID_FMT_RGB565: case VID_FMT_RGB555: vf->linesize[0] = sz->w * 2; vf->data[0] = buf; break; case VID_FMT_NV12: case VID_FMT_NV21: vf->linesize[0] = sz->w; vf->linesize[1] = w*2; vf->data[0] = buf; vf->data[1] = vf->data[0] + vf->linesize[0] * sz->h; break; case VID_FMT_YUV444P: vf->linesize[0] = sz->w; vf->linesize[1] = sz->w; vf->linesize[2] = sz->w; vf->data[0] = buf; vf->data[1] = vf->data[0] + vf->linesize[0] * sz->h; vf->data[2] = vf->data[1] + vf->linesize[1] * sz->h; break; default: (void)re_printf("vidframe: no fmt %s\n", vidfmt_name(fmt)); return; } vf->size = *sz; vf->fmt = fmt; } /** * Allocate an empty video frame * * @param vfp Pointer to allocated video frame * @param fmt Video pixel format * @param sz Size of video frame * * @return 0 for success, otherwise error code */ int vidframe_alloc(struct vidframe **vfp, enum vidfmt fmt, const struct vidsz *sz) { struct vidframe *vf; if (!sz || !sz->w || !sz->h) return EINVAL; vf = mem_zalloc(sizeof(*vf) + vidframe_size(fmt, sz), NULL); if (!vf) return ENOMEM; vidframe_init_buf(vf, fmt, sz, (uint8_t *)(vf + 1)); *vfp = vf; return 0; } /** * Fill a video frame with a nice color * * @param vf Video frame * @param r Red color component * @param g Green color component * @param b Blue color component */ void vidframe_fill(struct vidframe *vf, uint32_t r, uint32_t g, uint32_t b) { uint8_t *p; unsigned h, i; if (!vf) return; switch (vf->fmt) { case VID_FMT_YUV420P: h = vf->size.h; memset(vf->data[0], rgb2y(r, g, b), h * vf->linesize[0]); memset(vf->data[1], rgb2u(r, g, b), h/2 * vf->linesize[1]); memset(vf->data[2], rgb2v(r, g, b), h/2 * vf->linesize[2]); break; case VID_FMT_YUV444P: h = vf->size.h; memset(vf->data[0], rgb2y(r, g, b), h * vf->linesize[0]); memset(vf->data[1], rgb2u(r, g, b), h * vf->linesize[1]); memset(vf->data[2], rgb2v(r, g, b), h * vf->linesize[2]); break; case VID_FMT_RGB32: p = vf->data[0]; for (i=0; ilinesize[0] * vf->size.h; i+=4) { *p++ = b; *p++ = g; *p++ = r; *p++ = 0; } break; default: (void)re_printf("vidfill: no fmt %s\n", vidfmt_name(vf->fmt)); break; } } /** * Copy content between to equally sized video frames of same pixel format * * @param dst Destination frame * @param src Source frame */ void vidframe_copy(struct vidframe *dst, const struct vidframe *src) { const uint8_t *ds0, *ds1, *ds2; unsigned lsd, lss, w, h, y; uint8_t *dd0, *dd1, *dd2; if (!dst || !src) return; if (!vidsz_cmp(&dst->size, &src->size)) return; if (dst->fmt != src->fmt) return; switch (dst->fmt) { case VID_FMT_YUV420P: lsd = dst->linesize[0]; lss = src->linesize[0]; dd0 = dst->data[0]; dd1 = dst->data[1]; dd2 = dst->data[2]; ds0 = src->data[0]; ds1 = src->data[1]; ds2 = src->data[2]; w = dst->size.w & ~1; h = dst->size.h & ~1; for (y=0; ylinesize[0]; lss = src->linesize[0]; dd0 = dst->data[0]; dd1 = dst->data[1]; dd2 = dst->data[2]; ds0 = src->data[0]; ds1 = src->data[1]; ds2 = src->data[2]; w = dst->size.w; h = dst->size.h; for (y=0; ylinesize[0]; lss = src->linesize[0]; dd0 = dst->data[0]; dd1 = dst->data[1]; ds0 = src->data[0]; ds1 = src->data[1]; w = dst->size.w & ~1; h = dst->size.h & ~1; for (y=0; y #include #include #include #include #if 0 /* * The lookup tables are generated with the following code: */ #define P 14 #define COEF_RV ((int32_t) (1.370705f * (float)(1 << P))) #define COEF_GU ((int32_t) (-0.337633f * (float)(1 << P))) #define COEF_GV ((int32_t) (-0.698001f * (float)(1 << P))) #define COEF_BU ((int32_t) (1.732446f * (float)(1 << P))) #define ERV(a) (COEF_RV * ((a) - 128)) #define EGU(a) (COEF_GU * ((a) - 128)) #define EGV(a) (COEF_GV * ((a) - 128)) #define EBU(a) (COEF_BU * ((a) - 128)) int16_t CRV[256]; int16_t CGU[256]; int16_t CGV[256]; int16_t CBU[256]; static void init_table(void) { int i; for (i = 0; i < 256; ++i) { CRV[i] = ERV(i) >> P; CGU[i] = EGU(i) >> P; CGV[i] = EGV(i) >> P; CBU[i] = EBU(i) >> P; } } #endif static const int16_t CRV[256] = { -176,-175,-173,-172,-170,-169,-168,-166,-165,-164,-162,-161, -159,-158,-157,-155,-154,-153,-151,-150,-149,-147,-146,-144, -143,-142,-140,-139,-138,-136,-135,-133,-132,-131,-129,-128, -127,-125,-124,-122,-121,-120,-118,-117,-116,-114,-113,-112, -110,-109,-107,-106,-105,-103,-102,-101, -99, -98, -96, -95, -94, -92, -91, -90, -88, -87, -85, -84, -83, -81, -80, -79, -77, -76, -75, -73, -72, -70, -69, -68, -66, -65, -64, -62, -61, -59, -58, -57, -55, -54, -53, -51, -50, -48, -47, -46, -44, -43, -42, -40, -39, -38, -36, -35, -33, -32, -31, -29, -28, -27, -25, -24, -22, -21, -20, -18, -17, -16, -14, -13, -11, -10, -9, -7, -6, -5, -3, -2, 0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 15, 16, 17, 19, 20, 21, 23, 24, 26, 27, 28, 30, 31, 32, 34, 35, 37, 38, 39, 41, 42, 43, 45, 46, 47, 49, 50, 52, 53, 54, 56, 57, 58, 60, 61, 63, 64, 65, 67, 68, 69, 71, 72, 74, 75, 76, 78, 79, 80, 82, 83, 84, 86, 87, 89, 90, 91, 93, 94, 95, 97, 98, 100, 101, 102, 104, 105, 106, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120, 121, 123, 124, 126, 127, 128, 130, 131, 132, 134, 135, 137, 138, 139, 141, 142, 143, 145, 146, 148, 149, 150, 152, 153, 154, 156, 157, 158, 160, 161, 163, 164, 165, 167, 168, 169, 171, 172, 174}; static const int16_t CGU[256] = { 43, 42, 42, 42, 41, 41, 41, 40, 40, 40, 39, 39, 39, 38, 38, 38, 37, 37, 37, 36, 36, 36, 35, 35, 35, 34, 34, 34, 33, 33, 33, 32, 32, 32, 31, 31, 31, 30, 30, 30, 29, 29, 29, 28, 28, 28, 27, 27, 27, 26, 26, 25, 25, 25, 24, 24, 24, 23, 23, 23, 22, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 17, 17, 17, 16, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0, -1, -1, -2, -2, -2, -3, -3, -3, -4, -4, -4, -5, -5, -5, -6, -6, -6, -7, -7, -7, -8, -8, -8, -9, -9, -9, -10, -10, -10, -11, -11, -11, -12, -12, -12, -13, -13, -13, -14, -14, -14, -15, -15, -15, -16, -16, -16, -17, -17, -17, -18, -18, -18, -19, -19, -19, -20, -20, -20, -21, -21, -21, -22, -22, -22, -23, -23, -23, -24, -24, -24, -25, -25, -25, -26, -26, -26, -27, -27, -28, -28, -28, -29, -29, -29, -30, -30, -30, -31, -31, -31, -32, -32, -32, -33, -33, -33, -34, -34, -34, -35, -35, -35, -36, -36, -36, -37, -37, -37, -38, -38, -38, -39, -39, -39, -40, -40, -40, -41, -41, -41, -42, -42, -42, -43, -43, -43}; static const int16_t CGV[256] = { 89, 88, 87, 87, 86, 85, 85, 84, 83, 83, 82, 81, 80, 80, 79, 78, 78, 77, 76, 76, 75, 74, 73, 73, 72, 71, 71, 70, 69, 69, 68, 67, 67, 66, 65, 64, 64, 63, 62, 62, 61, 60, 60, 59, 58, 57, 57, 56, 55, 55, 54, 53, 53, 52, 51, 50, 50, 49, 48, 48, 47, 46, 46, 45, 44, 43, 43, 42, 41, 41, 40, 39, 39, 38, 37, 36, 36, 35, 34, 34, 33, 32, 32, 31, 30, 30, 29, 28, 27, 27, 26, 25, 25, 24, 23, 23, 22, 21, 20, 20, 19, 18, 18, 17, 16, 16, 15, 14, 13, 13, 12, 11, 11, 10, 9, 9, 8, 7, 6, 6, 5, 4, 4, 3, 2, 2, 1, 0, 0, -1, -2, -3, -3, -4, -5, -5, -6, -7, -7, -8, -9, -10, -10, -11, -12, -12, -13, -14, -14, -15, -16, -17, -17, -18, -19, -19, -20, -21, -21, -22, -23, -24, -24, -25, -26, -26, -27, -28, -28, -29, -30, -31, -31, -32, -33, -33, -34, -35, -35, -36, -37, -37, -38, -39, -40, -40, -41, -42, -42, -43, -44, -44, -45, -46, -47, -47, -48, -49, -49, -50, -51, -51, -52, -53, -54, -54, -55, -56, -56, -57, -58, -58, -59, -60, -61, -61, -62, -63, -63, -64, -65, -65, -66, -67, -68, -68, -69, -70, -70, -71, -72, -72, -73, -74, -74, -75, -76, -77, -77, -78, -79, -79, -80, -81, -81, -82, -83, -84, -84, -85, -86, -86, -87, -88, -88, -89}; static const int16_t CBU[256] = { -222,-221,-219,-217,-215,-214,-212,-210,-208,-207,-205,-203, -201,-200,-198,-196,-195,-193,-191,-189,-188,-186,-184,-182, -181,-179,-177,-175,-174,-172,-170,-169,-167,-165,-163,-162, -160,-158,-156,-155,-153,-151,-149,-148,-146,-144,-143,-141, -139,-137,-136,-134,-132,-130,-129,-127,-125,-124,-122,-120, -118,-117,-115,-113,-111,-110,-108,-106,-104,-103,-101, -99, -98, -96, -94, -92, -91, -89, -87, -85, -84, -82, -80, -78, -77, -75, -73, -72, -70, -68, -66, -65, -63, -61, -59, -58, -56, -54, -52, -51, -49, -47, -46, -44, -42, -40, -39, -37, -35, -33, -32, -30, -28, -26, -25, -23, -21, -20, -18, -16, -14, -13, -11, -9, -7, -6, -4, -2, 0, 1, 3, 5, 6, 8, 10, 12, 13, 15, 17, 19, 20, 22, 24, 25, 27, 29, 31, 32, 34, 36, 38, 39, 41, 43, 45, 46, 48, 50, 51, 53, 55, 57, 58, 60, 62, 64, 65, 67, 69, 71, 72, 74, 76, 77, 79, 81, 83, 84, 86, 88, 90, 91, 93, 95, 97, 98, 100, 102, 103, 105, 107, 109, 110, 112, 114, 116, 117, 119, 121, 123, 124, 126, 128, 129, 131, 133, 135, 136, 138, 140, 142, 143, 145, 147, 148, 150, 152, 154, 155, 157, 159, 161, 162, 164, 166, 168, 169, 171, 173, 174, 176, 178, 180, 181, 183, 185, 187, 188, 190, 192, 194, 195, 197, 199, 200, 202, 204, 206, 207, 209, 211, 213, 214, 216, 218, 220}; static inline void yuv2rgb(uint8_t *rgb, uint8_t y, int ruv, int guv, int buv) { *rgb++ = saturate_u8(y + buv); *rgb++ = saturate_u8(y + guv); *rgb++ = saturate_u8(y + ruv); *rgb = 0; } static inline void yuv2rgb565(uint8_t *rgb, uint8_t y, int ruv, int guv, int buv) { int r = saturate_u8(y + ruv) >> 3; int g = saturate_u8(y + guv) >> 2; int b = saturate_u8(y + buv) >> 3; rgb[1] = r << 3 | g >> 3; rgb[0] = g << 5 | b; } static inline void yuv2rgb555(uint8_t *rgb, uint8_t y, int ruv, int guv, int buv) { uint8_t r = saturate_u8(y + ruv) >> 3; uint8_t g = saturate_u8(y + guv) >> 3; uint8_t b = saturate_u8(y + buv) >> 3; rgb[1] = r << 2 | g >> 3; rgb[0] = g << 5 | b; } static inline void _yuv2rgb(uint8_t *rgb, uint8_t y, uint8_t u, uint8_t v) { int ruv, guv, buv; ruv = CRV[v]; guv = CGV[v] + CGU[u]; buv = CBU[u]; yuv2rgb(rgb, y, ruv, guv, buv); } typedef void (line_h)(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *sd0, const uint8_t *sd1, const uint8_t *sd2, unsigned lss); static void yuv420p_to_yuv420p(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *ds0, const uint8_t *ds1, const uint8_t *ds2, unsigned lss ) { unsigned x, xd, xs, xs2; unsigned id, is; for (x=0; x>1) + (ys>>1)*lss/2; dd1[id] = ds1[is]; dd2[id] = ds2[is]; } } static void yuyv422_to_yuv420p(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *sd0, const uint8_t *sd1, const uint8_t *sd2, unsigned lss ) { unsigned x, xd, xs; unsigned id, is, is2; (void)sd1; (void)sd2; for (x=0; x> 16, x0 >> 8, x0); dd0[id+1] = rgb2y(x1 >> 16, x1 >> 8, x1); dd0[id + lsd] = rgb2y(x2 >> 16, x2 >> 8, x2); dd0[id+1 + lsd] = rgb2y(x3 >> 16, x3 >> 8, x3); id = xd/2 + yd*lsd/4; dd1[id] = rgb2u(x0 >> 16, x0 >> 8, x0); dd2[id] = rgb2v(x0 >> 16, x0 >> 8, x0); } } static void rgb32_to_yuv444p(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *ds0, const uint8_t *ds1, const uint8_t *ds2, unsigned lss ) { unsigned x, xd, xs; unsigned id; (void)ds1; (void)ds2; for (x=0; x> 16, x0 >> 8, x0); dd0[id + lsd] = rgb2y(x1 >> 16, x1 >> 8, x1); dd1[id] = rgb2u(x0 >> 16, x0 >> 8, x0); dd1[id + lsd] = rgb2u(x1 >> 16, x1 >> 8, x1); dd2[id] = rgb2v(x0 >> 16, x0 >> 8, x0); dd2[id + lsd] = rgb2v(x1 >> 16, x1 >> 8, x1); } } static void yuv420p_to_rgb32(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *ds0, const uint8_t *ds1, const uint8_t *ds2, unsigned lss) { unsigned x, xd, xs, xs2; unsigned id, is; (void)dd1; (void)dd2; for (x=0; x>1) + (ys>>1)*lss/2; u = ds1[is]; v = ds2[is]; ruv = CRV[v]; guv = CGV[v] + CGU[u]; buv = CBU[u]; yuv2rgb(&dd0[id], ds0[xs + ys*lss], ruv, guv, buv); yuv2rgb(&dd0[id+4], ds0[xs2 + ys*lss], ruv, guv, buv); yuv2rgb(&dd0[id + lsd], ds0[xs + ys2*lss], ruv, guv, buv); yuv2rgb(&dd0[id+4 + lsd], ds0[xs2 + ys2*lss], ruv, guv, buv); } } static void yuv420p_to_rgb565(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *ds0, const uint8_t *ds1, const uint8_t *ds2, unsigned lss) { unsigned x, xd, xs, xs2; unsigned id, is; (void)dd1; (void)dd2; for (x=0; x>1) + (ys>>1)*lss/2; u = ds1[is]; v = ds2[is]; ruv = CRV[v]; guv = CGV[v] + CGU[u]; buv = CBU[u]; yuv2rgb565(&dd0[id], ds0[xs + ys*lss], ruv, guv,buv); yuv2rgb565(&dd0[id+2], ds0[xs2 + ys*lss], ruv, guv,buv); yuv2rgb565(&dd0[id + lsd], ds0[xs + ys2*lss], ruv, guv,buv); yuv2rgb565(&dd0[id+2 + lsd], ds0[xs2 + ys2*lss], ruv, guv,buv); } } static void yuv420p_to_rgb555(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *ds0, const uint8_t *ds1, const uint8_t *ds2, unsigned lss) { unsigned x, xd, xs, xs2; unsigned id, is; (void)dd1; (void)dd2; for (x=0; x>1) + (ys>>1)*lss/2; u = ds1[is]; v = ds2[is]; ruv = CRV[v]; guv = CGV[v] + CGU[u]; buv = CBU[u]; yuv2rgb555(&dd0[id], ds0[xs + ys*lss], ruv, guv,buv); yuv2rgb555(&dd0[id+2], ds0[xs2 + ys*lss], ruv, guv,buv); yuv2rgb555(&dd0[id + lsd], ds0[xs + ys2*lss], ruv, guv,buv); yuv2rgb555(&dd0[id+2 + lsd], ds0[xs2 + ys2*lss], ruv, guv,buv); } } static void nv12_to_yuv420p(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *ds0, const uint8_t *ds1, const uint8_t *ds2, unsigned lss ) { unsigned x, xd, xs, xs2; unsigned id, is; (void)ds2; for (x=0; x>1) + (yd>>1)*lsd/2; is = xs/2 + ys*lss/4; dd1[id] = ds1[2*is]; dd2[id] = ds1[2*is+1]; } } static void yuv420p_to_nv12(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *ds0, const uint8_t *ds1, const uint8_t *ds2, unsigned lss ) { unsigned x, xd, xs, xs2; unsigned id, is; (void)dd2; for (x=0; x>1) + (ys>>1)*lss/2; dd1[2*id] = ds1[is]; dd1[2*id+1] = ds2[is]; } } static void nv21_to_yuv420p(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *ds0, const uint8_t *ds1, const uint8_t *ds2, unsigned lss ) { unsigned x, xd, xs, xs2; unsigned id, is; (void)ds2; for (x=0; x>1) + (ys>>1)*lss/2) & ~1; dd2[id] = ds1[2*is]; dd1[id] = ds1[2*is+1]; } } static void yuv444p_to_rgb32(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *ds0, const uint8_t *ds1, const uint8_t *ds2, unsigned lss) { unsigned x, xd, xs; unsigned id; unsigned is1, is2; (void)dd1; (void)dd2; for (x=0; xfmt < MAX_SRC && dst->fmt < MAX_DST) { /* Lookup conversion function */ lineh = conv_table[src->fmt][dst->fmt]; } if (!lineh) { (void)re_printf("vidconv: no pixel converter found for" " %s -> %s\n", vidfmt_name(src->fmt), vidfmt_name(dst->fmt)); return; } if (r) { r->x &= ~1; r->y &= ~1; r->w &= ~1; r->h &= ~1; if ((r->x + r->w) > dst->size.w || (r->y + r->h) > dst->size.h) { (void)re_printf("vidconv: out of bounds (%u x %u)\n", dst->size.w, dst->size.h); return; } } else { rdst.x = rdst.y = 0; rdst.w = dst->size.w & ~1; rdst.h = dst->size.h & ~1; r = &rdst; } rw = (double)src->size.w / (double)r->w; rh = (double)src->size.h / (double)r->h; lsd = dst->linesize[0]; lss = src->linesize[0]; dd0 = dst->data[0]; dd1 = dst->data[1]; dd2 = dst->data[2]; ds0 = src->data[0]; ds1 = src->data[1]; ds2 = src->data[2]; for (y=0; yh; y+=2) { yd = y + r->y; ys = (unsigned)(y * rh); ys2 = (unsigned)((y+1) * rh); lineh(r->x, r->w, rw, yd, ys, ys2, dd0, dd1, dd2, lsd, ds0, ds1, ds2, lss); } } /** * Same as vidconv(), but maintain source aspect ratio within bounds of r * * @param dst Destination video frame * @param src Source video frame * @param r Drawing area in destination frame */ void vidconv_aspect(struct vidframe *dst, const struct vidframe *src, struct vidrect *r) { struct vidsz asz; double ar; ar = (double)src->size.w / (double)src->size.h; asz.w = r->w; asz.h = r->h; r->w = (unsigned)min((double)asz.w, (double)asz.h * ar); r->h = (unsigned)min((double)asz.h, (double)asz.w / ar); r->x = r->x + (asz.w - r->w) / 2; r->y = r->y + (asz.h - r->h) / 2; vidconv(dst, src, r); } rem-0.6.0/src/vidmix/000077500000000000000000000000001337577470400144105ustar00rootroot00000000000000rem-0.6.0/src/vidmix/mod.mk000066400000000000000000000001111337577470400155110ustar00rootroot00000000000000# # mod.mk # # Copyright (C) 2010 Creytiv.com # SRCS += vidmix/vidmix.c rem-0.6.0/src/vidmix/vidmix.c000066400000000000000000000314701337577470400160610ustar00rootroot00000000000000/** * @file vidmix.c Video Mixer * * Copyright (C) 2010 Creytiv.com */ #define _BSD_SOURCE 1 #define _DEFAULT_SOURCE 1 #include #define __USE_UNIX98 1 #include #include #include #include #include #include struct vidmix { pthread_rwlock_t rwlock; struct list srcl; bool initialized; }; struct vidmix_source { struct le le; pthread_t thread; pthread_mutex_t mutex; struct vidframe *frame_tx; struct vidframe *frame_rx; struct vidmix *mix; vidmix_frame_h *fh; void *arg; void *focus; bool content_hide; bool focus_full; unsigned fint; bool selfview; bool content; bool clear; bool run; }; static inline void source_mix_full(struct vidframe *mframe, const struct vidframe *frame_src); static inline void clear_frame(struct vidframe *vf) { vidframe_fill(vf, 0, 0, 0); } static void clear_all(struct vidmix *mix) { struct le *le; for (le=mix->srcl.head; le; le=le->next) { struct vidmix_source *src = le->data; src->clear = true; } } static void destructor(void *arg) { struct vidmix *mix = arg; if (mix->initialized) (void)pthread_rwlock_destroy(&mix->rwlock); } static void source_destructor(void *arg) { struct vidmix_source *src = arg; if (src->run) { src->run = false; pthread_join(src->thread, NULL); } if (src->le.list) { pthread_rwlock_wrlock(&src->mix->rwlock); list_unlink(&src->le); clear_all(src->mix); pthread_rwlock_unlock(&src->mix->rwlock); } mem_deref(src->frame_tx); mem_deref(src->frame_rx); mem_deref(src->mix); } static inline void source_mix(struct vidframe *mframe, const struct vidframe *frame_src, unsigned n, unsigned rows, unsigned idx, bool focus, bool focus_this, bool focus_full) { struct vidrect rect; if (!frame_src) return; if (focus) { const unsigned nmin = focus_full ? 12 : 6; n = max((n+1), nmin)/2; if (focus_this) { rect.w = mframe->size.w * (n-1) / n; rect.h = mframe->size.h * (n-1) / n; rect.x = 0; rect.y = 0; } else { rect.w = mframe->size.w / n; rect.h = mframe->size.h / n; if (idx < n) { rect.x = mframe->size.w - rect.w; rect.y = rect.h * idx; } else if (idx < (n*2 - 1)) { rect.x = rect.w * (n*2 - 2 - idx); rect.y = mframe->size.h - rect.h; } else { return; } } } else if (rows == 1) { source_mix_full(mframe, frame_src); return; } else { rect.w = mframe->size.w / rows; rect.h = mframe->size.h / rows; rect.x = rect.w * (idx % rows); rect.y = rect.h * (idx / rows); } vidconv_aspect(mframe, frame_src, &rect); } static inline void source_mix_full(struct vidframe *mframe, const struct vidframe *frame_src) { if (!frame_src) return; if (vidsz_cmp(&mframe->size, &frame_src->size)) { vidframe_copy(mframe, frame_src); } else { struct vidrect rect; rect.w = mframe->size.w; rect.h = mframe->size.h; rect.x = 0; rect.y = 0; vidconv_aspect(mframe, frame_src, &rect); } } static inline unsigned calc_rows(unsigned n) { unsigned rows; for (rows=1;; rows++) if (n <= (rows * rows)) return rows; } static void *vidmix_thread(void *arg) { struct vidmix_source *src = arg; struct vidmix *mix = src->mix; uint64_t ts = tmr_jiffies(); pthread_mutex_lock(&src->mutex); while (src->run) { unsigned n, rows, idx; struct le *le; uint64_t now; pthread_mutex_unlock(&src->mutex); (void)usleep(4000); pthread_mutex_lock(&src->mutex); now = tmr_jiffies(); if (ts > now) continue; if (!src->frame_tx) { ts += src->fint; continue; } pthread_rwlock_rdlock(&mix->rwlock); if (src->clear) { clear_frame(src->frame_tx); src->clear = false; } for (le=mix->srcl.head, n=0; le; le=le->next) { const struct vidmix_source *lsrc = le->data; if (lsrc == src && !src->selfview) continue; if (lsrc->content && src->content_hide) continue; if (lsrc == src->focus && src->focus_full) source_mix_full(src->frame_tx, lsrc->frame_rx); ++n; } rows = calc_rows(n); for (le=mix->srcl.head, idx=0; le; le=le->next) { const struct vidmix_source *lsrc = le->data; if (lsrc == src && !src->selfview) continue; if (lsrc->content && src->content_hide) continue; if (lsrc == src->focus && src->focus_full) continue; source_mix(src->frame_tx, lsrc->frame_rx, n, rows, idx, src->focus != NULL, src->focus == lsrc, src->focus_full); if (src->focus != lsrc) ++idx; } pthread_rwlock_unlock(&mix->rwlock); src->fh((uint32_t)ts * 90, src->frame_tx, src->arg); ts += src->fint; } pthread_mutex_unlock(&src->mutex); return NULL; } static void *content_thread(void *arg) { struct vidmix_source *src = arg; struct vidmix *mix = src->mix; uint64_t ts = tmr_jiffies(); pthread_mutex_lock(&src->mutex); while (src->run) { struct le *le; uint64_t now; pthread_mutex_unlock(&src->mutex); (void)usleep(4000); pthread_mutex_lock(&src->mutex); now = tmr_jiffies(); if (ts > now) continue; pthread_rwlock_rdlock(&mix->rwlock); for (le=mix->srcl.head; le; le=le->next) { const struct vidmix_source *lsrc = le->data; if (!lsrc->content || !lsrc->frame_rx || lsrc == src) continue; src->fh((uint32_t)ts * 90, lsrc->frame_rx, src->arg); break; } pthread_rwlock_unlock(&mix->rwlock); ts += src->fint; } pthread_mutex_unlock(&src->mutex); return NULL; } /** * Allocate a new Video mixer * * @param mixp Pointer to allocated video mixer * * @return 0 for success, otherwise error code */ int vidmix_alloc(struct vidmix **mixp) { pthread_rwlockattr_t attr; struct vidmix *mix; int err; if (!mixp) return EINVAL; mix = mem_zalloc(sizeof(*mix), destructor); if (!mix) return ENOMEM; err = pthread_rwlockattr_init(&attr); if (err) { mem_deref(mix); return err; } #if defined(LINUX) && defined(__GLIBC__) err = pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); if (err) goto out; #endif err = pthread_rwlock_init(&mix->rwlock, &attr); if (err) goto out; mix->initialized = true; out: (void)pthread_rwlockattr_destroy(&attr); if (err) mem_deref(mix); else *mixp = mix; return err; } /** * Allocate a video mixer source * * @param srcp Pointer to allocated video source * @param mix Video mixer * @param sz Size of output video frame (optional) * @param fps Output frame rate (frames per second) * @param content True if source is of type content * @param fh Mixer frame handler * @param arg Handler argument * * @return 0 for success, otherwise error code */ int vidmix_source_alloc(struct vidmix_source **srcp, struct vidmix *mix, const struct vidsz *sz, unsigned fps, bool content, vidmix_frame_h *fh, void *arg) { struct vidmix_source *src; int err; if (!srcp || !mix || !fps || !fh) return EINVAL; src = mem_zalloc(sizeof(*src), source_destructor); if (!src) return ENOMEM; src->mix = mem_ref(mix); src->fint = 1000/fps; src->content = content; src->fh = fh; src->arg = arg; err = pthread_mutex_init(&src->mutex, NULL); if (err) goto out; if (sz) { err = vidframe_alloc(&src->frame_tx, VID_FMT_YUV420P, sz); if (err) goto out; clear_frame(src->frame_tx); } out: if (err) mem_deref(src); else *srcp = src; return err; } /** * Check if vidmix source is enabled * * @param src Video mixer source * * @return true if enabled, otherwise false */ bool vidmix_source_isenabled(const struct vidmix_source *src) { return src ? (src->le.list != NULL) : false; } /** * Check if vidmix source is running * * @param src Video mixer source * * @return true if running, otherwise false */ bool vidmix_source_isrunning(const struct vidmix_source *src) { return src ? src->run : false; } /** * Get focus source * * @param src Video mixer source * * @return pointer of focused source or NULL if focus is not set */ void *vidmix_source_get_focus(const struct vidmix_source *src) { return src ? src->focus : NULL; } /** * Enable/disable vidmix source * * @param src Video mixer source * @param enable True to enable, false to disable */ void vidmix_source_enable(struct vidmix_source *src, bool enable) { if (!src) return; if (src->le.list && enable) return; if (!src->le.list && !enable) return; pthread_rwlock_wrlock(&src->mix->rwlock); if (enable) { if (src->frame_rx) clear_frame(src->frame_rx); list_append(&src->mix->srcl, &src->le, src); } else { list_unlink(&src->le); } clear_all(src->mix); pthread_rwlock_unlock(&src->mix->rwlock); } /** * Start vidmix source thread * * @param src Video mixer source * * @return 0 for success, otherwise error code */ int vidmix_source_start(struct vidmix_source *src) { int err; if (!src) return EINVAL; if (src->run) return EALREADY; src->run = true; err = pthread_create(&src->thread, NULL, src->content ? content_thread : vidmix_thread, src); if (err) { src->run = false; } return err; } /** * Stop vidmix source thread * * @param src Video mixer source */ void vidmix_source_stop(struct vidmix_source *src) { if (!src) return; if (src->run) { src->run = false; pthread_join(src->thread, NULL); } } /** * Set video mixer output frame size * * @param src Video mixer source * @param sz Size of output video frame * * @return 0 for success, otherwise error code */ int vidmix_source_set_size(struct vidmix_source *src, const struct vidsz *sz) { struct vidframe *frame; int err; if (!src || !sz) return EINVAL; if (src->frame_tx && vidsz_cmp(&src->frame_tx->size, sz)) return 0; err = vidframe_alloc(&frame, VID_FMT_YUV420P, sz); if (err) return err; clear_frame(frame); pthread_mutex_lock(&src->mutex); mem_deref(src->frame_tx); src->frame_tx = frame; pthread_mutex_unlock(&src->mutex); return 0; } /** * Set video mixer output frame rate * * @param src Video mixer source * @param fps Output frame rate (frames per second) */ void vidmix_source_set_rate(struct vidmix_source *src, unsigned fps) { if (!src || !fps) return; pthread_mutex_lock(&src->mutex); src->fint = 1000/fps; pthread_mutex_unlock(&src->mutex); } /** * Set video mixer content hide * * @param src Video mixer source * @param hide True to hide content, false to show */ void vidmix_source_set_content_hide(struct vidmix_source *src, bool hide) { if (!src) return; pthread_mutex_lock(&src->mutex); src->content_hide = hide; src->clear = true; pthread_mutex_unlock(&src->mutex); } /** * Toggle vidmix source selfview * * @param src Video mixer source */ void vidmix_source_toggle_selfview(struct vidmix_source *src) { if (!src) return; pthread_mutex_lock(&src->mutex); src->selfview = !src->selfview; src->clear = true; pthread_mutex_unlock(&src->mutex); } /** * Set focus on selected participant source * * @param src Video mixer source * @param focus_src Video mixer source to focus, NULL to clear focus state * @param focus_full Full focus */ void vidmix_source_set_focus(struct vidmix_source *src, const struct vidmix_source *focus_src, bool focus_full) { if (!src) return; pthread_mutex_lock(&src->mutex); src->focus_full = focus_full; src->focus = (void *)focus_src; src->clear = true; pthread_mutex_unlock(&src->mutex); } /** * Set focus on selected participant * * @param src Video mixer source * @param pidx Participant to focus, 0 to disable */ void vidmix_source_set_focus_idx(struct vidmix_source *src, unsigned pidx) { bool focus_full = false; void *focus = NULL; if (!src) return; if (pidx > 0) { struct le *le; unsigned i; pthread_rwlock_rdlock(&src->mix->rwlock); for (le=src->mix->srcl.head, i=1; le; le=le->next) { const struct vidmix_source *lsrc = le->data; if (lsrc == src && !src->selfview) continue; if (lsrc->content && src->content_hide) continue; if (i++ == pidx) { focus = (void *)lsrc; break; } } pthread_rwlock_unlock(&src->mix->rwlock); } if (focus && focus == src->focus) focus_full = !src->focus_full; pthread_mutex_lock(&src->mutex); src->focus_full = focus_full; src->focus = focus; src->clear = true; pthread_mutex_unlock(&src->mutex); } /** * Put a video frame into the video mixer * * @param src Video source * @param frame Video frame */ void vidmix_source_put(struct vidmix_source *src, const struct vidframe *frame) { if (!src || !frame || frame->fmt != VID_FMT_YUV420P) return; if (!src->frame_rx || !vidsz_cmp(&src->frame_rx->size, &frame->size)) { struct vidframe *frm; int err; err = vidframe_alloc(&frm, VID_FMT_YUV420P, &frame->size); if (err) return; pthread_rwlock_wrlock(&src->mix->rwlock); mem_deref(src->frame_rx); src->frame_rx = frm; clear_all(src->mix); pthread_rwlock_unlock(&src->mix->rwlock); } vidframe_copy(src->frame_rx, frame); } rem-0.6.0/util/000077500000000000000000000000001337577470400132765ustar00rootroot00000000000000rem-0.6.0/util/genfir.py000066400000000000000000000007311337577470400151230ustar00rootroot00000000000000#!/usr/bin/python import scipy.signal TAPS = 31 CUTOFF = 8000.0 # Hz SRATE = 16000.0 # Hz cutoff = CUTOFF / SRATE coeffs = scipy.signal.firwin(TAPS, cutoff) print "/*" print " * FIR filter with cutoff %dHz, samplerate %dHz" % (CUTOFF, SRATE) print " */" print "static const int16_t fir_lowpass[%d] = {" % (TAPS) i = 0 for c in coeffs: v = int(c * 32768.0) print " %5d," % (v), i += 1 if not (i % 8): print "\n" , print "" print "};"