multimon-1.0/0000755000310500031050000000000010362742101013142 5ustar bottomsbottomsmultimon-1.0/COPYING0000644000310500031050000006131410271505162014205 0ustar bottomsbottoms GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA. Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! multimon-1.0/Makefile0000644000310500031050000000474010271506265014617 0ustar bottomsbottomsDEBUG =n OS =$(shell uname) MACH =$(shell uname -m) CFLAGS =-Wall -Wstrict-prototypes -I/usr/X11R6/include ifeq ($(OS),SunOS) ifeq ($(DEBUG),y) CFLAGS +=-g -O -DSUN_AUDIO -DARCH_SPARC else CFLAGS +=-O3 -DSUN_AUDIO -DARCH_SPARC endif LDFLAGSX =-lX11 -L/usr/X11R6/lib -R/usr/X11R6/lib -lsocket -lnsl else ifeq ($(MACH),x86_64) ifeq ($(DEBUG),y) CFLAGS +=-g -O -DARCH_X86_64 else CFLAGS +=-O3 -DARCH_X86_64 endif LDFLAGSX =-lX11 -L/usr/X11R6/lib64 else ifeq ($(DEBUG),y) CFLAGS +=-g -O -march=i486 -mtune=pentium4 -falign-loops=2 -falign-jumps=2 \ -malign-functions=2 -DARCH_I386 else CFLAGS +=-O3 -march=i486 -mtune=pentium4 -falign-loops=2 -falign-jumps=2 \ -falign-functions=2 -DARCH_I386 endif LDFLAGSX =-lX11 -L/usr/X11R6/lib endif endif BINDIR =bin-$(shell uname -m) AS86 =as86 -0 -a LD86 =ld86 -0 AS =as LD =ld LDFLAGS =-lm HOSTCC =gcc CC =gcc MAKE =make CPP =$(CC) -E AR =ar STRIP =strip MKDIR =mkdir all: $(BINDIR) $(BINDIR)/multimon $(BINDIR)/gen $(BINDIR)/%.s: %.c $(CC) $(CFLAGS) -S -o $@ $< $(BINDIR)/%.o: $(BINDIR)/%.s $(AS) -c -o $@ $< $(BINDIR)/%.o: %.c $(CC) $(CFLAGS) -c -o $@ $< SRC_L2 =hdlc.c pocsag.c SRC_L1 =demod_afsk12.c demod_afsk24.c demod_afsk24_2.c SRC_L1 +=demod_hapn48.c demod_fsk96.c SRC_L1 +=demod_poc5.c demod_poc12.c demod_poc24.c SRC_L1 +=demod_dtmf.c demod_zvei.c demod_display.c SRC_MISC =unixinput.c costabf.c xdisplay.c SRC_GEN =gen.c gen_dtmf.c gen_sin.c gen_zvei.c gen_hdlc.c costabi.c OBJ_L2 =$(SRC_L2:%.c=$(BINDIR)/%.o) OBJ_L1 =$(SRC_L1:%.c=$(BINDIR)/%.o) OBJ_MISC =$(SRC_MISC:%.c=$(BINDIR)/%.o) OBJ_GEN =$(SRC_GEN:%.c=$(BINDIR)/%.o) $(BINDIR): $(MKDIR) $(BINDIR) $(BINDIR)/multimon: $(OBJ_L2) $(OBJ_L1) $(OBJ_MISC) $(CC) $^ $(LDFLAGS) $(LDFLAGSX) -o $@ $(BINDIR)/gen: $(OBJ_GEN) $(CC) $^ $(LDFLAGS) -o $@ $(BINDIR)/mkcostab: $(BINDIR)/mkcostab.o $(CC) $^ $(LDFLAGS) -o $@ costabi.c costabf.c: $(BINDIR)/mkcostab $(BINDIR)/mkcostab clean: $(RM) -f core `find . -name '*.[oas]' -print` $(RM) -f core `find . -name 'core' -print` $(RM) -f core costabi.c costabf.c *~ multimon.tar.bz2 $(RM) -rf bin-* depend dep: $(BINDIR) costabi.c costabf.c $(CPP) -M $(CFLAGS) $(SRC_MISC) $(SRC_L1) $(SRC_L2) $(SRC_GEN) mkcostab.c > $(BINDIR)/.depend dist: tar cjf multimon.tar.bz2 COPYING Makefile filter.h filter-i386.h gen.h multimon.h \ $(SRC_MISC) $(SRC_L1) $(SRC_L2) $(SRC_GEN) mkcostab.c ifeq ($(BINDIR)/.depend,$(wildcard $(BINDIR)/.depend)) include $(BINDIR)/.depend endif multimon-1.0/filter.h0000644000310500031050000000664007573266454014634 0ustar bottomsbottoms/* * filter.h -- optimized filter routines * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #ifndef _FILTER_H #define _FILTER_H /* ---------------------------------------------------------------------- */ #ifdef ARCH_I386 #include "filter-i386.h" #endif /* ARCH_I386 */ /* ---------------------------------------------------------------------- */ extern inline unsigned int hweight32(unsigned int w) __attribute__ ((unused)); extern inline unsigned int hweight16(unsigned short w) __attribute__ ((unused)); extern inline unsigned int hweight8(unsigned char w) __attribute__ ((unused)); extern inline unsigned int hweight32(unsigned int w) { unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555); res = (res & 0x33333333) + ((res >> 2) & 0x33333333); res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F); res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF); return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF); } extern inline unsigned int hweight16(unsigned short w) { unsigned short res = (w & 0x5555) + ((w >> 1) & 0x5555); res = (res & 0x3333) + ((res >> 2) & 0x3333); res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F); return (res & 0x00FF) + ((res >> 8) & 0x00FF); } extern inline unsigned int hweight8(unsigned char w) { unsigned short res = (w & 0x55) + ((w >> 1) & 0x55); res = (res & 0x33) + ((res >> 2) & 0x33); return (res & 0x0F) + ((res >> 4) & 0x0F); } extern inline unsigned int gcd(unsigned int x, unsigned int y) __attribute__ ((unused)); extern inline unsigned int lcm(unsigned int x, unsigned int y) __attribute__ ((unused)); extern inline unsigned int gcd(unsigned int x, unsigned int y) { for (;;) { if (!x) return y; if (!y) return x; if (x > y) x %= y; else y %= x; } } extern inline unsigned int lcm(unsigned int x, unsigned int y) { return x * y / gcd(x, y); } /* ---------------------------------------------------------------------- */ #ifndef __HAVE_ARCH_MAC extern inline float mac(const float *a, const float *b, unsigned int size) { float sum = 0; unsigned int i; for (i = 0; i < size; i++) sum += (*a++) * (*b++); return sum; } #endif /* __HAVE_ARCH_MAC */ extern inline float fsqr(float f) { return f*f; } /* ---------------------------------------------------------------------- */ #endif /* _FILTER_H */ multimon-1.0/filter-i386.h0000644000310500031050000001632107573266454015320 0ustar bottomsbottoms/* * filter-i386.h -- optimized filter routines * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #ifndef _FILTER_I386_H #define _FILTER_I386_H /* ---------------------------------------------------------------------- */ #define __HAVE_ARCH_MAC #define mac(a,b,size) \ (__builtin_constant_p(size) ? __mac_c((a),(b),(size)) : __mac_g((a),(b),(size))) #include extern inline float __mac_g(const float *a, const float *b, unsigned int size) { float sum = 0; unsigned int i; for (i = 0; i < size; i++) sum += (*a++) * (*b++); return sum; } extern inline float __mac_c(const float *a, const float *b, unsigned int size) { float f; /* * inspired from Phil Karn, KA9Q's home page */ switch (size) { case 9: asm volatile ("flds (%1);\n\t" "fmuls (%2);\n\t" "flds 4(%1);\n\t" "fmuls 4(%2);\n\t" "flds 8(%1);\n\t" "fmuls 8(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 12(%1);\n\t" "fmuls 12(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 16(%1);\n\t" "fmuls 16(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 20(%1);\n\t" "fmuls 20(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 24(%1);\n\t" "fmuls 24(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 28(%1);\n\t" "fmuls 28(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 32(%1);\n\t" "fmuls 32(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "faddp;\n\t" : "=t" (f) : "r" (a), "r" (b) : "memory"); return f; case 18: asm volatile ("flds (%1);\n\t" "fmuls (%2);\n\t" "flds 4(%1);\n\t" "fmuls 4(%2);\n\t" "flds 8(%1);\n\t" "fmuls 8(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 12(%1);\n\t" "fmuls 12(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 16(%1);\n\t" "fmuls 16(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 20(%1);\n\t" "fmuls 20(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 24(%1);\n\t" "fmuls 24(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 28(%1);\n\t" "fmuls 28(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 32(%1);\n\t" "fmuls 32(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 36(%1);\n\t" "fmuls 36(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 40(%1);\n\t" "fmuls 40(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 44(%1);\n\t" "fmuls 44(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 48(%1);\n\t" "fmuls 48(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 52(%1);\n\t" "fmuls 52(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 56(%1);\n\t" "fmuls 56(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 60(%1);\n\t" "fmuls 60(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 64(%1);\n\t" "fmuls 64(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 68(%1);\n\t" "fmuls 68(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "faddp;\n\t" : "=t" (f) : "r" (a), "r" (b) : "memory"); return f; case 24: asm volatile ("flds (%1);\n\t" "fmuls (%2);\n\t" "flds 4(%1);\n\t" "fmuls 4(%2);\n\t" "flds 8(%1);\n\t" "fmuls 8(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 12(%1);\n\t" "fmuls 12(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 16(%1);\n\t" "fmuls 16(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 20(%1);\n\t" "fmuls 20(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 24(%1);\n\t" "fmuls 24(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 28(%1);\n\t" "fmuls 28(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 32(%1);\n\t" "fmuls 32(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 36(%1);\n\t" "fmuls 36(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 40(%1);\n\t" "fmuls 40(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 44(%1);\n\t" "fmuls 44(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 48(%1);\n\t" "fmuls 48(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 52(%1);\n\t" "fmuls 52(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 56(%1);\n\t" "fmuls 56(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 60(%1);\n\t" "fmuls 60(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 64(%1);\n\t" "fmuls 64(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 68(%1);\n\t" "fmuls 68(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 72(%1);\n\t" "fmuls 72(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 76(%1);\n\t" "fmuls 76(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 80(%1);\n\t" "fmuls 80(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 84(%1);\n\t" "fmuls 84(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 88(%1);\n\t" "fmuls 88(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "flds 92(%1);\n\t" "fmuls 92(%2);\n\t" "fxch %%st(2);\n\t" "faddp;\n\t" "faddp;\n\t" : "=t" (f) : "r" (a), "r" (b) : "memory"); return f; default: printf("Warning: optimize __mac_c(..., ..., %d)\n", size); return __mac_g(a, b, size); } } /* ---------------------------------------------------------------------- */ #endif /* _FILTER_I386_H */ multimon-1.0/gen.h0000644000310500031050000000513007573266453014110 0ustar bottomsbottoms/* * gen.h -- generate different test signals * * Copyright (C) 1997 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #define SAMPLE_RATE 22050 #define MS(x) ((float)(x)*SAMPLE_RATE/1000) extern const int costabi[0x400]; #define COS(x) costabi[(((x)>>6)&0x3ffu)] enum gen_type { gentype_dtmf, gentype_sine, gentype_zvei, gentype_hdlc }; struct gen_params { enum gen_type type; int ampl; union { struct { int duration; int pause; char str[256]; } dtmf; struct { int duration; int freq; } sine; struct { int duration; int pause; char str[256]; } zvei; struct { int modulation; int txdelay; int pktlen; unsigned char pkt[256]; } hdlc; } p; }; struct gen_state { union { struct { int ch_idx; int ph_row, ph_col, phinc_row, phinc_col; int time, time2; } dtmf; struct { int ph, phinc; int time; } sine; struct { int ch_idx; int ph, phinc; int time, time2; } zvei; struct { int lastb; int ch_idx, bitmask; unsigned int ph, phinc, bitph; unsigned int datalen; unsigned char data[512]; } hdlc; } s; }; extern void gen_init_dtmf(struct gen_params *p, struct gen_state *s); extern int gen_dtmf(signed short *buf, int buflen, struct gen_params *p, struct gen_state *s); extern void gen_init_sine(struct gen_params *p, struct gen_state *s); extern int gen_sine(signed short *buf, int buflen, struct gen_params *p, struct gen_state *s); extern void gen_init_zvei(struct gen_params *p, struct gen_state *s); extern int gen_zvei(signed short *buf, int buflen, struct gen_params *p, struct gen_state *s); extern void gen_init_hdlc(struct gen_params *p, struct gen_state *s); extern int gen_hdlc(signed short *buf, int buflen, struct gen_params *p, struct gen_state *s); multimon-1.0/multimon.h0000644000310500031050000001062707573266454015213 0ustar bottomsbottoms/* * multimon.h -- Monitor for many different modulation formats * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #ifndef _MULTIMON_H #define _MULTIMON_H /* ---------------------------------------------------------------------- */ extern const float costabf[0x400]; #define COS(x) costabf[(((x)>>6)&0x3ffu)] #define SIN(x) COS((x)+0xc000) /* ---------------------------------------------------------------------- */ struct demod_state { const struct demod_param *dem_par; union { struct l2_state_hdlc { unsigned char rxbuf[512]; unsigned char *rxptr; unsigned int rxstate; unsigned int rxbitstream; unsigned int rxbitbuf; } hdlc; struct l2_state_pocsag { unsigned long rx_data; struct l2_pocsag_rx { unsigned char rx_sync; unsigned char rx_word; unsigned char rx_bit; char func; unsigned long adr; unsigned char buffer[128]; unsigned int numnibbles; } rx[2]; } pocsag; } l2; union { struct l1_state_poc5 { unsigned int dcd_shreg; unsigned int sphase; unsigned int subsamp; } poc5; struct l1_state_poc12 { unsigned int dcd_shreg; unsigned int sphase; unsigned int subsamp; } poc12; struct l1_state_poc24 { unsigned int dcd_shreg; unsigned int sphase; } poc24; struct l1_state_afsk12 { unsigned int dcd_shreg; unsigned int sphase; unsigned int lasts; unsigned int subsamp; } afsk12; struct l1_state_afsk24 { unsigned int dcd_shreg; unsigned int sphase; unsigned int lasts; } afsk24; struct l1_state_hapn48 { unsigned int shreg; unsigned int sphase; float lvllo, lvlhi; } hapn48; struct l1_state_fsk96 { unsigned int dcd_shreg; unsigned int sphase; unsigned int descram; } fsk96; struct l1_state_dtmf { unsigned int ph[8]; float energy[4]; float tenergy[4][16]; int blkcount; int lastch; } dtmf; struct l1_state_zvei { unsigned int ph[16]; float energy[4]; float tenergy[4][32]; int blkcount; int lastch; } zvei; struct l1_state_scope { int datalen; int dispnum; float data[512]; } scope; } l1; }; struct demod_param { const char *name; unsigned int samplerate; unsigned int overlap; void (*init)(struct demod_state *s); void (*demod)(struct demod_state *s, float *buffer, int length); }; /* ---------------------------------------------------------------------- */ extern const struct demod_param demod_poc5; extern const struct demod_param demod_poc12; extern const struct demod_param demod_poc24; extern const struct demod_param demod_afsk1200; extern const struct demod_param demod_afsk2400; extern const struct demod_param demod_afsk2400_2; extern const struct demod_param demod_hapn4800; extern const struct demod_param demod_fsk9600; extern const struct demod_param demod_dtmf; extern const struct demod_param demod_zvei; extern const struct demod_param demod_scope; #define ALL_DEMOD &demod_poc5, &demod_poc12, &demod_poc24, \ &demod_afsk1200, &demod_afsk2400, &demod_afsk2400_2, &demod_hapn4800, \ &demod_fsk9600, &demod_dtmf, &demod_zvei, &demod_scope /* ---------------------------------------------------------------------- */ void verbprintf(int verb_level, const char *fmt, ...); void hdlc_init(struct demod_state *s); void hdlc_rxbit(struct demod_state *s, int bit); void pocsag_init(struct demod_state *s); void pocsag_rxbit(struct demod_state *s, int bit); void xdisp_terminate(int cnum); int xdisp_start(void); int xdisp_update(int cnum, float *f); /* ---------------------------------------------------------------------- */ #endif /* _MULTIMON_H */ multimon-1.0/unixinput.c0000644000310500031050000003140407573266454015401 0ustar bottomsbottoms/* * unixinput.c -- input sound samples * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "multimon.h" #include #include #include #include #include #include #include #include #include #include #ifdef SUN_AUDIO #include #include #include #else /* SUN_AUDIO */ #include #include #endif /* SUN_AUDIO */ /* ---------------------------------------------------------------------- */ static const char *allowed_types[] = { "raw", "aiff", "au", "hcom", "sf", "voc", "cdr", "dat", "smp", "wav", "maud", "vwe", NULL }; /* ---------------------------------------------------------------------- */ static const struct demod_param *dem[] = { ALL_DEMOD }; #define NUMDEMOD (sizeof(dem)/sizeof(dem[0])) static struct demod_state dem_st[NUMDEMOD]; static unsigned int dem_mask[(NUMDEMOD+31)/32]; #define MASK_SET(n) dem_mask[(n)>>5] |= 1<<((n)&0x1f) #define MASK_RESET(n) dem_mask[(n)>>5] &= ~(1<<((n)&0x1f)) #define MASK_ISSET(n) (dem_mask[(n)>>5] & 1<<((n)&0x1f)) /* ---------------------------------------------------------------------- */ static int verbose_level = 0; /* ---------------------------------------------------------------------- */ void verbprintf(int verb_level, const char *fmt, ...) { va_list args; va_start(args, fmt); if (verb_level <= verbose_level) vfprintf(stdout, fmt, args); va_end(args); } /* ---------------------------------------------------------------------- */ static void process_buffer(float *buf, unsigned int len) { int i; for (i = 0; i < NUMDEMOD; i++) if (MASK_ISSET(i) && dem[i]->demod) dem[i]->demod(dem_st+i, buf, len); } /* ---------------------------------------------------------------------- */ #ifdef SUN_AUDIO static void input_sound(unsigned int sample_rate, unsigned int overlap, const char *ifname) { audio_info_t audioinfo; audio_info_t audioinfo2; audio_device_t audiodev; int fd; short buffer[8192]; float fbuf[16384]; unsigned int fbuf_cnt = 0; int i; short *sp; if ((fd = open(ifname ? ifname : "/dev/audio", O_RDONLY)) < 0) { perror("open"); exit (10); } if (ioctl(fd, AUDIO_GETDEV, &audiodev) == -1) { perror("ioctl: AUDIO_GETDEV"); exit (10); } AUDIO_INITINFO(&audioinfo); audioinfo.record.sample_rate = sample_rate; audioinfo.record.channels = 1; audioinfo.record.precision = 16; audioinfo.record.encoding = AUDIO_ENCODING_LINEAR; /*audioinfo.record.gain = 0x20; audioinfo.record.port = AUDIO_LINE_IN; audioinfo.monitor_gain = 0;*/ if (ioctl(fd, AUDIO_SETINFO, &audioinfo) == -1) { perror("ioctl: AUDIO_SETINFO"); exit (10); } if (ioctl(fd, I_FLUSH, FLUSHR) == -1) { perror("ioctl: I_FLUSH"); exit (10); } if (ioctl(fd, AUDIO_GETINFO, &audioinfo2) == -1) { perror("ioctl: AUDIO_GETINFO"); exit (10); } fprintf(stdout, "Audio device: name %s, ver %s, config %s, " "sampling rate %d\n", audiodev.name, audiodev.version, audiodev.config, audioinfo.record.sample_rate); for (;;) { i = read(fd, sp = buffer, sizeof(buffer)); if (i < 0 && errno != EAGAIN) { perror("read"); exit(4); } if (!i) break; if (i > 0) { for (; i >= sizeof(buffer[0]); i -= sizeof(buffer[0]), sp++) fbuf[fbuf_cnt++] = (*sp) * (1.0/32768.0); if (i) fprintf(stderr, "warning: noninteger number of samples read\n"); if (fbuf_cnt > overlap) { process_buffer(fbuf, fbuf_cnt-overlap); memmove(fbuf, fbuf+fbuf_cnt-overlap, overlap*sizeof(fbuf[0])); fbuf_cnt = overlap; } } } close(fd); } #else /* SUN_AUDIO */ /* ---------------------------------------------------------------------- */ static void input_sound(unsigned int sample_rate, unsigned int overlap, const char *ifname) { int sndparam; int fd; union { short s[8192]; unsigned char b[8192]; } b; float fbuf[16384]; unsigned int fbuf_cnt = 0; int i; short *sp; unsigned char *bp; int fmt = 0; if ((fd = open(ifname ? ifname : "/dev/dsp", O_RDONLY)) < 0) { perror("open"); exit (10); } sndparam = AFMT_S16_LE; /* we want 16 bits/sample signed */ /* little endian; works only on little endian systems! */ if (ioctl(fd, SNDCTL_DSP_SETFMT, &sndparam) == -1) { perror("ioctl: SNDCTL_DSP_SETFMT"); exit (10); } if (sndparam != AFMT_S16_LE) { fmt = 1; sndparam = AFMT_U8; if (ioctl(fd, SNDCTL_DSP_SETFMT, &sndparam) == -1) { perror("ioctl: SNDCTL_DSP_SETFMT"); exit (10); } if (sndparam != AFMT_U8) { perror("ioctl: SNDCTL_DSP_SETFMT"); exit (10); } } sndparam = 0; /* we want only 1 channel */ if (ioctl(fd, SNDCTL_DSP_STEREO, &sndparam) == -1) { perror("ioctl: SNDCTL_DSP_STEREO"); exit (10); } if (sndparam != 0) { fprintf(stderr, "soundif: Error, cannot set the channel " "number to 1\n"); exit (10); } sndparam = sample_rate; if (ioctl(fd, SNDCTL_DSP_SPEED, &sndparam) == -1) { perror("ioctl: SNDCTL_DSP_SPEED"); exit (10); } if ((10*abs(sndparam-sample_rate)) > sample_rate) { perror("ioctl: SNDCTL_DSP_SPEED"); exit (10); } if (sndparam != sample_rate) { fprintf(stderr, "Warning: Sampling rate is %u, " "requested %u\n", sndparam, sample_rate); } #if 0 sndparam = 4; if (ioctl(fd, SOUND_PCM_SUBDIVIDE, &sndparam) == -1) { perror("ioctl: SOUND_PCM_SUBDIVIDE"); } if (sndparam != 4) { perror("ioctl: SOUND_PCM_SUBDIVIDE"); } #endif for (;;) { if (fmt) { i = read(fd, bp = b.b, sizeof(b.b)); if (i < 0 && errno != EAGAIN) { perror("read"); exit(4); } if (!i) break; if (i > 0) { for (; i >= sizeof(b.b[0]); i -= sizeof(b.b[0]), sp++) fbuf[fbuf_cnt++] = ((int)(*bp)-0x80) * (1.0/128.0); if (i) fprintf(stderr, "warning: noninteger number of samples read\n"); if (fbuf_cnt > overlap) { process_buffer(fbuf, fbuf_cnt-overlap); memmove(fbuf, fbuf+fbuf_cnt-overlap, overlap*sizeof(fbuf[0])); fbuf_cnt = overlap; } } } else { i = read(fd, sp = b.s, sizeof(b.s)); if (i < 0 && errno != EAGAIN) { perror("read"); exit(4); } if (!i) break; if (i > 0) { for (; i >= sizeof(b.s[0]); i -= sizeof(b.s[0]), sp++) fbuf[fbuf_cnt++] = (*sp) * (1.0/32768.0); if (i) fprintf(stderr, "warning: noninteger number of samples read\n"); if (fbuf_cnt > overlap) { process_buffer(fbuf, fbuf_cnt-overlap); memmove(fbuf, fbuf+fbuf_cnt-overlap, overlap*sizeof(fbuf[0])); fbuf_cnt = overlap; } } } } close(fd); } #endif /* SUN_AUDIO */ /* ---------------------------------------------------------------------- */ static void input_file(unsigned int sample_rate, unsigned int overlap, const char *fname, const char *type) { struct stat statbuf; int pipedes[2]; int pid = 0, soxstat; int fd; int i; short buffer[8192]; float fbuf[16384]; unsigned int fbuf_cnt = 0; short *sp; /* * if the input type is not raw, sox is started to convert the * samples to the requested format */ if (!type || !strcmp(type, "raw")) { if ((fd = open(fname, O_RDONLY)) < 0) { perror("open"); exit(10); } } else { if (stat(fname, &statbuf)) { perror("stat"); exit(10); } if (pipe(pipedes)) { perror("pipe"); exit(10); } if (!(pid = fork())) { char srate[8]; /* * child starts here... first set up filedescriptors, * then start sox... */ sprintf(srate, "%d", sample_rate); close(pipedes[0]); /* close reading pipe end */ close(1); /* close standard output */ if (dup2(pipedes[1], 1) < 0) perror("dup2"); close(pipedes[1]); /* close writing pipe end */ execlp("sox", "sox", "-t", type, fname, "-t", "raw", "-s", "-w", "-r", srate, "-", NULL); perror("execlp"); exit(10); } if (pid < 0) { perror("fork"); exit(10); } close(pipedes[1]); /* close writing pipe end */ fd = pipedes[0]; } /* * demodulate */ for (;;) { i = read(fd, sp = buffer, sizeof(buffer)); if (i < 0 && errno != EAGAIN) { perror("read"); exit(4); } if (!i) break; if (i > 0) { for (; i >= sizeof(buffer[0]); i -= sizeof(buffer[0]), sp++) fbuf[fbuf_cnt++] = (*sp) * (1.0/32768.0); if (i) fprintf(stderr, "warning: noninteger number of samples read\n"); if (fbuf_cnt > overlap) { process_buffer(fbuf, fbuf_cnt-overlap); memmove(fbuf, fbuf+fbuf_cnt-overlap, overlap*sizeof(fbuf[0])); fbuf_cnt = overlap; } } } close(fd); waitpid(pid, &soxstat, 0); } /* ---------------------------------------------------------------------- */ static const char usage_str[] = "multimod\n" "Demodulates many different radio transmission formats\n" "(C) 1996 by Thomas Sailer HB9JNX/AE4WA\n" " -t : input file type (any other type than raw requires sox)\n" " -a : add demodulator\n" " -s : subtract demodulator\n"; int main(int argc, char *argv[]) { int c; int errflg = 0; int i; char **itype; int mask_first = 1; int sample_rate = -1; unsigned int overlap = 0; char *input_type = "hw"; fprintf(stdout, "multimod (C) 1996/1997 by Tom Sailer HB9JNX/AE4WA\n" "available demodulators:"); for (i = 0; i < NUMDEMOD; i++) fprintf(stdout, " %s", dem[i]->name); fprintf(stdout, "\n"); while ((c = getopt(argc, argv, "t:a:s:v:")) != EOF) { switch (c) { case '?': errflg++; break; case 'v': verbose_level = strtoul(optarg, 0, 0); break; case 't': for (itype = (char **)allowed_types; *itype; itype++) if (!strcmp(*itype, optarg)) { input_type = *itype; goto intypefound; } fprintf(stderr, "invalid input type \"%s\"\n" "allowed types: ", optarg); for (itype = (char **)allowed_types; *itype; itype++) fprintf(stderr, "%s ", *itype); fprintf(stderr, "\n"); errflg++; intypefound: break; case 'a': if (mask_first) memset(dem_mask, 0, sizeof(dem_mask)); mask_first = 0; for (i = 0; i < NUMDEMOD; i++) if (!strcasecmp(optarg, dem[i]->name)) { MASK_SET(i); break; } if (i >= NUMDEMOD) { fprintf(stderr, "invalid mode \"%s\"\n", optarg); errflg++; } break; case 's': if (mask_first) memset(dem_mask, 0xff, sizeof(dem_mask)); mask_first = 0; for (i = 0; i < NUMDEMOD; i++) if (!strcasecmp(optarg, dem[i]->name)) { MASK_RESET(i); break; } if (i >= NUMDEMOD) { fprintf(stderr, "invalid mode \"%s\"\n", optarg); errflg++; } break; } } if (errflg) { (void)fprintf(stderr, usage_str); exit(2); } if (mask_first) memset(dem_mask, 0xff, sizeof(dem_mask)); fprintf(stdout, "Enabled demodulators:"); for (i = 0; i < NUMDEMOD; i++) if (MASK_ISSET(i)) { fprintf(stdout, " %s", dem[i]->name); memset(dem_st+i, 0, sizeof(dem_st[i])); dem_st[i].dem_par = dem[i]; if (dem[i]->init) dem[i]->init(dem_st+i); if (sample_rate == -1) sample_rate = dem[i]->samplerate; else if (sample_rate != dem[i]->samplerate) { fprintf(stdout, "\n"); fprintf(stderr, "Error: Current sampling rate %d, " " demodulator \"%s\" requires %d\n", sample_rate, dem[i]->name, dem[i]->samplerate); exit(3); } if (dem[i]->overlap > overlap) overlap = dem[i]->overlap; } fprintf(stdout, "\n"); if (!strcmp(input_type, "hw")) { if ((argc - optind) >= 1) input_sound(sample_rate, overlap, argv[optind]); else input_sound(sample_rate, overlap, NULL); exit(0); } if ((argc - optind) < 1) { (void)fprintf(stderr, "no source files specified\n"); exit(4); } for (i = optind; i < argc; i++) input_file(sample_rate, overlap, argv[i], input_type); exit(0); } /* ---------------------------------------------------------------------- */ multimon-1.0/costabf.c0000644000310500031050000003512110271506360014735 0ustar bottomsbottoms/* * This file is machine generated, DO NOT EDIT! */ float costabf[1024] = { 1.000000000, 0.999981165, 0.999924719, 0.999830604, 0.999698818, 0.999529421, 0.999322355, 0.999077737, 0.998795450, 0.998475552, 0.998118103, 0.997723043, 0.997290432, 0.996820271, 0.996312618, 0.995767415, 0.995184720, 0.994564593, 0.993906975, 0.993211925, 0.992479563, 0.991709769, 0.990902662, 0.990058184, 0.989176512, 0.988257587, 0.987301409, 0.986308098, 0.985277653, 0.984210074, 0.983105481, 0.981963873, 0.980785251, 0.979569793, 0.978317380, 0.977028131, 0.975702107, 0.974339366, 0.972939968, 0.971503913, 0.970031261, 0.968522072, 0.966976464, 0.965394437, 0.963776052, 0.962121427, 0.960430503, 0.958703458, 0.956940353, 0.955141187, 0.953306019, 0.951435030, 0.949528158, 0.947585583, 0.945607305, 0.943593442, 0.941544056, 0.939459205, 0.937339008, 0.935183525, 0.932992816, 0.930766940, 0.928506076, 0.926210225, 0.923879504, 0.921514034, 0.919113874, 0.916679084, 0.914209783, 0.911706030, 0.909168005, 0.906595707, 0.903989315, 0.901348829, 0.898674488, 0.895966232, 0.893224299, 0.890448749, 0.887639642, 0.884797096, 0.881921291, 0.879012227, 0.876070082, 0.873094976, 0.870086968, 0.867046237, 0.863972843, 0.860866964, 0.857728601, 0.854557991, 0.851355195, 0.848120332, 0.844853580, 0.841554999, 0.838224709, 0.834862888, 0.831469595, 0.828045070, 0.824589312, 0.821102500, 0.817584813, 0.814036310, 0.810457170, 0.806847572, 0.803207517, 0.799537241, 0.795836926, 0.792106569, 0.788346410, 0.784556568, 0.780737221, 0.776888490, 0.773010433, 0.769103348, 0.765167236, 0.761202395, 0.757208824, 0.753186822, 0.749136388, 0.745057762, 0.740951121, 0.736816585, 0.732654274, 0.728464365, 0.724247098, 0.720002532, 0.715730846, 0.711432219, 0.707106769, 0.702754736, 0.698376238, 0.693971455, 0.689540565, 0.685083687, 0.680601001, 0.676092684, 0.671558976, 0.666999936, 0.662415802, 0.657806695, 0.653172851, 0.648514390, 0.643831551, 0.639124453, 0.634393275, 0.629638255, 0.624859512, 0.620057225, 0.615231574, 0.610382795, 0.605511069, 0.600616455, 0.595699310, 0.590759695, 0.585797846, 0.580813944, 0.575808167, 0.570780754, 0.565731823, 0.560661554, 0.555570245, 0.550457954, 0.545324981, 0.540171444, 0.534997642, 0.529803634, 0.524589658, 0.519356012, 0.514102757, 0.508830130, 0.503538370, 0.498227656, 0.492898196, 0.487550169, 0.482183784, 0.476799220, 0.471396744, 0.465976506, 0.460538715, 0.455083579, 0.449611336, 0.444122136, 0.438616246, 0.433093816, 0.427555084, 0.422000259, 0.416429549, 0.410843164, 0.405241311, 0.399624199, 0.393992037, 0.388345033, 0.382683426, 0.377007425, 0.371317208, 0.365612984, 0.359895051, 0.354163527, 0.348418683, 0.342660725, 0.336889863, 0.331106305, 0.325310290, 0.319502026, 0.313681751, 0.307849646, 0.302005947, 0.296150893, 0.290284663, 0.284407526, 0.278519690, 0.272621363, 0.266712755, 0.260794103, 0.254865646, 0.248927608, 0.242980182, 0.237023607, 0.231058106, 0.225083917, 0.219101235, 0.213110313, 0.207111374, 0.201104641, 0.195090324, 0.189068660, 0.183039889, 0.177004218, 0.170961887, 0.164913118, 0.158858150, 0.152797192, 0.146730468, 0.140658244, 0.134580702, 0.128498107, 0.122410677, 0.116318628, 0.110222206, 0.104121633, 0.098017141, 0.091908954, 0.085797310, 0.079682440, 0.073564567, 0.067443922, 0.061320737, 0.055195246, 0.049067676, 0.042938258, 0.036807224, 0.030674804, 0.024541229, 0.018406730, 0.012271538, 0.006135885, 0.000000000, -0.006135885, -0.012271538, -0.018406730, -0.024541229, -0.030674804, -0.036807224, -0.042938258, -0.049067676, -0.055195246, -0.061320737, -0.067443922, -0.073564567, -0.079682440, -0.085797310, -0.091908954, -0.098017141, -0.104121633, -0.110222206, -0.116318628, -0.122410677, -0.128498107, -0.134580702, -0.140658244, -0.146730468, -0.152797192, -0.158858150, -0.164913118, -0.170961887, -0.177004218, -0.183039889, -0.189068660, -0.195090324, -0.201104641, -0.207111374, -0.213110313, -0.219101235, -0.225083917, -0.231058106, -0.237023607, -0.242980182, -0.248927608, -0.254865646, -0.260794103, -0.266712755, -0.272621363, -0.278519690, -0.284407526, -0.290284663, -0.296150893, -0.302005947, -0.307849646, -0.313681751, -0.319502026, -0.325310290, -0.331106305, -0.336889863, -0.342660725, -0.348418683, -0.354163527, -0.359895051, -0.365612984, -0.371317208, -0.377007425, -0.382683426, -0.388345033, -0.393992037, -0.399624199, -0.405241311, -0.410843164, -0.416429549, -0.422000259, -0.427555084, -0.433093816, -0.438616246, -0.444122136, -0.449611336, -0.455083579, -0.460538715, -0.465976506, -0.471396744, -0.476799220, -0.482183784, -0.487550169, -0.492898196, -0.498227656, -0.503538370, -0.508830130, -0.514102757, -0.519356012, -0.524589658, -0.529803634, -0.534997642, -0.540171444, -0.545324981, -0.550457954, -0.555570245, -0.560661554, -0.565731823, -0.570780754, -0.575808167, -0.580813944, -0.585797846, -0.590759695, -0.595699310, -0.600616455, -0.605511069, -0.610382795, -0.615231574, -0.620057225, -0.624859512, -0.629638255, -0.634393275, -0.639124453, -0.643831551, -0.648514390, -0.653172851, -0.657806695, -0.662415802, -0.666999936, -0.671558976, -0.676092684, -0.680601001, -0.685083687, -0.689540565, -0.693971455, -0.698376238, -0.702754736, -0.707106769, -0.711432219, -0.715730846, -0.720002532, -0.724247098, -0.728464365, -0.732654274, -0.736816585, -0.740951121, -0.745057762, -0.749136388, -0.753186822, -0.757208824, -0.761202395, -0.765167236, -0.769103348, -0.773010433, -0.776888490, -0.780737221, -0.784556568, -0.788346410, -0.792106569, -0.795836926, -0.799537241, -0.803207517, -0.806847572, -0.810457170, -0.814036310, -0.817584813, -0.821102500, -0.824589312, -0.828045070, -0.831469595, -0.834862888, -0.838224709, -0.841554999, -0.844853580, -0.848120332, -0.851355195, -0.854557991, -0.857728601, -0.860866964, -0.863972843, -0.867046237, -0.870086968, -0.873094976, -0.876070082, -0.879012227, -0.881921291, -0.884797096, -0.887639642, -0.890448749, -0.893224299, -0.895966232, -0.898674488, -0.901348829, -0.903989315, -0.906595707, -0.909168005, -0.911706030, -0.914209783, -0.916679084, -0.919113874, -0.921514034, -0.923879504, -0.926210225, -0.928506076, -0.930766940, -0.932992816, -0.935183525, -0.937339008, -0.939459205, -0.941544056, -0.943593442, -0.945607305, -0.947585583, -0.949528158, -0.951435030, -0.953306019, -0.955141187, -0.956940353, -0.958703458, -0.960430503, -0.962121427, -0.963776052, -0.965394437, -0.966976464, -0.968522072, -0.970031261, -0.971503913, -0.972939968, -0.974339366, -0.975702107, -0.977028131, -0.978317380, -0.979569793, -0.980785251, -0.981963873, -0.983105481, -0.984210074, -0.985277653, -0.986308098, -0.987301409, -0.988257587, -0.989176512, -0.990058184, -0.990902662, -0.991709769, -0.992479563, -0.993211925, -0.993906975, -0.994564593, -0.995184720, -0.995767415, -0.996312618, -0.996820271, -0.997290432, -0.997723043, -0.998118103, -0.998475552, -0.998795450, -0.999077737, -0.999322355, -0.999529421, -0.999698818, -0.999830604, -0.999924719, -0.999981165, -1.000000000, -0.999981165, -0.999924719, -0.999830604, -0.999698818, -0.999529421, -0.999322355, -0.999077737, -0.998795450, -0.998475552, -0.998118103, -0.997723043, -0.997290432, -0.996820271, -0.996312618, -0.995767415, -0.995184720, -0.994564593, -0.993906975, -0.993211925, -0.992479563, -0.991709769, -0.990902662, -0.990058184, -0.989176512, -0.988257587, -0.987301409, -0.986308098, -0.985277653, -0.984210074, -0.983105481, -0.981963873, -0.980785251, -0.979569793, -0.978317380, -0.977028131, -0.975702107, -0.974339366, -0.972939968, -0.971503913, -0.970031261, -0.968522072, -0.966976464, -0.965394437, -0.963776052, -0.962121427, -0.960430503, -0.958703458, -0.956940353, -0.955141187, -0.953306019, -0.951435030, -0.949528158, -0.947585583, -0.945607305, -0.943593442, -0.941544056, -0.939459205, -0.937339008, -0.935183525, -0.932992816, -0.930766940, -0.928506076, -0.926210225, -0.923879504, -0.921514034, -0.919113874, -0.916679084, -0.914209783, -0.911706030, -0.909168005, -0.906595707, -0.903989315, -0.901348829, -0.898674488, -0.895966232, -0.893224299, -0.890448749, -0.887639642, -0.884797096, -0.881921291, -0.879012227, -0.876070082, -0.873094976, -0.870086968, -0.867046237, -0.863972843, -0.860866964, -0.857728601, -0.854557991, -0.851355195, -0.848120332, -0.844853580, -0.841554999, -0.838224709, -0.834862888, -0.831469595, -0.828045070, -0.824589312, -0.821102500, -0.817584813, -0.814036310, -0.810457170, -0.806847572, -0.803207517, -0.799537241, -0.795836926, -0.792106569, -0.788346410, -0.784556568, -0.780737221, -0.776888490, -0.773010433, -0.769103348, -0.765167236, -0.761202395, -0.757208824, -0.753186822, -0.749136388, -0.745057762, -0.740951121, -0.736816585, -0.732654274, -0.728464365, -0.724247098, -0.720002532, -0.715730846, -0.711432219, -0.707106769, -0.702754736, -0.698376238, -0.693971455, -0.689540565, -0.685083687, -0.680601001, -0.676092684, -0.671558976, -0.666999936, -0.662415802, -0.657806695, -0.653172851, -0.648514390, -0.643831551, -0.639124453, -0.634393275, -0.629638255, -0.624859512, -0.620057225, -0.615231574, -0.610382795, -0.605511069, -0.600616455, -0.595699310, -0.590759695, -0.585797846, -0.580813944, -0.575808167, -0.570780754, -0.565731823, -0.560661554, -0.555570245, -0.550457954, -0.545324981, -0.540171444, -0.534997642, -0.529803634, -0.524589658, -0.519356012, -0.514102757, -0.508830130, -0.503538370, -0.498227656, -0.492898196, -0.487550169, -0.482183784, -0.476799220, -0.471396744, -0.465976506, -0.460538715, -0.455083579, -0.449611336, -0.444122136, -0.438616246, -0.433093816, -0.427555084, -0.422000259, -0.416429549, -0.410843164, -0.405241311, -0.399624199, -0.393992037, -0.388345033, -0.382683426, -0.377007425, -0.371317208, -0.365612984, -0.359895051, -0.354163527, -0.348418683, -0.342660725, -0.336889863, -0.331106305, -0.325310290, -0.319502026, -0.313681751, -0.307849646, -0.302005947, -0.296150893, -0.290284663, -0.284407526, -0.278519690, -0.272621363, -0.266712755, -0.260794103, -0.254865646, -0.248927608, -0.242980182, -0.237023607, -0.231058106, -0.225083917, -0.219101235, -0.213110313, -0.207111374, -0.201104641, -0.195090324, -0.189068660, -0.183039889, -0.177004218, -0.170961887, -0.164913118, -0.158858150, -0.152797192, -0.146730468, -0.140658244, -0.134580702, -0.128498107, -0.122410677, -0.116318628, -0.110222206, -0.104121633, -0.098017141, -0.091908954, -0.085797310, -0.079682440, -0.073564567, -0.067443922, -0.061320737, -0.055195246, -0.049067676, -0.042938258, -0.036807224, -0.030674804, -0.024541229, -0.018406730, -0.012271538, -0.006135885, -0.000000000, 0.006135885, 0.012271538, 0.018406730, 0.024541229, 0.030674804, 0.036807224, 0.042938258, 0.049067676, 0.055195246, 0.061320737, 0.067443922, 0.073564567, 0.079682440, 0.085797310, 0.091908954, 0.098017141, 0.104121633, 0.110222206, 0.116318628, 0.122410677, 0.128498107, 0.134580702, 0.140658244, 0.146730468, 0.152797192, 0.158858150, 0.164913118, 0.170961887, 0.177004218, 0.183039889, 0.189068660, 0.195090324, 0.201104641, 0.207111374, 0.213110313, 0.219101235, 0.225083917, 0.231058106, 0.237023607, 0.242980182, 0.248927608, 0.254865646, 0.260794103, 0.266712755, 0.272621363, 0.278519690, 0.284407526, 0.290284663, 0.296150893, 0.302005947, 0.307849646, 0.313681751, 0.319502026, 0.325310290, 0.331106305, 0.336889863, 0.342660725, 0.348418683, 0.354163527, 0.359895051, 0.365612984, 0.371317208, 0.377007425, 0.382683426, 0.388345033, 0.393992037, 0.399624199, 0.405241311, 0.410843164, 0.416429549, 0.422000259, 0.427555084, 0.433093816, 0.438616246, 0.444122136, 0.449611336, 0.455083579, 0.460538715, 0.465976506, 0.471396744, 0.476799220, 0.482183784, 0.487550169, 0.492898196, 0.498227656, 0.503538370, 0.508830130, 0.514102757, 0.519356012, 0.524589658, 0.529803634, 0.534997642, 0.540171444, 0.545324981, 0.550457954, 0.555570245, 0.560661554, 0.565731823, 0.570780754, 0.575808167, 0.580813944, 0.585797846, 0.590759695, 0.595699310, 0.600616455, 0.605511069, 0.610382795, 0.615231574, 0.620057225, 0.624859512, 0.629638255, 0.634393275, 0.639124453, 0.643831551, 0.648514390, 0.653172851, 0.657806695, 0.662415802, 0.666999936, 0.671558976, 0.676092684, 0.680601001, 0.685083687, 0.689540565, 0.693971455, 0.698376238, 0.702754736, 0.707106769, 0.711432219, 0.715730846, 0.720002532, 0.724247098, 0.728464365, 0.732654274, 0.736816585, 0.740951121, 0.745057762, 0.749136388, 0.753186822, 0.757208824, 0.761202395, 0.765167236, 0.769103348, 0.773010433, 0.776888490, 0.780737221, 0.784556568, 0.788346410, 0.792106569, 0.795836926, 0.799537241, 0.803207517, 0.806847572, 0.810457170, 0.814036310, 0.817584813, 0.821102500, 0.824589312, 0.828045070, 0.831469595, 0.834862888, 0.838224709, 0.841554999, 0.844853580, 0.848120332, 0.851355195, 0.854557991, 0.857728601, 0.860866964, 0.863972843, 0.867046237, 0.870086968, 0.873094976, 0.876070082, 0.879012227, 0.881921291, 0.884797096, 0.887639642, 0.890448749, 0.893224299, 0.895966232, 0.898674488, 0.901348829, 0.903989315, 0.906595707, 0.909168005, 0.911706030, 0.914209783, 0.916679084, 0.919113874, 0.921514034, 0.923879504, 0.926210225, 0.928506076, 0.930766940, 0.932992816, 0.935183525, 0.937339008, 0.939459205, 0.941544056, 0.943593442, 0.945607305, 0.947585583, 0.949528158, 0.951435030, 0.953306019, 0.955141187, 0.956940353, 0.958703458, 0.960430503, 0.962121427, 0.963776052, 0.965394437, 0.966976464, 0.968522072, 0.970031261, 0.971503913, 0.972939968, 0.974339366, 0.975702107, 0.977028131, 0.978317380, 0.979569793, 0.980785251, 0.981963873, 0.983105481, 0.984210074, 0.985277653, 0.986308098, 0.987301409, 0.988257587, 0.989176512, 0.990058184, 0.990902662, 0.991709769, 0.992479563, 0.993211925, 0.993906975, 0.994564593, 0.995184720, 0.995767415, 0.996312618, 0.996820271, 0.997290432, 0.997723043, 0.998118103, 0.998475552, 0.998795450, 0.999077737, 0.999322355, 0.999529421, 0.999698818, 0.999830604, 0.999924719, 0.999981165 }; multimon-1.0/xdisplay.c0000644000310500031050000002431310271505162015151 0ustar bottomsbottoms/* * xdisplay.c -- actually displaying things * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "multimon.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* ---------------------------------------------------------------------- */ #define WIDTH 512 #define HEIGHT 256 union comdata { short s[WIDTH]; unsigned char b[0]; }; #define SAMPLING_RATE 22050 /* ---------------------------------------------------------------------- */ /* * child data structures */ static Display *display = NULL; static Window window; static GC gc; static Pixmap pixmap; static unsigned long col_zeroline; static unsigned long col_background; static unsigned long col_trace; static int cmdpipe[2]; static int datapipe[2]; /* * parent data */ struct xdisp { int used; pid_t pid; int cmdfd; int datafd; }; #define NUMCLI 16 static struct xdisp cli[NUMCLI] = { { 0, }, }; /* ---------------------------------------------------------------------- */ static int x_error_handler(Display *disp, XErrorEvent *evt) { char err_buf[256], mesg[256], number[256]; char *mtype = "XlibMessage"; XGetErrorText(disp, evt->error_code, err_buf, sizeof(err_buf)); (void)fprintf(stderr, "X Error: %s\n", err_buf); XGetErrorDatabaseText(disp, mtype, "MajorCode", "Request Major code %d", mesg, sizeof(mesg)); (void)fprintf(stderr, mesg, evt->request_code); (void)sprintf(number, "%d", evt->request_code); XGetErrorDatabaseText(disp, "XRequest", number, "", err_buf, sizeof(err_buf)); (void)fprintf(stderr, " (%s)\n", err_buf); abort(); } /* ---------------------------------------------------------------------- */ static Bool predicate(Display *display, XEvent *event, char *arg) { return True; } /* ---------------------------------------------------------------------- */ static char *x_getkey(void) { XWindowAttributes winattrs; XEvent evt; static char kbuf[32]; int i; if (!display) return NULL; while (XCheckIfEvent(display, &evt, predicate, NULL)) { switch (evt.type) { case KeyPress: i = XLookupString((XKeyEvent *)&evt, kbuf, sizeof(kbuf)-1, NULL, NULL); if (i) { kbuf[i] = 0; return kbuf; } continue; case DestroyNotify: XCloseDisplay(display); exit(0); case Expose: XGetWindowAttributes(display, window, &winattrs); XCopyArea(display, window, pixmap, gc, 0, 0, winattrs.width, winattrs.height, 0, 0); continue; default: continue; } } return NULL; } /* ---------------------------------------------------------------------- */ static void process_keystrokes(void) { char *cp; while ((cp = x_getkey())) { printf("X: Keys pressed: %s\n", cp); } } /* ---------------------------------------------------------------------- */ static int do_x_select(int fd, int wr) { int *xconn, xconnnum; int max = fd, i; fd_set rmask, wmask; if (!XInternalConnectionNumbers(display, &xconn, &xconnnum)) { perror("XInternalConnectionNumbers"); exit(1); } FD_ZERO(&rmask); FD_ZERO(&wmask); if (wr) FD_SET(fd, &wmask); else FD_SET(fd, &rmask); for (i = 0; i < xconnnum; i++) { FD_SET(xconn[i], &rmask); if (xconn[i] > max) max = xconn[i]; } i = select(max+1, &rmask, &wmask, NULL, NULL); if (i < 0) { perror("select"); exit(1); } for (i = 0; i < xconnnum; i++) if (FD_ISSET(xconn[i], &rmask)) XProcessInternalConnection(display, xconn[i]); XFree(xconn); process_keystrokes(); if (wr) return FD_ISSET(fd, &wmask); else return FD_ISSET(fd, &rmask); } /* ---------------------------------------------------------------------- */ static void child_win_init(void) { XSetWindowAttributes attr; XGCValues gcv; XColor color, dummy; XSizeHints sizehints; /* * start graphical output */ if (!(display = XOpenDisplay(NULL))) { fprintf(stderr, "X: Unable to open X display\n"); exit(1); } XSetErrorHandler(x_error_handler); XAllocNamedColor(display, DefaultColormap(display, 0), "red", &color, &dummy); col_zeroline = color.pixel; col_background = WhitePixel(display, 0); col_trace = BlackPixel(display, 0); attr.background_pixel = col_background; window = XCreateWindow(display, XRootWindow(display, 0), 200, 200, WIDTH, HEIGHT, 5, DefaultDepth(display, 0), InputOutput, DefaultVisual(display, 0), CWBackPixel, &attr); if (!(pixmap = XCreatePixmap(display, window, WIDTH, HEIGHT, DefaultDepth(display, 0)))) { fprintf(stderr, "X: unable to open offscreen pixmap\n"); exit(1); } XSelectInput(display, window, KeyPressMask | StructureNotifyMask | ExposureMask) ; gcv.line_width = 1; gcv.line_style = LineSolid; gc = XCreateGC(display, pixmap, GCForeground | GCLineWidth, &gcv); /* * Do not allow the window to be resized */ memset(&sizehints, 0, sizeof(sizehints)); sizehints.min_width = sizehints.max_width = WIDTH; sizehints.min_height = sizehints.max_height = HEIGHT; sizehints.flags = PMinSize | PMaxSize; XSetWMNormalHints(display, window, &sizehints); XMapWindow(display, window); XSynchronize(display, 1); } /* ---------------------------------------------------------------------- */ #define YCOORD(x) (((x)>>8)+(HEIGHT/2)) static void child_process(void) { union comdata d; unsigned char *bp; int i, j; /* * main loop */ for (;;) { /* * send synchronisation mark */ while (!do_x_select(cmdpipe[1], 1)); i = write(cmdpipe[1], "r", 1); if (i < 1) { perror("write"); exit(1); } /* * read data */ for (j = sizeof(d), bp = d.b; j > 0; ) { while (!do_x_select(datapipe[0], 0)); i = read(datapipe[0], bp, j); if (i < 1) { perror("read"); exit(1); } j -= i; bp += i; } /* * clear pixmap */ XSetState(display, gc, col_background, col_background, GXcopy, AllPlanes); XFillRectangle(display, pixmap, gc, 0, 0, WIDTH, HEIGHT); /* * draw zero line */ XSetForeground(display, gc, col_zeroline); XDrawLine(display, pixmap, gc, 0, YCOORD(0), WIDTH, YCOORD(0)); /* * draw input */ XSetForeground(display, gc, col_trace); for (i = 1; i < WIDTH; i++) XDrawLine(display, pixmap, gc, i-1, YCOORD(d.s[i-1]), i, YCOORD(d.s[i])); XCopyArea(display, pixmap, window, gc, 0, 0, WIDTH, HEIGHT, 0, 0); /* XSync(display, 0); */ } XDestroyWindow(display, window); XCloseDisplay(display); } /* ---------------------------------------------------------------------- */ static void sigchld_handler(int sig) { pid_t pid; int st; unsigned int cnum; while ((pid = wait4(0, &st, WNOHANG, NULL)) != (pid_t)-1) { for (cnum = 0; cnum < NUMCLI; cnum++) if (cli[cnum].used && cli[cnum].pid == pid) { cli[cnum].used = 0; close(cli[cnum].cmdfd); close(cli[cnum].datafd); cli[cnum].pid = (pid_t)-1; fprintf(stderr, "child process %i died, " "status %i\n", (int)pid, st); } } } /* ---------------------------------------------------------------------- */ void xdisp_terminate(int cnum) { if (cnum < 0 || cnum >= NUMCLI) return; kill(cli[cnum].pid, SIGTERM); } /* ---------------------------------------------------------------------- */ int xdisp_start(void) { unsigned int cnum; /* * find free client struct */ for (cnum = 0; (cnum < NUMCLI) && cli[cnum].used; cnum++); if (cnum >= NUMCLI) return -1; signal(SIGCHLD, sigchld_handler); /* * start "IPC" mechanism (using the pipes) */ if (pipe(cmdpipe)) return -1; if (pipe(datapipe)) { close(cmdpipe[0]); close(cmdpipe[1]); } if ((cli[cnum].pid = fork())) { if (cli[cnum].pid == (pid_t)-1) { /* error */ close(cmdpipe[0]); close(cmdpipe[1]); close(datapipe[0]); close(datapipe[1]); return -1; } /* parent */ cli[cnum].cmdfd = cmdpipe[0]; close(cmdpipe[1]); close(datapipe[0]); cli[cnum].datafd = datapipe[1]; cli[cnum].used = 1; fcntl(cmdpipe[0], F_SETFL, (fcntl(cmdpipe[0], F_GETFL, 0) | O_NDELAY)); return cnum; } /* * child; the X process */ close(cmdpipe[0]); close(datapipe[1]); close(0); /* close stdin */ child_win_init(); child_process(); exit(0); } /* ---------------------------------------------------------------------- */ int xdisp_update(int cnum, float *f) { unsigned char *bp; short *sp; int i, j; char c; union comdata d; if (cnum < 0 || cnum >= NUMCLI) return 0; i = read(cli[cnum].cmdfd, &c, 1); if (i < 0 && errno != EAGAIN) { perror("read"); xdisp_terminate(cnum); return 0; } if (i < 1) return 0; if (c != 'r') return 0; for (sp = d.s, i = 0; i < WIDTH; i++, sp++, f++) { if (*f >= 1) *sp = 32767; else if (*f <= -1) *sp = -32767; else *sp = 32767.0 * (*f); } bp = d.b; j = sizeof(d); while (j > 0) { i = write(cli[cnum].datafd, bp, j); if (i < 0 && errno != EAGAIN) { perror("write"); xdisp_terminate(cnum); return 0; } if (i > 0) { bp += i; j -= i; } } return 1; } /* ---------------------------------------------------------------------- */ multimon-1.0/demod_afsk12.c0000644000310500031050000000743307573266454015602 0ustar bottomsbottoms/* * demod_afsk12.c -- 1200 baud AFSK demodulator * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "multimon.h" #include "filter.h" #include #include /* ---------------------------------------------------------------------- */ /* * Standard TCM3105 clock frequency: 4.4336MHz * Mark frequency: 2200 Hz * Space frequency: 1200 Hz */ #define FREQ_MARK 1200 #define FREQ_SPACE 2200 #define FREQ_SAMP 22050 #define BAUD 1200 #define SUBSAMP 2 /* ---------------------------------------------------------------------- */ #define CORRLEN ((int)(FREQ_SAMP/BAUD)) #define SPHASEINC (0x10000u*BAUD*SUBSAMP/FREQ_SAMP) static float corr_mark_i[CORRLEN]; static float corr_mark_q[CORRLEN]; static float corr_space_i[CORRLEN]; static float corr_space_q[CORRLEN]; /* ---------------------------------------------------------------------- */ static void afsk12_init(struct demod_state *s) { float f; int i; hdlc_init(s); memset(&s->l1.afsk12, 0, sizeof(s->l1.afsk12)); for (f = 0, i = 0; i < CORRLEN; i++) { corr_mark_i[i] = cos(f); corr_mark_q[i] = sin(f); f += 2.0*M_PI*FREQ_MARK/FREQ_SAMP; } for (f = 0, i = 0; i < CORRLEN; i++) { corr_space_i[i] = cos(f); corr_space_q[i] = sin(f); f += 2.0*M_PI*FREQ_SPACE/FREQ_SAMP; } } /* ---------------------------------------------------------------------- */ static void afsk12_demod(struct demod_state *s, float *buffer, int length) { float f; unsigned char curbit; if (s->l1.afsk12.subsamp) { int numfill = SUBSAMP - s->l1.afsk12.subsamp; if (length < numfill) { s->l1.afsk12.subsamp += length; return; } buffer += numfill; length -= numfill; s->l1.afsk12.subsamp = 0; } for (; length >= SUBSAMP; length -= SUBSAMP, buffer += SUBSAMP) { f = fsqr(mac(buffer, corr_mark_i, CORRLEN)) + fsqr(mac(buffer, corr_mark_q, CORRLEN)) - fsqr(mac(buffer, corr_space_i, CORRLEN)) - fsqr(mac(buffer, corr_space_q, CORRLEN)); s->l1.afsk12.dcd_shreg <<= 1; s->l1.afsk12.dcd_shreg |= (f > 0); verbprintf(10, "%c", '0'+(s->l1.afsk12.dcd_shreg & 1)); /* * check if transition */ if ((s->l1.afsk12.dcd_shreg ^ (s->l1.afsk12.dcd_shreg >> 1)) & 1) { if (s->l1.afsk12.sphase < (0x8000u-(SPHASEINC/2))) s->l1.afsk12.sphase += SPHASEINC/8; else s->l1.afsk12.sphase -= SPHASEINC/8; } s->l1.afsk12.sphase += SPHASEINC; if (s->l1.afsk12.sphase >= 0x10000u) { s->l1.afsk12.sphase &= 0xffffu; s->l1.afsk12.lasts <<= 1; s->l1.afsk12.lasts |= s->l1.afsk12.dcd_shreg & 1; curbit = (s->l1.afsk12.lasts ^ (s->l1.afsk12.lasts >> 1) ^ 1) & 1; verbprintf(9, " %c ", '0'+curbit); hdlc_rxbit(s, curbit); } } s->l1.afsk12.subsamp = length; } /* ---------------------------------------------------------------------- */ const struct demod_param demod_afsk1200 = { "AFSK1200", FREQ_SAMP, CORRLEN, afsk12_init, afsk12_demod }; /* ---------------------------------------------------------------------- */ multimon-1.0/demod_afsk24.c0000644000310500031050000000730007573266454015576 0ustar bottomsbottoms/* * demod_afsk24.c -- 2400 baud AFSK demodulator * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "multimon.h" #include "filter.h" #include #include /* ---------------------------------------------------------------------- */ /* * Standard TCM3105 clock frequency: 4.4336MHz * Xtal used: 8 MHz * Ratio: 1.8044 * Mark frequency: 3970 Hz * Space frequency: 2165 Hz */ #define FREQ_MARK 3970 #define FREQ_SPACE 2165 #define FREQ_SAMP 22050 #define BAUD 2400 /* ---------------------------------------------------------------------- */ #define CORRLEN (2*(int)(FREQ_SAMP/BAUD)) #define SPHASEINC (0x10000u*BAUD/FREQ_SAMP) static float corr_mark_i[CORRLEN]; static float corr_mark_q[CORRLEN]; static float corr_space_i[CORRLEN]; static float corr_space_q[CORRLEN]; /* ---------------------------------------------------------------------- */ static void afsk24_init(struct demod_state *s) { float f; int i; hdlc_init(s); memset(&s->l1.afsk24, 0, sizeof(s->l1.afsk24)); for (f = 0, i = 0; i < CORRLEN; i++) { corr_mark_i[i] = cos(f); corr_mark_q[i] = sin(f); f += 2.0*M_PI*FREQ_MARK/FREQ_SAMP; } for (f = 0, i = 0; i < CORRLEN; i++) { corr_space_i[i] = cos(f); corr_space_q[i] = sin(f); f += 2.0*M_PI*FREQ_SPACE/FREQ_SAMP; } for (i = 0; i < CORRLEN; i++) { f = 0.54 - 0.46*cos(2*M_PI*i/(float)(CORRLEN-1)); corr_mark_i[i] *= f; corr_mark_q[i] *= f; corr_space_i[i] *= f; corr_space_q[i] *= f; } } /* ---------------------------------------------------------------------- */ static void afsk24_demod(struct demod_state *s, float *buffer, int length) { float f; unsigned char curbit; for (; length > 0; length--, buffer++) { f = fsqr(mac(buffer, corr_mark_i, CORRLEN)) + fsqr(mac(buffer, corr_mark_q, CORRLEN)) - fsqr(mac(buffer, corr_space_i, CORRLEN)) - fsqr(mac(buffer, corr_space_q, CORRLEN)); s->l1.afsk24.dcd_shreg <<= 1; s->l1.afsk24.dcd_shreg |= (f > 0); verbprintf(10, "%c", '0'+(s->l1.afsk24.dcd_shreg & 1)); /* * check if transition */ if ((s->l1.afsk24.dcd_shreg ^ (s->l1.afsk24.dcd_shreg >> 1)) & 1) { if (s->l1.afsk24.sphase < (0x8000u-(SPHASEINC/2))) s->l1.afsk24.sphase += SPHASEINC/8; else s->l1.afsk24.sphase -= SPHASEINC/8; } s->l1.afsk24.sphase += SPHASEINC; if (s->l1.afsk24.sphase >= 0x10000u) { s->l1.afsk24.sphase &= 0xffffu; s->l1.afsk24.lasts <<= 1; s->l1.afsk24.lasts |= s->l1.afsk24.dcd_shreg & 1; curbit = (s->l1.afsk24.lasts ^ (s->l1.afsk24.lasts >> 1) ^ 1) & 1; verbprintf(9, " %c ", '0'+curbit); hdlc_rxbit(s, curbit); } } } /* ---------------------------------------------------------------------- */ const struct demod_param demod_afsk2400 = { "AFSK2400", FREQ_SAMP, CORRLEN, afsk24_init, afsk24_demod }; /* ---------------------------------------------------------------------- */ multimon-1.0/demod_afsk24_2.c0000644000310500031050000000732107573266454016022 0ustar bottomsbottoms/* * demod_afsk24.c -- 2400 baud AFSK demodulator * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "multimon.h" #include "filter.h" #include #include /* ---------------------------------------------------------------------- */ /* * Standard TCM3105 clock frequency: 4.4336MHz * Xtal used: 7.3728 MHz * Ratio: 1.6629 * Mark frequency: 3658 Hz * Space frequency: 1996 Hz */ #define FREQ_MARK 3658 #define FREQ_SPACE 1996 #define FREQ_SAMP 22050 #define BAUD 2400 /* ---------------------------------------------------------------------- */ #define CORRLEN ((int)(2*FREQ_SAMP/BAUD)) #define SPHASEINC (0x10000u*BAUD/FREQ_SAMP) static float corr_mark_i[CORRLEN]; static float corr_mark_q[CORRLEN]; static float corr_space_i[CORRLEN]; static float corr_space_q[CORRLEN]; /* ---------------------------------------------------------------------- */ static void afsk24_2_init(struct demod_state *s) { float f; int i; hdlc_init(s); memset(&s->l1.afsk24, 0, sizeof(s->l1.afsk24)); for (f = 0, i = 0; i < CORRLEN; i++) { corr_mark_i[i] = cos(f); corr_mark_q[i] = sin(f); f += 2.0*M_PI*FREQ_MARK/FREQ_SAMP; } for (f = 0, i = 0; i < CORRLEN; i++) { corr_space_i[i] = cos(f); corr_space_q[i] = sin(f); f += 2.0*M_PI*FREQ_SPACE/FREQ_SAMP; } for (i = 0; i < CORRLEN; i++) { f = 0.54 - 0.46*cos(2*M_PI*i/(float)(CORRLEN-1)); corr_mark_i[i] *= f; corr_mark_q[i] *= f; corr_space_i[i] *= f; corr_space_q[i] *= f; } } /* ---------------------------------------------------------------------- */ static void afsk24_2_demod(struct demod_state *s, float *buffer, int length) { float f; unsigned char curbit; for (; length > 0; length--, buffer++) { f = fsqr(mac(buffer, corr_mark_i, CORRLEN)) + fsqr(mac(buffer, corr_mark_q, CORRLEN)) - fsqr(mac(buffer, corr_space_i, CORRLEN)) - fsqr(mac(buffer, corr_space_q, CORRLEN)); s->l1.afsk24.dcd_shreg <<= 1; s->l1.afsk24.dcd_shreg |= (f > 0); verbprintf(10, "%c", '0'+(s->l1.afsk24.dcd_shreg & 1)); /* * check if transition */ if ((s->l1.afsk24.dcd_shreg ^ (s->l1.afsk24.dcd_shreg >> 1)) & 1) { if (s->l1.afsk24.sphase < (0x8000u-(SPHASEINC/2))) s->l1.afsk24.sphase += SPHASEINC/8; else s->l1.afsk24.sphase -= SPHASEINC/8; } s->l1.afsk24.sphase += SPHASEINC; if (s->l1.afsk24.sphase >= 0x10000u) { s->l1.afsk24.sphase &= 0xffffu; s->l1.afsk24.lasts <<= 1; s->l1.afsk24.lasts |= s->l1.afsk24.dcd_shreg & 1; curbit = (s->l1.afsk24.lasts ^ (s->l1.afsk24.lasts >> 1) ^ 1) & 1; verbprintf(9, " %c ", '0'+curbit); hdlc_rxbit(s, curbit); } } } /* ---------------------------------------------------------------------- */ const struct demod_param demod_afsk2400_2 = { "AFSK2400_2", FREQ_SAMP, CORRLEN, afsk24_2_init, afsk24_2_demod }; /* ---------------------------------------------------------------------- */ multimon-1.0/demod_hapn48.c0000644000310500031050000000633410271505162015571 0ustar bottomsbottoms/* * demod_hapn48.c -- HAPN 4800 baud demodulator (G3RUH) * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "multimon.h" #include "filter.h" #include #include /* ---------------------------------------------------------------------- */ #define FREQ_SAMP 22050 #define BAUD 4800 /* ---------------------------------------------------------------------- */ #define SPHASEINC (0x10000u*BAUD/FREQ_SAMP) /* ---------------------------------------------------------------------- */ static void hapn48_init(struct demod_state *s) { hdlc_init(s); memset(&s->l1.hapn48, 0, sizeof(s->l1.hapn48)); } /* ---------------------------------------------------------------------- */ static void hapn48_demod(struct demod_state *s, float *buffer, int length) { int cursync; unsigned int curbit; for (; length > 0; length--, buffer++) { s->l1.hapn48.lvlhi *= 0.999; s->l1.hapn48.lvllo *= 0.999; if (buffer[1] > s->l1.hapn48.lvlhi) s->l1.hapn48.lvlhi = buffer[1]; if (buffer[1] < s->l1.hapn48.lvllo) s->l1.hapn48.lvllo = buffer[1]; cursync = 0; s->l1.hapn48.shreg = (s->l1.hapn48.shreg << 1) | (s->l1.hapn48.shreg & 1); if (buffer[1] > s->l1.hapn48.lvlhi * 0.5) { s->l1.hapn48.shreg |= 1; cursync = (buffer[1] > buffer[0] && buffer[1] > buffer[2]); } else if (buffer[1] < s->l1.hapn48.lvllo * 0.5) { s->l1.hapn48.shreg &= ~1; cursync = (buffer[1] < buffer[0] && buffer[1] < buffer[2]); } verbprintf(10, "%c", '0' + (s->l1.hapn48.shreg & 1)); s->l1.hapn48.sphase += SPHASEINC; if (((s->l1.hapn48.shreg >> 1) ^ s->l1.hapn48.shreg) & 1) { if (s->l1.hapn48.sphase >= 0x8000+SPHASEINC/2) s->l1.hapn48.sphase -= 0x800; else s->l1.hapn48.sphase += 0x800; } #if 0 if (cursync) { if (((s->l1.hapn48.sphase-0x8000)&0xffffu) >= 0x8000+SPHASEINC/2) s->l1.hapn48.sphase -= 0x800; else s->l1.hapn48.sphase += 0x800; } #endif if (s->l1.hapn48.sphase >= 0x10000) { s->l1.hapn48.sphase &= 0xffff; curbit = ((s->l1.hapn48.shreg >> 4) ^ s->l1.hapn48.shreg ^ 1) & 1; verbprintf(9, " %c ", '0'+curbit); hdlc_rxbit(s, curbit); } } } /* ---------------------------------------------------------------------- */ const struct demod_param demod_hapn4800 = { "HAPN4800", FREQ_SAMP, 3, hapn48_init, hapn48_demod }; /* ---------------------------------------------------------------------- */ multimon-1.0/demod_fsk96.c0000644000310500031050000001036207573266454015450 0ustar bottomsbottoms/* * demod_fsk96.c -- FSK 9600 baud demodulator (G3RUH) * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "multimon.h" #include "filter.h" #include #include /* ---------------------------------------------------------------------- */ #define FREQ_SAMP 22050 #define BAUD 9600 /* ---------------------------------------------------------------------- */ #define DESCRAM_TAP1 0x20000 #define DESCRAM_TAP2 0x01000 #define DESCRAM_TAP3 0x00001 #define DESCRAM_TAPSH1 17 #define DESCRAM_TAPSH2 12 #define DESCRAM_TAPSH3 0 #define SCRAM_TAP1 0x20000 /* X^17 */ #define SCRAM_TAPN 0x00021 /* X^0+X^5 */ /* --------------------------------------------------------------------- */ #define FILTLEN 24 #define UPSAMP 3 static const float inp_filt[3][24] = { { 0.000440, -0.001198, -0.000493, 0.003648, -0.000630, -0.008433, 0.005567, 0.015557, -0.019931, -0.026514, 0.079822, 0.181779, 0.124956, -0.002471, -0.032062, 0.008024, 0.012568, -0.006559, -0.004235, 0.003711, 0.000909, -0.001520, -0.000018, 0.000709}, { 0.000686, -0.000618, -0.001332, 0.002494, 0.002258, -0.007308, -0.001538, 0.016708, -0.004897, -0.035748, 0.034724, 0.161417, 0.161417, 0.034724, -0.035748, -0.004897, 0.016708, -0.001538, -0.007308, 0.002258, 0.002494, -0.001332, -0.000618, 0.000686}, { 0.000709, -0.000018, -0.001520, 0.000909, 0.003711, -0.004235, -0.006559, 0.012568, 0.008024, -0.032062, -0.002471, 0.124956, 0.181779, 0.079822, -0.026514, -0.019931, 0.015557, 0.005567, -0.008433, -0.000630, 0.003648, -0.000493, -0.001198, 0.000440} }; #define SPHASEINC (0x10000u*BAUD/FREQ_SAMP/UPSAMP) /* ---------------------------------------------------------------------- */ static void fsk96_init(struct demod_state *s) { hdlc_init(s); memset(&s->l1.fsk96, 0, sizeof(s->l1.fsk96)); } /* ---------------------------------------------------------------------- */ static void fsk96_demod(struct demod_state *s, float *buffer, int length) { float f; unsigned char curbit; int i; unsigned int descx; for (; length > 0; length--, buffer++) { for (i = 0; i < UPSAMP; i++) { f = mac(buffer, inp_filt[i], FILTLEN); s->l1.fsk96.dcd_shreg <<= 1; s->l1.fsk96.dcd_shreg |= (f > 0); verbprintf(10, "%c", '0'+(s->l1.fsk96.dcd_shreg & 1)); /* * check if transition */ if ((s->l1.fsk96.dcd_shreg ^ (s->l1.fsk96.dcd_shreg >> 1)) & 1) { if (s->l1.fsk96.sphase < (0x8000u-(SPHASEINC/2))) s->l1.fsk96.sphase += SPHASEINC/8; else s->l1.fsk96.sphase -= SPHASEINC/8; } s->l1.fsk96.sphase += SPHASEINC; if (s->l1.fsk96.sphase >= 0x10000u) { s->l1.fsk96.sphase &= 0xffffu; s->l1.fsk96.descram <<= 1; s->l1.fsk96.descram |= s->l1.fsk96.dcd_shreg & 1; descx = s->l1.fsk96.descram ^ (s->l1.fsk96.descram >> 1); curbit = ((descx >> DESCRAM_TAPSH1) ^ (descx >> DESCRAM_TAPSH2) ^ (descx >> DESCRAM_TAPSH3) ^ 1) & 1; verbprintf(9, " %c ", '0'+curbit); hdlc_rxbit(s, curbit); } } } } /* ---------------------------------------------------------------------- */ const struct demod_param demod_fsk9600 = { "FSK9600", FREQ_SAMP, FILTLEN, fsk96_init, fsk96_demod }; /* ---------------------------------------------------------------------- */ multimon-1.0/demod_poc5.c0000644000310500031050000000545107573266454015357 0ustar bottomsbottoms/* * demod_poc5.c -- 512 baud POCSAG demodulator * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * POCSAG (Post Office Code Standard Advisory Group) * Radio Paging Decoder * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "multimon.h" #include "filter.h" #include #include /* ---------------------------------------------------------------------- */ #define FREQ_SAMP 22050 #define BAUD 512 #define SUBSAMP 5 #define FILTLEN 1 /* ---------------------------------------------------------------------- */ #define SPHASEINC (0x10000u*BAUD*SUBSAMP/FREQ_SAMP) /* ---------------------------------------------------------------------- */ static void poc5_init(struct demod_state *s) { pocsag_init(s); memset(&s->l1.poc5, 0, sizeof(s->l1.poc5)); } /* ---------------------------------------------------------------------- */ static void poc5_demod(struct demod_state *s, float *buffer, int length) { if (s->l1.poc5.subsamp) { int numfill = SUBSAMP - s->l1.poc5.subsamp; if (length < numfill) { s->l1.poc5.subsamp += length; return; } buffer += numfill; length -= numfill; s->l1.poc5.subsamp = 0; } for (; length >= SUBSAMP; length -= SUBSAMP, buffer += SUBSAMP) { s->l1.poc5.dcd_shreg <<= 1; s->l1.poc5.dcd_shreg |= ((*buffer) > 0); verbprintf(10, "%c", '0'+(s->l1.poc5.dcd_shreg & 1)); /* * check if transition */ if ((s->l1.poc5.dcd_shreg ^ (s->l1.poc5.dcd_shreg >> 1)) & 1) { if (s->l1.poc5.sphase < (0x8000u-(SPHASEINC/2))) s->l1.poc5.sphase += SPHASEINC/8; else s->l1.poc5.sphase -= SPHASEINC/8; } s->l1.poc5.sphase += SPHASEINC; if (s->l1.poc5.sphase >= 0x10000u) { s->l1.poc5.sphase &= 0xffffu; pocsag_rxbit(s, s->l1.poc5.dcd_shreg & 1); } } s->l1.poc5.subsamp = length; } /* ---------------------------------------------------------------------- */ const struct demod_param demod_poc5 = { "POCSAG512", FREQ_SAMP, FILTLEN, poc5_init, poc5_demod }; /* ---------------------------------------------------------------------- */ multimon-1.0/demod_poc12.c0000644000310500031050000000550607573266454015436 0ustar bottomsbottoms/* * demod_poc12.c -- 1200 baud POCSAG demodulator * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * POCSAG (Post Office Code Standard Advisory Group) * Radio Paging Decoder * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "multimon.h" #include "filter.h" #include #include /* ---------------------------------------------------------------------- */ #define FREQ_SAMP 22050 #define BAUD 1200 #define SUBSAMP 2 #define FILTLEN 1 /* ---------------------------------------------------------------------- */ #define SPHASEINC (0x10000u*BAUD*SUBSAMP/FREQ_SAMP) /* ---------------------------------------------------------------------- */ static void poc12_init(struct demod_state *s) { pocsag_init(s); memset(&s->l1.poc12, 0, sizeof(s->l1.poc12)); } /* ---------------------------------------------------------------------- */ static void poc12_demod(struct demod_state *s, float *buffer, int length) { if (s->l1.poc12.subsamp) { int numfill = SUBSAMP - s->l1.poc12.subsamp; if (length < numfill) { s->l1.poc12.subsamp += length; return; } buffer += numfill; length -= numfill; s->l1.poc12.subsamp = 0; } for (; length >= SUBSAMP; length -= SUBSAMP, buffer += SUBSAMP) { s->l1.poc12.dcd_shreg <<= 1; s->l1.poc12.dcd_shreg |= ((*buffer) > 0); verbprintf(10, "%c", '0'+(s->l1.poc12.dcd_shreg & 1)); /* * check if transition */ if ((s->l1.poc12.dcd_shreg ^ (s->l1.poc12.dcd_shreg >> 1)) & 1) { if (s->l1.poc12.sphase < (0x8000u-(SPHASEINC/2))) s->l1.poc12.sphase += SPHASEINC/8; else s->l1.poc12.sphase -= SPHASEINC/8; } s->l1.poc12.sphase += SPHASEINC; if (s->l1.poc12.sphase >= 0x10000u) { s->l1.poc12.sphase &= 0xffffu; pocsag_rxbit(s, s->l1.poc12.dcd_shreg & 1); } } s->l1.poc12.subsamp = length; } /* ---------------------------------------------------------------------- */ const struct demod_param demod_poc12 = { "POCSAG1200", FREQ_SAMP, FILTLEN, poc12_init, poc12_demod }; /* ---------------------------------------------------------------------- */ multimon-1.0/demod_poc24.c0000644000310500031050000000502207573266454015432 0ustar bottomsbottoms/* * demod_poc24.c -- 2400 baud POCSAG demodulator * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * POCSAG (Post Office Code Standard Advisory Group) * Radio Paging Decoder * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "multimon.h" #include "filter.h" #include #include /* ---------------------------------------------------------------------- */ #define FREQ_SAMP 22050 #define BAUD 2400 #define FILTLEN 1 /* ---------------------------------------------------------------------- */ #define SPHASEINC (0x10000u*BAUD/FREQ_SAMP) /* ---------------------------------------------------------------------- */ static void poc24_init(struct demod_state *s) { pocsag_init(s); memset(&s->l1.poc24, 0, sizeof(s->l1.poc24)); } /* ---------------------------------------------------------------------- */ static void poc24_demod(struct demod_state *s, float *buffer, int length) { for (; length > 0; length--, buffer++) { s->l1.poc24.dcd_shreg <<= 1; s->l1.poc24.dcd_shreg |= ((*buffer) > 0); verbprintf(10, "%c", '0'+(s->l1.poc24.dcd_shreg & 1)); /* * check if transition */ if ((s->l1.poc24.dcd_shreg ^ (s->l1.poc24.dcd_shreg >> 1)) & 1) { if (s->l1.poc24.sphase < (0x8000u-(SPHASEINC/2))) s->l1.poc24.sphase += SPHASEINC/8; else s->l1.poc24.sphase -= SPHASEINC/8; } s->l1.poc24.sphase += SPHASEINC; if (s->l1.poc24.sphase >= 0x10000u) { s->l1.poc24.sphase &= 0xffffu; pocsag_rxbit(s, s->l1.poc24.dcd_shreg & 1); } } } /* ---------------------------------------------------------------------- */ const struct demod_param demod_poc24 = { "POCSAG2400", FREQ_SAMP, FILTLEN, poc24_init, poc24_demod }; /* ---------------------------------------------------------------------- */ multimon-1.0/demod_dtmf.c0000644000310500031050000001046207573266454015441 0ustar bottomsbottoms/* * demod_dtmf.c -- DTMF signalling demodulator/decoder * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "multimon.h" #include "filter.h" #include #include /* ---------------------------------------------------------------------- */ /* * * DTMF frequencies * * 1209 1336 1477 1633 * 697 1 2 3 A * 770 4 5 6 B * 852 7 8 9 C * 941 * 0 # D * */ #define SAMPLE_RATE 22050 #define BLOCKLEN (SAMPLE_RATE/100) /* 10ms blocks */ #define BLOCKNUM 4 /* must match numbers in multimon.h */ #define PHINC(x) ((x)*0x10000/SAMPLE_RATE) static const char *dtmf_transl = "123A456B789C*0#D"; static const unsigned int dtmf_phinc[8] = { PHINC(1209), PHINC(1336), PHINC(1477), PHINC(1633), PHINC(697), PHINC(770), PHINC(852), PHINC(941) }; /* ---------------------------------------------------------------------- */ static void dtmf_init(struct demod_state *s) { memset(&s->l1.dtmf, 0, sizeof(s->l1.dtmf)); } /* ---------------------------------------------------------------------- */ static int find_max_idx(const float *f) { float en = 0; int idx = -1, i; for (i = 0; i < 4; i++) if (f[i] > en) { en = f[i]; idx = i; } if (idx < 0) return -1; en *= 0.1; for (i = 0; i < 4; i++) if (idx != i && f[i] > en) return -1; return idx; } /* ---------------------------------------------------------------------- */ static inline int process_block(struct demod_state *s) { float tote; float totte[16]; int i, j; tote = 0; for (i = 0; i < BLOCKNUM; i++) tote += s->l1.dtmf.energy[i]; for (i = 0; i < 16; i++) { totte[i] = 0; for (j = 0; j < BLOCKNUM; j++) totte[i] += s->l1.dtmf.tenergy[j][i]; } for (i = 0; i < 8; i++) totte[i] = fsqr(totte[i]) + fsqr(totte[i+8]); memmove(s->l1.dtmf.energy+1, s->l1.dtmf.energy, sizeof(s->l1.dtmf.energy) - sizeof(s->l1.dtmf.energy[0])); s->l1.dtmf.energy[0] = 0; memmove(s->l1.dtmf.tenergy+1, s->l1.dtmf.tenergy, sizeof(s->l1.dtmf.tenergy) - sizeof(s->l1.dtmf.tenergy[0])); memset(s->l1.dtmf.tenergy, 0, sizeof(s->l1.dtmf.tenergy[0])); tote *= (BLOCKNUM*BLOCKLEN*0.5); /* adjust for block lengths */ verbprintf(10, "DTMF: Energies: %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f\n", tote, totte[0], totte[1], totte[2], totte[3], totte[4], totte[5], totte[6], totte[7]); if ((i = find_max_idx(totte)) < 0) return -1; if ((j = find_max_idx(totte+4)) < 0) return -1; if ((tote * 0.4) > (totte[i] + totte[j+4])) return -1; return (i & 3) | ((j << 2) & 0xc); } /* ---------------------------------------------------------------------- */ static void dtmf_demod(struct demod_state *s, float *buffer, int length) { float s_in; int i; for (; length > 0; length--, buffer++) { s_in = *buffer; s->l1.dtmf.energy[0] += fsqr(s_in); for (i = 0; i < 8; i++) { s->l1.dtmf.tenergy[0][i] += COS(s->l1.dtmf.ph[i]) * s_in; s->l1.dtmf.tenergy[0][i+8] += SIN(s->l1.dtmf.ph[i]) * s_in; s->l1.dtmf.ph[i] += dtmf_phinc[i]; } if ((s->l1.dtmf.blkcount--) <= 0) { s->l1.dtmf.blkcount = BLOCKLEN; i = process_block(s); if (i != s->l1.dtmf.lastch && i >= 0) verbprintf(0, "DTMF: %c\n", dtmf_transl[i]); s->l1.dtmf.lastch = i; } } } /* ---------------------------------------------------------------------- */ const struct demod_param demod_dtmf = { "DTMF", SAMPLE_RATE, 0, dtmf_init, dtmf_demod }; /* ---------------------------------------------------------------------- */ multimon-1.0/demod_zvei.c0000644000310500031050000001075007573266454015464 0ustar bottomsbottoms/* * demod_zvei.c -- ZVEI signalling demodulator/decoder * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "multimon.h" #include "filter.h" #include #include /* ---------------------------------------------------------------------- */ #define SAMPLE_RATE 22050 #define BLOCKLEN (SAMPLE_RATE/100) /* 10ms blocks */ #define BLOCKNUM 4 /* must match numbers in multimon.h */ #define PHINC(x) ((x)*0x10000/SAMPLE_RATE) static const unsigned int zvei_freq[16] = { PHINC(2400), PHINC(1060), PHINC(1160), PHINC(1270), PHINC(1400), PHINC(1530), PHINC(1670), PHINC(1830), PHINC(2000), PHINC(2200), PHINC(2800), PHINC(810), PHINC(970), PHINC(886), PHINC(2600), PHINC(0) }; static const unsigned int zveis_freq[16] = { PHINC(2400), PHINC(1060), PHINC(1160), PHINC(1270), PHINC(1400), PHINC(1530), PHINC(1670), PHINC(1830), PHINC(2000), PHINC(2200), PHINC(886), PHINC(810), PHINC(740), PHINC(680), PHINC(970), PHINC(0) }; /* ---------------------------------------------------------------------- */ static void zvei_init(struct demod_state *s) { memset(&s->l1.zvei, 0, sizeof(s->l1.zvei)); } /* ---------------------------------------------------------------------- */ static int find_max_idx(const float *f) { float en = 0; int idx = -1, i; for (i = 0; i < 16; i++) if (f[i] > en) { en = f[i]; idx = i; } if (idx < 0) return -1; en *= 0.1; for (i = 0; i < 16; i++) if (idx != i && f[i] > en) return -1; return idx; } /* ---------------------------------------------------------------------- */ static inline int process_block(struct demod_state *s) { float tote; float totte[32]; int i, j; tote = 0; for (i = 0; i < BLOCKNUM; i++) tote += s->l1.zvei.energy[i]; for (i = 0; i < 32; i++) { totte[i] = 0; for (j = 0; j < BLOCKNUM; j++) totte[i] += s->l1.zvei.tenergy[j][i]; } for (i = 0; i < 16; i++) totte[i] = fsqr(totte[i]) + fsqr(totte[i+16]); memmove(s->l1.zvei.energy+1, s->l1.zvei.energy, sizeof(s->l1.zvei.energy) - sizeof(s->l1.zvei.energy[0])); s->l1.zvei.energy[0] = 0; memmove(s->l1.zvei.tenergy+1, s->l1.zvei.tenergy, sizeof(s->l1.zvei.tenergy) - sizeof(s->l1.zvei.tenergy[0])); memset(s->l1.zvei.tenergy, 0, sizeof(s->l1.zvei.tenergy[0])); tote *= (BLOCKNUM*BLOCKLEN*0.5); /* adjust for block lengths */ verbprintf(10, "ZVEI: Energies: %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f" " %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f\n", tote, totte[0], totte[1], totte[2], totte[3], totte[4], totte[5], totte[6], totte[7], totte[8], totte[9], totte[10], totte[11], totte[12], totte[13], totte[14], totte[15]); if ((i = find_max_idx(totte)) < 0) return -1; if ((tote * 0.4) > totte[i]) return -1; return i; } /* ---------------------------------------------------------------------- */ static void zvei_demod(struct demod_state *s, float *buffer, int length) { float s_in; int i; for (; length > 0; length--, buffer++) { s_in = *buffer; s->l1.zvei.energy[0] += fsqr(s_in); for (i = 0; i < 16; i++) { s->l1.zvei.tenergy[0][i] += COS(s->l1.zvei.ph[i]) * s_in; s->l1.zvei.tenergy[0][i+16] += SIN(s->l1.zvei.ph[i]) * s_in; s->l1.zvei.ph[i] += zvei_freq[i]; } if ((s->l1.zvei.blkcount--) <= 0) { s->l1.zvei.blkcount = BLOCKLEN; i = process_block(s); if (i != s->l1.zvei.lastch && i >= 0) verbprintf(0, "ZVEI: %1x\n", i); s->l1.zvei.lastch = i; } } } /* ---------------------------------------------------------------------- */ const struct demod_param demod_zvei = { "ZVEI", SAMPLE_RATE, 0, zvei_init, zvei_demod }; /* ---------------------------------------------------------------------- */ multimon-1.0/demod_display.c0000644000310500031050000000504407573266454016154 0ustar bottomsbottoms/* * demod_display.c -- signal display * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "multimon.h" #include #include #include #include #include #include #include #include #include /* ---------------------------------------------------------------------- */ #define SAMPLING_RATE 22050 /* ---------------------------------------------------------------------- */ static void scope_init(struct demod_state *s) { memset(&s->l1.scope, 0, sizeof(s->l1.scope)); s->l1.scope.dispnum = xdisp_start(); if (s->l1.scope.dispnum == -1) return; } /* ---------------------------------------------------------------------- */ #define MEMSIZE sizeof(s->l1.scope.data)/sizeof(s->l1.scope.data[0]) static void scope_demod(struct demod_state *s, float *buffer, int length) { float *src, *dst; int i, j; if (s->l1.scope.dispnum == -1) return; if (length >= MEMSIZE) { src = buffer+length-MEMSIZE; dst = s->l1.scope.data; i = MEMSIZE; } else { i = MEMSIZE-length; memmove(s->l1.scope.data, s->l1.scope.data+i, i*sizeof(s->l1.scope.data[0])); src = buffer; dst = s->l1.scope.data+i; i = length; } s->l1.scope.datalen += i; memcpy(dst, src, i*sizeof(s->l1.scope.data[0])); if (s->l1.scope.datalen < MEMSIZE) return; if (xdisp_update(s->l1.scope.dispnum, s->l1.scope.data)) s->l1.scope.datalen = 0; } /* ---------------------------------------------------------------------- */ const struct demod_param demod_scope = { "SCOPE", SAMPLING_RATE, 0, scope_init, scope_demod }; /* ---------------------------------------------------------------------- */ multimon-1.0/hdlc.c0000644000310500031050000002461407573266454014255 0ustar bottomsbottoms/* * hdlc.c -- hdlc decoder and AX.25 packet dump * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "multimon.h" #include /* ---------------------------------------------------------------------- */ /* * the CRC routines are stolen from WAMPES * by Dieter Deyke */ static const unsigned short crc_ccitt_table[] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; /* ---------------------------------------------------------------------- */ static inline int check_crc_ccitt(const unsigned char *buf, int cnt) { unsigned int crc = 0xffff; for (; cnt > 0; cnt--) crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff]; return (crc & 0xffff) == 0xf0b8; } /* ---------------------------------------------------------------------- */ static void ax25_disp_packet(struct demod_state *s, unsigned char *bp, unsigned int len) { unsigned char v1=1,cmd=0; unsigned char i,j; if (!bp || len < 10) return; #if 1 if (!check_crc_ccitt(bp, len)) return; #endif len -= 2; if (bp[1] & 1) { /* * FlexNet Header Compression */ v1 = 0; cmd = (bp[1] & 2) != 0; verbprintf(0, "%s: fm ? to ", s->dem_par->name); i = (bp[2] >> 2) & 0x3f; if (i) verbprintf(0, "%c",i+0x20); i = ((bp[2] << 4) | ((bp[3] >> 4) & 0xf)) & 0x3f; if (i) verbprintf(0, "%c",i+0x20); i = ((bp[3] << 2) | ((bp[4] >> 6) & 3)) & 0x3f; if (i) verbprintf(0, "%c",i+0x20); i = bp[4] & 0x3f; if (i) verbprintf(0, "%c",i+0x20); i = (bp[5] >> 2) & 0x3f; if (i) verbprintf(0, "%c",i+0x20); i = ((bp[5] << 4) | ((bp[6] >> 4) & 0xf)) & 0x3f; if (i) verbprintf(0, "%c",i+0x20); verbprintf(0, "-%u QSO Nr %u", bp[6] & 0xf, (bp[0] << 6) | (bp[1] >> 2)); bp += 7; len -= 7; } else { /* * normal header */ if (len < 15) return; if ((bp[6] & 0x80) != (bp[13] & 0x80)) { v1 = 0; cmd = (bp[6] & 0x80); } verbprintf(0, "%s: fm ", s->dem_par->name); for(i = 7; i < 13; i++) if ((bp[i] &0xfe) != 0x40) verbprintf(0, "%c",bp[i] >> 1); verbprintf(0, "-%u to ",(bp[13] >> 1) & 0xf); for(i = 0; i < 6; i++) if ((bp[i] &0xfe) != 0x40) verbprintf(0, "%c",bp[i] >> 1); verbprintf(0, "-%u",(bp[6] >> 1) & 0xf); bp += 14; len -= 14; if ((!(bp[-1] & 1)) && (len >= 7)) verbprintf(0, " via "); while ((!(bp[-1] & 1)) && (len >= 7)) { for(i = 0; i < 6; i++) if ((bp[i] &0xfe) != 0x40) verbprintf(0, "%c",bp[i] >> 1); verbprintf(0, "-%u",(bp[6] >> 1) & 0xf); bp += 7; len -= 7; if ((!(bp[-1] & 1)) && (len >= 7)) verbprintf(0, ","); } } if(!len) return; i = *bp++; len--; j = v1 ? ((i & 0x10) ? '!' : ' ') : ((i & 0x10) ? (cmd ? '+' : '-') : (cmd ? '^' : 'v')); if (!(i & 1)) { /* * Info frame */ verbprintf(0, " I%u%u%c",(i >> 5) & 7,(i >> 1) & 7,j); } else if (i & 2) { /* * U frame */ switch (i & (~0x10)) { case 0x03: verbprintf(0, " UI%c",j); break; case 0x2f: verbprintf(0, " SABM%c",j); break; case 0x43: verbprintf(0, " DISC%c",j); break; case 0x0f: verbprintf(0, " DM%c",j); break; case 0x63: verbprintf(0, " UA%c",j); break; case 0x87: verbprintf(0, " FRMR%c",j); break; default: verbprintf(0, " unknown U (0x%x)%c",i & (~0x10),j); break; } } else { /* * supervisory */ switch (i & 0xf) { case 0x1: verbprintf(0, " RR%u%c",(i >> 5) & 7,j); break; case 0x5: verbprintf(0, " RNR%u%c",(i >> 5) & 7,j); break; case 0x9: verbprintf(0, " REJ%u%c",(i >> 5) & 7,j); break; default: verbprintf(0, " unknown S (0x%x)%u%c", i & 0xf, (i >> 5) & 7, j); break; } } if (!len) { verbprintf(0, "\n"); return; } verbprintf(0, " pid=%02X\n", *bp++); len--; j = 0; while (len) { i = *bp++; if ((i >= 32) && (i < 128)) verbprintf(0, "%c",i); else if (i == 13) { if (j) verbprintf(0, "\n"); j = 0; } else verbprintf(0, "."); if (i >= 32) j = 1; len--; } if (j) verbprintf(0, "\n"); } /* ---------------------------------------------------------------------- */ void hdlc_init(struct demod_state *s) { memset(&s->l2.hdlc, 0, sizeof(s->l2.hdlc)); } /* ---------------------------------------------------------------------- */ void hdlc_rxbit(struct demod_state *s, int bit) { s->l2.hdlc.rxbitstream <<= 1; s->l2.hdlc.rxbitstream |= !!bit; if ((s->l2.hdlc.rxbitstream & 0xff) == 0x7e) { if (s->l2.hdlc.rxstate && (s->l2.hdlc.rxptr - s->l2.hdlc.rxbuf) > 2) ax25_disp_packet(s, s->l2.hdlc.rxbuf, s->l2.hdlc.rxptr - s->l2.hdlc.rxbuf); s->l2.hdlc.rxstate = 1; s->l2.hdlc.rxptr = s->l2.hdlc.rxbuf; s->l2.hdlc.rxbitbuf = 0x80; return; } if ((s->l2.hdlc.rxbitstream & 0x7f) == 0x7f) { s->l2.hdlc.rxstate = 0; return; } if (!s->l2.hdlc.rxstate) return; if ((s->l2.hdlc.rxbitstream & 0x3f) == 0x3e) /* stuffed bit */ return; if (s->l2.hdlc.rxbitstream & 1) s->l2.hdlc.rxbitbuf |= 0x100; if (s->l2.hdlc.rxbitbuf & 1) { if (s->l2.hdlc.rxptr >= s->l2.hdlc.rxbuf+sizeof(s->l2.hdlc.rxbuf)) { s->l2.hdlc.rxstate = 0; verbprintf(1, "Error: packet size too large\n"); return; } *s->l2.hdlc.rxptr++ = s->l2.hdlc.rxbitbuf >> 1; s->l2.hdlc.rxbitbuf = 0x80; return; } s->l2.hdlc.rxbitbuf >>= 1; } /* ---------------------------------------------------------------------- */ multimon-1.0/pocsag.c0000644000310500031050000003053307573266454014614 0ustar bottomsbottoms/* * pocsag.c -- POCSAG protocol decoder * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * POCSAG (Post Office Code Standard Advisory Group) * Radio Paging Decoder * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "multimon.h" #include /* ---------------------------------------------------------------------- */ #define CHARSET_LATIN1 /* ---------------------------------------------------------------------- */ /* * the code used by POCSAG is a (n=31,k=21) BCH Code with dmin=5, * thus it could correct two bit errors in a 31-Bit codeword. * It is a systematic code. * The generator polynomial is: * g(x) = x^10+x^9+x^8+x^6+x^5+x^3+1 * The parity check polynomial is: * h(x) = x^21+x^20+x^18+x^16+x^14+x^13+x^12+x^11+x^8+x^5+x^3+1 * g(x) * h(x) = x^n+1 */ #define BCH_POLY 03551 /* octal */ #define BCH_N 31 #define BCH_K 21 /* * some codewords with special POCSAG meaning */ #define POCSAG_SYNC 0x7cd215d8 #define POCSAG_SYNCINFO 0x7cf21436 #define POCSAG_IDLE 0x7a89c197 #define POCSAG_SYNC_WORDS ((2000000 >> 3) << 13) /* ---------------------------------------------------------------------- */ static unsigned char service_mask = 0x87; /* ---------------------------------------------------------------------- */ static inline unsigned char even_parity(unsigned long data) { unsigned int temp = data ^ (data >> 16); temp = temp ^ (temp >> 8); temp = temp ^ (temp >> 4); temp = temp ^ (temp >> 2); temp = temp ^ (temp >> 1); return temp & 1; } /* ---------------------------------------------------------------------- */ static unsigned long pocsag_code(unsigned long data) { unsigned long ret = data << (BCH_N-BCH_K), shreg = ret; unsigned long mask = 1L << (BCH_N-1), coeff = BCH_POLY << (BCH_K-1); int n = BCH_K; for(; n > 0; mask >>= 1, coeff >>= 1, n--) if (shreg & mask) shreg ^= coeff; ret ^= shreg; ret = (ret << 1) | even_parity(ret); verbprintf(9, "BCH coder: data: %08lx shreg: %08lx ret: %08lx\n", data, shreg, ret); return ret; } /* ---------------------------------------------------------------------- */ static unsigned int pocsag_syndrome(unsigned long data) { unsigned long shreg = data >> 1; /* throw away parity bit */ unsigned long mask = 1L << (BCH_N-1), coeff = BCH_POLY << (BCH_K-1); int n = BCH_K; for(; n > 0; mask >>= 1, coeff >>= 1, n--) if (shreg & mask) shreg ^= coeff; if (even_parity(data)) shreg |= (1 << (BCH_N - BCH_K)); verbprintf(9, "BCH syndrome: data: %08lx syn: %08lx\n", data, shreg); return shreg; } /* ---------------------------------------------------------------------- */ static void print_msg_numeric(struct l2_pocsag_rx *rx) { static const char *conv_table = "084 2.6]195-3U7["; unsigned char *bp = rx->buffer; int len = rx->numnibbles; char buf[256], *cp = buf; if (len >= sizeof(buf)) len = sizeof(buf)-1; for (; len > 0; bp++, len -= 2) { *cp++ = conv_table[(*bp >> 4) & 0xf]; if (len > 1) *cp++ = conv_table[*bp & 0xf]; } *cp = '\0'; verbprintf(0, "%s\n", buf); } /* ---------------------------------------------------------------------- */ static char *translate_alpha(unsigned char chr) { static const struct trtab { unsigned char code; char *str; } trtab[] = {{ 0, "" }, { 1, "" }, { 2, "" }, { 3, "" }, { 4, "" }, { 5, "" }, { 6, "" }, { 7, "" }, { 8, "" }, { 9, "" }, { 10, "" }, { 11, "" }, { 12, "" }, { 13, "" }, { 14, "" }, { 15, "" }, { 16, "" }, { 17, "" }, { 18, "" }, { 19, "" }, { 20, "" }, { 21, "" }, { 22, "" }, { 23, "" }, { 24, "" }, { 25, "" }, { 26, "" }, { 27, "" }, { 28, "" }, { 29, "" }, { 30, "" }, { 31, "" }, #ifdef CHARSET_LATIN1 { 0x5b, "\304" }, /* upper case A dieresis */ { 0x5c, "\326" }, /* upper case O dieresis */ { 0x5d, "\334" }, /* upper case U dieresis */ { 0x7b, "\344" }, /* lower case a dieresis */ { 0x7c, "\366" }, /* lower case o dieresis */ { 0x7d, "\374" }, /* lower case u dieresis */ { 0x7e, "\337" }}; /* sharp s */ #else /* CHARSET_LATIN1 */ { 0x5b, "AE" }, /* upper case A dieresis */ { 0x5c, "OE" }, /* upper case O dieresis */ { 0x5d, "UE" }, /* upper case U dieresis */ { 0x7b, "ae" }, /* lower case a dieresis */ { 0x7c, "oe" }, /* lower case o dieresis */ { 0x7d, "ue" }, /* lower case u dieresis */ { 0x7e, "ss" }}; /* sharp s */ #endif /* CHARSET_LATIN1 */ int min = 0, max = (sizeof(trtab) / sizeof(trtab[0])) - 1; /* * binary search, list must be ordered! */ for (;;) { int mid = (min+max) >> 1; const struct trtab *tb = trtab + mid; int cmp = ((int) tb->code) - ((int) chr); if (!cmp) return tb->str; if (cmp < 0) { min = mid+1; if (min > max) return NULL; } if (cmp > 0) { max = mid-1; if (max < min) return NULL; } } } /* ---------------------------------------------------------------------- */ static void print_msg_alpha(struct l2_pocsag_rx *rx) { unsigned long data = 0; int datalen = 0; unsigned char *bp = rx->buffer; int len = rx->numnibbles; char buf[256], *cp = buf; int buffree = sizeof(buf)-1; unsigned char curchr; char *tstr; while (len > 0) { while (datalen < 7 && len > 0) { if (len == 1) { data = (data << 4) | ((*bp >> 4) & 0xf); datalen += 4; len = 0; } else { data = (data << 8) | *bp++; datalen += 8; len -= 2; } } if (datalen < 7) continue; datalen -= 7; curchr = ((data >> datalen) & 0x7f) << 1; curchr = ((curchr & 0xf0) >> 4) | ((curchr & 0x0f) << 4); curchr = ((curchr & 0xcc) >> 2) | ((curchr & 0x33) << 2); curchr = ((curchr & 0xaa) >> 1) | ((curchr & 0x55) << 1); tstr = translate_alpha(curchr); if (tstr) { int tlen = strlen(tstr); if (buffree >= tlen) { memcpy(cp, tstr, tlen); cp += tlen; buffree -= tlen; } } else if (buffree > 0) { *cp++ = curchr; buffree--; } } *cp = '\0'; verbprintf(0, "%s\n", buf); } /* ---------------------------------------------------------------------- */ static void print_msg_skyper(struct l2_pocsag_rx *rx) { unsigned long data = 0; int datalen = 0; unsigned char *bp = rx->buffer; int len = rx->numnibbles; char buf[256], *cp = buf; int buffree = sizeof(buf)-1; unsigned char curchr; char *tstr; while (len > 0) { while (datalen < 7 && len > 0) { if (len == 1) { data = (data << 4) | ((*bp >> 4) & 0xf); datalen += 4; len = 0; } else { data = (data << 8) | *bp++; datalen += 8; len -= 2; } } if (datalen < 7) continue; datalen -= 7; curchr = ((data >> datalen) & 0x7f) << 1; curchr = ((curchr & 0xf0) >> 4) | ((curchr & 0x0f) << 4); curchr = ((curchr & 0xcc) >> 2) | ((curchr & 0x33) << 2); curchr = ((curchr & 0xaa) >> 1) | ((curchr & 0x55) << 1); tstr = translate_alpha(curchr-1); if (tstr) { int tlen = strlen(tstr); if (buffree >= tlen) { memcpy(cp, tstr, tlen); cp += tlen; buffree -= tlen; } } else if (buffree > 0) { *cp++ = curchr-1; buffree--; } } *cp = '\0'; verbprintf(0, "%s\n", buf); } /* ---------------------------------------------------------------------- */ static void pocsag_printmessage(struct demod_state *s, struct l2_pocsag_rx *rx, const char *add_name) { verbprintf(0, "%s%s: Address: %7lu Function: %1u\n", s->dem_par->name, add_name, rx->adr, rx->func); if (!rx->numnibbles) return; if (service_mask & (0x01 << rx->func)) { verbprintf(0, "%s%s: Numeric: ", s->dem_par->name, add_name); print_msg_numeric(rx); } if (service_mask & (0x10 << rx->func)) { if (rx->func == 3 && rx->adr >= 4000 && rx->adr <= 5000) { verbprintf(0, "%s%s: Alpha (SKYPER): ", s->dem_par->name, add_name); print_msg_skyper(rx); } else { verbprintf(0, "%s%s: Alpha: ", s->dem_par->name, add_name); print_msg_alpha(rx); } } } /* ---------------------------------------------------------------------- */ void pocsag_init(struct demod_state *s) { memset(&s->l2.pocsag, 0, sizeof(s->l2.pocsag)); } /* ---------------------------------------------------------------------- */ static void do_one_bit(struct demod_state *s, struct l2_pocsag_rx *rx, unsigned long rx_data, const char *add_name) { unsigned char rxword; if (!rx->rx_sync) { if (rx_data == POCSAG_SYNC || rx_data == POCSAG_SYNCINFO) { rx->rx_sync = 2; rx->rx_bit = rx->rx_word = 0; rx->func = -1; return; } return; } if ((++(rx->rx_bit)) < 32) return; /* * one complete word received */ rx->rx_bit = 0; /* * check codeword */ if (pocsag_syndrome(rx_data)) { /* * codeword not valid */ rx->rx_sync--; verbprintf(7, "%s: Bad codeword: %08lx%s\n", s->dem_par->name, rx_data, rx->rx_sync ? "" : "sync lost"); if (!(rx->func & (~3))) { verbprintf(0, "%s%s: Warning: message garbled\n", s->dem_par->name, add_name); pocsag_printmessage(s, rx, add_name); } rx->func = -1; /* invalidate message */ return; } /* do something with the data */ verbprintf(8, "%s%s: Codeword: %08lx\n", s->dem_par->name, add_name, rx_data); rxword = rx->rx_word++; if (rxword >= 16) { /* * received word shoud be a * frame synch */ rx->rx_word = 0; if ((rx_data == POCSAG_SYNC) || (rx_data == POCSAG_SYNCINFO)) rx->rx_sync = 10; else rx->rx_sync -= 2; return; } if (rx_data == POCSAG_IDLE) { /* * it seems that we can output the message right here */ if (!(rx->func & (~3))) pocsag_printmessage(s, rx, add_name); rx->func = -1; /* invalidate message */ return; } if (rx_data & 0x80000000) { /* * this is a data word */ unsigned long data; unsigned char *bp; if (rx->func & (~3)) { /* * no message being received */ verbprintf(7, "%s%s: Lonesome data codeword: %08lx\n", s->dem_par->name, add_name, rx_data); return; } if (rx->numnibbles > sizeof(rx->buffer)*2 - 5) { verbprintf(0, "%s%s: Warning: Message too long\n", s->dem_par->name, add_name); pocsag_printmessage(s, rx, add_name); rx->func = -1; return; } bp = rx->buffer + (rx->numnibbles >> 1); data = rx_data >> 11; if (rx->numnibbles & 1) { bp[0] = (bp[0] & 0xf0) | ((data >> 16) & 0xf); bp[1] = data >> 8; bp[2] = data; } else { bp[0] = data >> 12; bp[1] = data >> 4; bp[2] = data << 4; } rx->numnibbles += 5; return; } /* * process address codeword */ if (rx_data >= POCSAG_SYNC_WORDS) { unsigned char func = (rx_data >> 11) & 3; unsigned long adr = ((rx_data >> 10) & 0x1ffff8) | ((rxword >> 1) & 7); verbprintf(0, "%s%s: Nonstandard address codeword: %08lx " "func %1u adr %08lx\n", s->dem_par->name, add_name, rx_data, func, adr); return; } if (!(rx->func & (~3))) pocsag_printmessage(s, rx, add_name); rx->func = (rx_data >> 11) & 3; rx->adr = ((rx_data >> 10) & 0x1ffff8) | ((rxword >> 1) & 7); rx->numnibbles = 0; } /* ---------------------------------------------------------------------- */ void pocsag_rxbit(struct demod_state *s, int bit) { s->l2.pocsag.rx_data <<= 1; s->l2.pocsag.rx_data |= !bit; verbprintf(9, " %c ", '1'-(s->l2.pocsag.rx_data & 1)); do_one_bit(s, s->l2.pocsag.rx, ~(s->l2.pocsag.rx_data), "+"); do_one_bit(s, s->l2.pocsag.rx+1, s->l2.pocsag.rx_data, "-"); } /* ---------------------------------------------------------------------- */ multimon-1.0/gen.c0000644000310500031050000003336610271505162014075 0ustar bottomsbottoms/* * gen.c -- generate different test signals * * Copyright (C) 1997 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "gen.h" #include #include #include #include #include #include #include #include #include #include #ifdef SUN_AUDIO #include #include #include #else /* SUN_AUDIO */ #include #include #endif /* SUN_AUDIO */ /* ---------------------------------------------------------------------- */ #ifdef __sun__ #include int snprintf(char *buf, size_t sz, const char *fmt, ...) { int i; va_list arg; va_start(arg, fmt); i = vsprintf(buf, fmt, arg); va_end(arg); return i; } #endif /* __sun__ */ /* ---------------------------------------------------------------------- */ static const char *allowed_types[] = { "raw", "aiff", "au", "hcom", "sf", "voc", "cdr", "dat", "smp", "wav", "maud", "vwe", NULL }; /* ---------------------------------------------------------------------- */ typedef void (*t_init_procs)(struct gen_params *, struct gen_state *); typedef int (*t_gen_procs)(signed short *, int, struct gen_params *, struct gen_state *); static const t_init_procs init_procs[] = { gen_init_dtmf, gen_init_sine, gen_init_zvei, gen_init_hdlc }; static const t_gen_procs gen_procs[] = { gen_dtmf, gen_sine, gen_zvei, gen_hdlc }; /* ---------------------------------------------------------------------- */ #define MAX_GEN 16 static struct gen_params params[MAX_GEN]; static struct gen_state state[MAX_GEN]; static int num_gen = 0; /* ---------------------------------------------------------------------- */ static int process_buffer(short *buf, int len) { int i; int totnum = 0, num; memset(buf, 0, len*sizeof(buf[0])); for (i = 0; i < num_gen; i++) { if (params[i].type >= sizeof(gen_procs)/sizeof(gen_procs[0])) break; if (!gen_procs[params[i].type]) break; num = gen_procs[params[i].type](buf, len, params+i, state+i); if (num > totnum) totnum = num; } return totnum; } /* ---------------------------------------------------------------------- */ #ifdef SUN_AUDIO static void output_sound(unsigned int sample_rate, const char *ifname) { audio_info_t audioinfo; audio_info_t audioinfo2; audio_device_t audiodev; int fd; short buffer[8192]; short *sp; int i, num, num2; if ((fd = open(ifname ? ifname : "/dev/audio", O_WRONLY)) < 0) { perror("open"); exit (10); } if (ioctl(fd, AUDIO_GETDEV, &audiodev) == -1) { perror("ioctl: AUDIO_GETDEV"); exit (10); } AUDIO_INITINFO(&audioinfo); audioinfo.record.sample_rate = sample_rate; audioinfo.record.channels = 1; audioinfo.record.precision = 16; audioinfo.record.encoding = AUDIO_ENCODING_LINEAR; /*audioinfo.record.gain = 0x20; audioinfo.record.port = AUDIO_LINE_IN; audioinfo.monitor_gain = 0;*/ if (ioctl(fd, AUDIO_SETINFO, &audioinfo) == -1) { perror("ioctl: AUDIO_SETINFO"); exit (10); } if (ioctl(fd, I_FLUSH, FLUSHW) == -1) { perror("ioctl: I_FLUSH"); exit (10); } if (ioctl(fd, AUDIO_GETINFO, &audioinfo2) == -1) { perror("ioctl: AUDIO_GETINFO"); exit (10); } fprintf(stdout, "Audio device: name %s, ver %s, config %s, " "sampling rate %d\n", audiodev.name, audiodev.version, audiodev.config, audioinfo.record.sample_rate); do { num2 = num = process_buffer(sp = buffer, sizeof(buffer)/sizeof(buffer[0])); while (num > 0) { i = write(fd, sp, num*sizeof(sp[0])); if (i < 0 && errno != EAGAIN) { perror("write"); exit(4); } if (i > 0) { if (i % sizeof(sp[0])) fprintf(stderr, "gen: warning: write wrote noninteger number of samples\n"); num -= i / sizeof(sp[0]); } } } while (num2 > 0); close(fd); } #else /* SUN_AUDIO */ /* ---------------------------------------------------------------------- */ static void output_sound(unsigned int sample_rate, const char *ifname) { int sndparam; int fd; union { short s[8192]; unsigned char b[8192]; } b; int i; short *sp; unsigned char *bp; int fmt = 0, num, num2; if ((fd = open(ifname ? ifname : "/dev/dsp", O_WRONLY)) < 0) { perror("open"); exit (10); } sndparam = AFMT_S16_LE; /* we want 16 bits/sample signed */ /* little endian; works only on little endian systems! */ if (ioctl(fd, SNDCTL_DSP_SETFMT, &sndparam) == -1) { perror("ioctl: SNDCTL_DSP_SETFMT"); exit (10); } if (sndparam != AFMT_S16_LE) { fmt = 1; sndparam = AFMT_U8; if (ioctl(fd, SNDCTL_DSP_SETFMT, &sndparam) == -1) { perror("ioctl: SNDCTL_DSP_SETFMT"); exit (10); } if (sndparam != AFMT_U8) { perror("ioctl: SNDCTL_DSP_SETFMT"); exit (10); } } sndparam = 0; /* we want only 1 channel */ if (ioctl(fd, SNDCTL_DSP_STEREO, &sndparam) == -1) { perror("ioctl: SNDCTL_DSP_STEREO"); exit (10); } if (sndparam != 0) { fprintf(stderr, "gen: Error, cannot set the channel " "number to 1\n"); exit (10); } sndparam = sample_rate; if (ioctl(fd, SNDCTL_DSP_SPEED, &sndparam) == -1) { perror("ioctl: SNDCTL_DSP_SPEED"); exit (10); } if ((10*abs(sndparam-sample_rate)) > sample_rate) { perror("ioctl: SNDCTL_DSP_SPEED"); exit (10); } if (sndparam != sample_rate) { fprintf(stderr, "Warning: Sampling rate is %u, " "requested %u\n", sndparam, sample_rate); } #if 0 sndparam = 4; if (ioctl(fd, SOUND_PCM_SUBDIVIDE, &sndparam) == -1) { perror("ioctl: SOUND_PCM_SUBDIVIDE"); } if (sndparam != 4) { perror("ioctl: SOUND_PCM_SUBDIVIDE"); } #endif do { num2 = num = process_buffer(b.s, sizeof(b.s)/sizeof(b.s[0])); if (fmt) { for (bp = b.b, sp = b.s, i = sizeof(b.s)/sizeof(b.s[0]); i > 0; i--, bp++, sp++) *bp = 0x80 + (*sp >> 8); bp = b.b; while (num > 0) { i = write(fd, bp, num*sizeof(bp[0])); if (i < 0 && errno != EAGAIN) { perror("write"); exit(4); } if (i > 0) { if (i % sizeof(bp[0])) fprintf(stderr, "gen: warning: write wrote noninteger number of samples\n"); num -= i / sizeof(bp[0]); } } } else { sp = b.s; while (num > 0) { i = write(fd, sp, num*sizeof(sp[0])); if (i < 0 && errno != EAGAIN) { perror("write"); exit(4); } if (i > 0) { if (i % sizeof(sp[0])) fprintf(stderr, "gen: warning: write wrote noninteger number of samples\n"); num -= i / sizeof(sp[0]); } } } } while (num2 > 0); close(fd); } #endif /* SUN_AUDIO */ /* ---------------------------------------------------------------------- */ static void output_file(unsigned int sample_rate, const char *fname, const char *type) { struct stat statbuf; int pipedes[2]; int pid = 0, soxstat; int fd; int i, num, num2; short buffer[8192]; short *sp; /* * if the input type is not raw, sox is started to convert the * samples to the requested format */ if (!type || !strcmp(type, "raw")) { if ((fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0777)) < 0) { perror("open"); exit(10); } } else { if (stat(fname, &statbuf)) { perror("stat"); exit(10); } if (pipe(pipedes)) { perror("pipe"); exit(10); } if (!(pid = fork())) { char srate[8]; /* * child starts here... first set up filedescriptors, * then start sox... */ snprintf(srate, sizeof(srate), "%d", sample_rate); close(pipedes[1]); /* close writing pipe end */ close(0); /* close standard input */ if (dup2(pipedes[0], 0) < 0) perror("dup2"); close(pipedes[0]); /* close reading pipe end */ execlp("sox", "sox", "-t", "raw", "-s", "-w", "-r", srate, "-", "-t", type, fname, NULL); perror("execlp"); exit(10); } if (pid < 0) { perror("fork"); exit(10); } close(pipedes[0]); /* close reading pipe end */ fd = pipedes[1]; } /* * modulate */ do { num2 = num = process_buffer(sp = buffer, sizeof(buffer)/sizeof(buffer[0])); while (num > 0) { i = write(fd, sp, num*sizeof(sp[0])); if (i < 0 && errno != EAGAIN) { perror("write"); exit(4); } if (i > 0) { if (i % sizeof(sp[0])) fprintf(stderr, "gen: warning: write wrote noninteger number of samples\n"); num -= i / sizeof(sp[0]); } } } while (num2 > 0); close(fd); waitpid(pid, &soxstat, 0); } /* ---------------------------------------------------------------------- */ static const char usage_str[] = "gen\n" "Generates test signals\n" "(C) 1997 by Thomas Sailer HB9JNX/AE4WA\n" " -t : input file type (any other type than raw requires sox)\n" " -a : amplitude\n" " -d : encode DTMF string\n" " -z : encode ZVEI string\n" " -s : encode sine\n" " -p : encode hdlc packet\n"; int main(int argc, char *argv[]) { int c; int errflg = 0; char **otype; char *output_type = "hw"; char *cp; fprintf(stdout, "gen - (C) 1997 by Tom Sailer HB9JNX/AE4WA\n"); while ((c = getopt(argc, argv, "t:a:d:s:z:p:")) != EOF) { switch (c) { case '?': errflg++; break; case 't': for (otype = (char **)allowed_types; *otype; otype++) if (!strcmp(*otype, optarg)) { output_type = *otype; goto outtypefound; } fprintf(stderr, "invalid output type \"%s\"\n" "allowed types: ", optarg); for (otype = (char **)allowed_types; *otype; otype++) fprintf(stderr, "%s ", *otype); fprintf(stderr, "\n"); errflg++; outtypefound: break; case 'a': if (num_gen <= 0) { fprintf(stderr, "gen: no generator selected\n"); errflg++; } if (!(cp = strstr(optarg, "dB"))) cp = strstr(optarg, "db"); if (cp) { *cp = '\0'; params[num_gen-1].ampl = 16384.0 * pow(10.0, strtod(optarg, NULL) / 20.0); } else { params[num_gen-1].ampl = 16384.0 * strtod(optarg, NULL); } break; case 'd': num_gen++; if (num_gen > MAX_GEN) { fprintf(stderr, "too many generators\n"); errflg++; break; } params[num_gen-1].type = gentype_dtmf; params[num_gen-1].ampl = 16384; params[num_gen-1].p.dtmf.duration = MS(100); params[num_gen-1].p.dtmf.pause = MS(100); strncpy(params[num_gen-1].p.dtmf.str, optarg, sizeof(params[num_gen-1].p.dtmf.str)); break; case 's': num_gen++; if (num_gen > MAX_GEN) { fprintf(stderr, "too many generators\n"); errflg++; break; } params[num_gen-1].type = gentype_sine; params[num_gen-1].ampl = 16384; params[num_gen-1].p.sine.duration = MS(1000); params[num_gen-1].p.sine.freq = strtoul(optarg, NULL, 0); break; case 'z': num_gen++; if (num_gen > MAX_GEN) { fprintf(stderr, "too many generators\n"); errflg++; break; } params[num_gen-1].type = gentype_zvei; params[num_gen-1].ampl = 16384; params[num_gen-1].p.zvei.duration = MS(50); params[num_gen-1].p.zvei.pause = MS(50); strncpy(params[num_gen-1].p.zvei.str, optarg, sizeof(params[num_gen-1].p.dtmf.str)); break; case 'p': num_gen++; if (num_gen > MAX_GEN) { fprintf(stderr, "too many generators\n"); errflg++; break; } params[num_gen-1].type = gentype_hdlc; params[num_gen-1].ampl = 16384; params[num_gen-1].p.hdlc.modulation = 0; params[num_gen-1].p.hdlc.txdelay = 100; params[num_gen-1].p.hdlc.pkt[0] = ('H') << 1; params[num_gen-1].p.hdlc.pkt[1] = ('B') << 1; params[num_gen-1].p.hdlc.pkt[2] = ('9') << 1; params[num_gen-1].p.hdlc.pkt[3] = ('J') << 1; params[num_gen-1].p.hdlc.pkt[4] = ('N') << 1; params[num_gen-1].p.hdlc.pkt[5] = ('X') << 1; params[num_gen-1].p.hdlc.pkt[6] = (0x00) << 1; params[num_gen-1].p.hdlc.pkt[7] = ('A') << 1; params[num_gen-1].p.hdlc.pkt[8] = ('E') << 1; params[num_gen-1].p.hdlc.pkt[9] = ('4') << 1; params[num_gen-1].p.hdlc.pkt[10] = ('W') << 1; params[num_gen-1].p.hdlc.pkt[11] = ('A') << 1; params[num_gen-1].p.hdlc.pkt[12] = (' ') << 1; params[num_gen-1].p.hdlc.pkt[13] = ((0x00) << 1) | 1; params[num_gen-1].p.hdlc.pkt[14] = 0x03; params[num_gen-1].p.hdlc.pkt[15] = 0xf0; strncpy(params[num_gen-1].p.hdlc.pkt+16, optarg, sizeof(params[num_gen-1].p.hdlc.pkt)-16); params[num_gen-1].p.hdlc.pktlen = 16 + strlen(params[num_gen-1].p.hdlc.pkt+16); } } if (errflg || num_gen <= 0) { (void)fprintf(stderr, usage_str); exit(2); } memset(state, 0, sizeof(state)); for (c = 0; c < num_gen; c++) { if (params[c].type >= sizeof(init_procs)/sizeof(init_procs[0])) break; if (!init_procs[params[c].type]) break; init_procs[params[c].type](params+c, state+c); } if (!strcmp(output_type, "hw")) { if ((argc - optind) >= 1) output_sound(SAMPLE_RATE, argv[optind]); else output_sound(SAMPLE_RATE, NULL); exit(0); } if ((argc - optind) < 1) { (void)fprintf(stderr, "no destination file specified\n"); exit(4); } output_file(SAMPLE_RATE, argv[optind], output_type); exit(0); } multimon-1.0/gen_dtmf.c0000644000310500031050000000533007573266454015120 0ustar bottomsbottoms/* * gen_dtmf.c -- generate DTMF sequences * * Copyright (C) 1997 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "gen.h" #include #include #include /* ---------------------------------------------------------------------- */ /* * * DTMF frequencies * * 1209 1336 1477 1633 * 697 1 2 3 A * 770 4 5 6 B * 852 7 8 9 C * 941 * 0 # D * */ static const char *dtmf_transl = "123A456B789C*0#D"; #define PHINC(x) ((float)(x)*0x10000/SAMPLE_RATE) static const unsigned int row_freq[4] = { PHINC(697), PHINC(770), PHINC(852), PHINC(941) }; static const unsigned int col_freq[4] = { PHINC(1209), PHINC(1336), PHINC(1477), PHINC(1633) }; void gen_init_dtmf(struct gen_params *p, struct gen_state *s) { memset(s, 0, sizeof(struct gen_state)); } int gen_dtmf(signed short *buf, int buflen, struct gen_params *p, struct gen_state *s) { char c; char *cp; int num = 0, i; for (; buflen > 0; buflen--, buf++, num++) { if (s->s.dtmf.time <= 0) { c = p->p.dtmf.str[s->s.dtmf.ch_idx]; if (!c) return num; s->s.dtmf.ch_idx++; cp = memchr(dtmf_transl, toupper(c), 16); if (!cp) { s->s.dtmf.time = s->s.dtmf.time2 = 1; fprintf(stderr, "gen: dtmf; invalid char '%c'\n", c); } else { s->s.dtmf.time = p->p.dtmf.duration + p->p.dtmf.pause; s->s.dtmf.time2 = p->p.dtmf.duration; i = cp - dtmf_transl; s->s.dtmf.phinc_row = row_freq[(i >> 2) & 3]; s->s.dtmf.phinc_col = col_freq[i & 3]; } } else if (!s->s.dtmf.time2) { s->s.dtmf.phinc_row = s->s.dtmf.phinc_col = 0; s->s.dtmf.ph_row = s->s.dtmf.ph_col = 0xc000; } s->s.dtmf.time--; s->s.dtmf.time2--; *buf += ((p->ampl >> 1) * (COS(s->s.dtmf.ph_row) + COS(s->s.dtmf.ph_col))) >> 15; s->s.dtmf.ph_row += s->s.dtmf.phinc_row; s->s.dtmf.ph_col += s->s.dtmf.phinc_col; } return num; } multimon-1.0/gen_sin.c0000644000310500031050000000313407573266454014757 0ustar bottomsbottoms/* * gen_sine.c -- generate DTMF sequences * * Copyright (C) 1997 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "gen.h" #include /* ---------------------------------------------------------------------- */ void gen_init_sine(struct gen_params *p, struct gen_state *s) { memset(s, 0, sizeof(struct gen_state)); s->s.sine.ph = 0; s->s.sine.phinc = (float)0x10000 * p->p.sine.freq / SAMPLE_RATE; s->s.sine.time = p->p.sine.duration; } int gen_sine(signed short *buf, int buflen, struct gen_params *p, struct gen_state *s) { int num = 0; for (; (buflen > 0) && (s->s.sine.time > 0); buflen--, buf++, num++, s->s.sine.time--) { *buf += (p->ampl * COS(s->s.sine.ph)) >> 15; s->s.sine.ph += s->s.sine.phinc; } return num; } multimon-1.0/gen_zvei.c0000644000310500031050000000526707573266454015154 0ustar bottomsbottoms/* * gen_zvei.c -- generate DTMF sequences * * Copyright (C) 1997 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "gen.h" #include #include #include /* ---------------------------------------------------------------------- */ #define PHINC(x) ((float)(x)*0x10000/SAMPLE_RATE) static const unsigned int zvei_freq[16] = { PHINC(2400), PHINC(1060), PHINC(1160), PHINC(1270), PHINC(1400), PHINC(1530), PHINC(1670), PHINC(1830), PHINC(2000), PHINC(2200), PHINC(2800), PHINC(810), PHINC(970), PHINC(886), PHINC(2600), PHINC(0) }; static const unsigned int zveis_freq[16] = { PHINC(2400), PHINC(1060), PHINC(1160), PHINC(1270), PHINC(1400), PHINC(1530), PHINC(1670), PHINC(1830), PHINC(2000), PHINC(2200), PHINC(886), PHINC(810), PHINC(740), PHINC(680), PHINC(970), PHINC(0) }; void gen_init_zvei(struct gen_params *p, struct gen_state *s) { memset(s, 0, sizeof(struct gen_state)); } int gen_zvei(signed short *buf, int buflen, struct gen_params *p, struct gen_state *s) { char c; int num = 0, i; for (; buflen > 0; buflen--, buf++, num++) { if (s->s.zvei.time <= 0) { c = p->p.zvei.str[s->s.zvei.ch_idx]; if (!c) return num; s->s.zvei.ch_idx++; if (!isxdigit(c)) { s->s.zvei.time = s->s.zvei.time2 = 1; fprintf(stderr, "gen: zvei; invalid char '%c'\n", c); } else { s->s.zvei.time = p->p.zvei.duration + p->p.zvei.pause; s->s.zvei.time2 = p->p.zvei.duration; if (c >= '0' && c <= '9') i = c - '0'; else if (c >= 'A' && c <= 'F') i = c - 'A' + 10; else i = c - 'a' + 10; s->s.zvei.phinc = zvei_freq[i & 0xf]; } } else if (!s->s.zvei.time2) { s->s.zvei.phinc = 0; s->s.zvei.ph = 0xc000; } s->s.zvei.time--; s->s.zvei.time2--; *buf += (p->ampl * COS(s->s.zvei.ph)) >> 15; s->s.zvei.ph += s->s.zvei.phinc; } return num; } multimon-1.0/gen_hdlc.c0000644000310500031050000001602207573266453015077 0ustar bottomsbottoms/* * gen_hdlc.c -- generate DTMF sequences * * Copyright (C) 1997 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include "gen.h" #include /* ---------------------------------------------------------------------- */ /* * the CRC routines are stolen from WAMPES * by Dieter Deyke */ static const unsigned short crc_ccitt_table[] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; /*---------------------------------------------------------------------------*/ #if 0 static inline void append_crc_ccitt(unsigned char *buffer, int len) { unsigned int crc = 0xffff; for (;len>0;len--) crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buffer++) & 0xff]; crc ^= 0xffff; *buffer++ = crc; *buffer++ = crc >> 8; } /*---------------------------------------------------------------------------*/ static inline int check_crc_ccitt(const unsigned char *buf, int cnt) { unsigned int crc = 0xffff; for (; cnt > 0; cnt--) crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff]; return (crc & 0xffff) == 0xf0b8; } #endif /*---------------------------------------------------------------------------*/ static __inline__ int calc_crc_ccitt(const unsigned char *buf, int cnt) { unsigned int crc = 0xffff; for (; cnt > 0; cnt--) crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff]; crc ^= 0xffff; return (crc & 0xffff); } /* ---------------------------------------------------------------------- */ struct hdlctx { unsigned int bitstream; unsigned int bitbuf; int numbits; }; static void txb_addbyte(struct gen_state *s, struct hdlctx *hdlctx, unsigned char bits, unsigned char stuff) { unsigned int mask1, mask2; unsigned int mask3; int i; if (hdlctx->numbits >= 8) { if (s->s.hdlc.datalen >= sizeof(s->s.hdlc.data)) return; s->s.hdlc.data[s->s.hdlc.datalen++] = hdlctx->bitbuf; hdlctx->bitbuf >>= 8; hdlctx->numbits -= 8; } hdlctx->bitbuf |= bits << hdlctx->numbits; hdlctx->bitstream >>= 8; hdlctx->bitstream |= bits << 8; mask1 = 0x1f0; mask2 = 0x100; mask3 = 0xffffffff >> (31 - hdlctx->numbits); hdlctx->numbits += 8; if (!stuff) goto nostuff; for(i = 0; i < 8; i++, mask1 <<= 1, mask2 <<= 1, mask3 = (mask3 << 1) | 1) { if ((hdlctx->bitstream & mask1) != mask1) continue; hdlctx->bitstream &= ~mask2; hdlctx->bitbuf = (hdlctx->bitbuf & mask3) | ((hdlctx->bitbuf & (~mask3)) << 1); hdlctx->numbits++; mask3 = (mask3 << 1) | 1; } nostuff: if (hdlctx->numbits >= 8) { if (s->s.hdlc.datalen >= sizeof(s->s.hdlc.data)) return; s->s.hdlc.data[s->s.hdlc.datalen++] = hdlctx->bitbuf; hdlctx->bitbuf >>= 8; hdlctx->numbits -= 8; } } /* ---------------------------------------------------------------------- */ void gen_init_hdlc(struct gen_params *p, struct gen_state *s) { struct hdlctx hdlctx = { 0, 0, 0 }; int i; memset(s, 0, sizeof(struct gen_state)); s->s.hdlc.bitmask = 1; for (i = 0; i < (p->p.hdlc.txdelay * (1200/100) / 8); i++) txb_addbyte(s, &hdlctx, 0x7e, 0); txb_addbyte(s, &hdlctx, 0x7e, 0); for (i = 0; i < p->p.hdlc.pktlen; i++) txb_addbyte(s, &hdlctx, p->p.hdlc.pkt[i], 1); i = calc_crc_ccitt(p->p.hdlc.pkt, p->p.hdlc.pktlen); txb_addbyte(s, &hdlctx, i, 1); txb_addbyte(s, &hdlctx, i >> 8, 1); txb_addbyte(s, &hdlctx, 0x7e, 0); txb_addbyte(s, &hdlctx, 0x7e, 0); txb_addbyte(s, &hdlctx, 0x7e, 0); txb_addbyte(s, &hdlctx, 0x7e, 0); txb_addbyte(s, &hdlctx, 0x7e, 0); txb_addbyte(s, &hdlctx, 0x7e, 0); } int gen_hdlc(signed short *buf, int buflen, struct gen_params *p, struct gen_state *s) { int num = 0; if (!s || s->s.hdlc.ch_idx < 0 || s->s.hdlc.ch_idx >= s->s.hdlc.datalen) return 0; for (; buflen > 0; buflen--, buf++, num++) { s->s.hdlc.bitph += 0x10000*1200 / SAMPLE_RATE; if (s->s.hdlc.bitph >= 0x10000u) { s->s.hdlc.bitph &= 0xffffu; s->s.hdlc.bitmask <<= 1; if (s->s.hdlc.bitmask >= 0x100) { s->s.hdlc.bitmask = 1; s->s.hdlc.ch_idx++; if (s->s.hdlc.ch_idx >= s->s.hdlc.datalen) return num; } if (!(s->s.hdlc.data[s->s.hdlc.ch_idx] & s->s.hdlc.bitmask)) s->s.hdlc.lastb = !s->s.hdlc.lastb; s->s.hdlc.phinc = (s->s.hdlc.lastb) ? 0x10000*2200/SAMPLE_RATE : 0x10000*1200/SAMPLE_RATE; } *buf += (p->ampl * COS(s->s.hdlc.ph)) >> 15; s->s.hdlc.ph += s->s.hdlc.phinc; } return num; } multimon-1.0/costabi.c0000644000310500031050000002051710271506360014743 0ustar bottomsbottoms/* * This file is machine generated, DO NOT EDIT! */ int costabi[1024] = { 32767, 32766, 32764, 32761, 32757, 32751, 32744, 32736, 32727, 32717, 32705, 32692, 32678, 32662, 32646, 32628, 32609, 32588, 32567, 32544, 32520, 32495, 32468, 32441, 32412, 32382, 32350, 32318, 32284, 32249, 32213, 32176, 32137, 32097, 32056, 32014, 31970, 31926, 31880, 31833, 31785, 31735, 31684, 31633, 31580, 31525, 31470, 31413, 31356, 31297, 31236, 31175, 31113, 31049, 30984, 30918, 30851, 30783, 30713, 30643, 30571, 30498, 30424, 30349, 30272, 30195, 30116, 30036, 29955, 29873, 29790, 29706, 29621, 29534, 29446, 29358, 29268, 29177, 29085, 28992, 28897, 28802, 28706, 28608, 28510, 28410, 28309, 28208, 28105, 28001, 27896, 27790, 27683, 27575, 27466, 27355, 27244, 27132, 27019, 26905, 26789, 26673, 26556, 26437, 26318, 26198, 26077, 25954, 25831, 25707, 25582, 25456, 25329, 25201, 25072, 24942, 24811, 24679, 24546, 24413, 24278, 24143, 24006, 23869, 23731, 23592, 23452, 23311, 23169, 23027, 22883, 22739, 22594, 22448, 22301, 22153, 22004, 21855, 21705, 21554, 21402, 21249, 21096, 20942, 20787, 20631, 20474, 20317, 20159, 20000, 19840, 19680, 19519, 19357, 19194, 19031, 18867, 18702, 18537, 18371, 18204, 18036, 17868, 17699, 17530, 17360, 17189, 17017, 16845, 16672, 16499, 16325, 16150, 15975, 15799, 15623, 15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191, 14009, 13827, 13645, 13462, 13278, 13094, 12909, 12724, 12539, 12353, 12166, 11980, 11792, 11604, 11416, 11227, 11038, 10849, 10659, 10469, 10278, 10087, 9895, 9703, 9511, 9319, 9126, 8932, 8739, 8545, 8351, 8156, 7961, 7766, 7571, 7375, 7179, 6982, 6786, 6589, 6392, 6195, 5997, 5799, 5601, 5403, 5205, 5006, 4807, 4608, 4409, 4210, 4011, 3811, 3611, 3411, 3211, 3011, 2811, 2610, 2410, 2209, 2009, 1808, 1607, 1406, 1206, 1005, 804, 603, 402, 201, 0, -201, -402, -603, -804, -1005, -1206, -1406, -1607, -1808, -2009, -2209, -2410, -2610, -2811, -3011, -3211, -3411, -3611, -3811, -4011, -4210, -4409, -4608, -4807, -5006, -5205, -5403, -5601, -5799, -5997, -6195, -6392, -6589, -6786, -6982, -7179, -7375, -7571, -7766, -7961, -8156, -8351, -8545, -8739, -8932, -9126, -9319, -9511, -9703, -9895, -10087, -10278, -10469, -10659, -10849, -11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353, -12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827, -14009, -14191, -14372, -14552, -14732, -14911, -15090, -15268, -15446, -15623, -15799, -15975, -16150, -16325, -16499, -16672, -16845, -17017, -17189, -17360, -17530, -17699, -17868, -18036, -18204, -18371, -18537, -18702, -18867, -19031, -19194, -19357, -19519, -19680, -19840, -20000, -20159, -20317, -20474, -20631, -20787, -20942, -21096, -21249, -21402, -21554, -21705, -21855, -22004, -22153, -22301, -22448, -22594, -22739, -22883, -23027, -23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143, -24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201, -25329, -25456, -25582, -25707, -25831, -25954, -26077, -26198, -26318, -26437, -26556, -26673, -26789, -26905, -27019, -27132, -27244, -27355, -27466, -27575, -27683, -27790, -27896, -28001, -28105, -28208, -28309, -28410, -28510, -28608, -28706, -28802, -28897, -28992, -29085, -29177, -29268, -29358, -29446, -29534, -29621, -29706, -29790, -29873, -29955, -30036, -30116, -30195, -30272, -30349, -30424, -30498, -30571, -30643, -30713, -30783, -30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297, -31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735, -31785, -31833, -31880, -31926, -31970, -32014, -32056, -32097, -32137, -32176, -32213, -32249, -32284, -32318, -32350, -32382, -32412, -32441, -32468, -32495, -32520, -32544, -32567, -32588, -32609, -32628, -32646, -32662, -32678, -32692, -32705, -32717, -32727, -32736, -32744, -32751, -32757, -32761, -32764, -32766, -32767, -32766, -32764, -32761, -32757, -32751, -32744, -32736, -32727, -32717, -32705, -32692, -32678, -32662, -32646, -32628, -32609, -32588, -32567, -32544, -32520, -32495, -32468, -32441, -32412, -32382, -32350, -32318, -32284, -32249, -32213, -32176, -32137, -32097, -32056, -32014, -31970, -31926, -31880, -31833, -31785, -31735, -31684, -31633, -31580, -31525, -31470, -31413, -31356, -31297, -31236, -31175, -31113, -31049, -30984, -30918, -30851, -30783, -30713, -30643, -30571, -30498, -30424, -30349, -30272, -30195, -30116, -30036, -29955, -29873, -29790, -29706, -29621, -29534, -29446, -29358, -29268, -29177, -29085, -28992, -28897, -28802, -28706, -28608, -28510, -28410, -28309, -28208, -28105, -28001, -27896, -27790, -27683, -27575, -27466, -27355, -27244, -27132, -27019, -26905, -26789, -26673, -26556, -26437, -26318, -26198, -26077, -25954, -25831, -25707, -25582, -25456, -25329, -25201, -25072, -24942, -24811, -24679, -24546, -24413, -24278, -24143, -24006, -23869, -23731, -23592, -23452, -23311, -23169, -23027, -22883, -22739, -22594, -22448, -22301, -22153, -22004, -21855, -21705, -21554, -21402, -21249, -21096, -20942, -20787, -20631, -20474, -20317, -20159, -20000, -19840, -19680, -19519, -19357, -19194, -19031, -18867, -18702, -18537, -18371, -18204, -18036, -17868, -17699, -17530, -17360, -17189, -17017, -16845, -16672, -16499, -16325, -16150, -15975, -15799, -15623, -15446, -15268, -15090, -14911, -14732, -14552, -14372, -14191, -14009, -13827, -13645, -13462, -13278, -13094, -12909, -12724, -12539, -12353, -12166, -11980, -11792, -11604, -11416, -11227, -11038, -10849, -10659, -10469, -10278, -10087, -9895, -9703, -9511, -9319, -9126, -8932, -8739, -8545, -8351, -8156, -7961, -7766, -7571, -7375, -7179, -6982, -6786, -6589, -6392, -6195, -5997, -5799, -5601, -5403, -5205, -5006, -4807, -4608, -4409, -4210, -4011, -3811, -3611, -3411, -3211, -3011, -2811, -2610, -2410, -2209, -2009, -1808, -1607, -1406, -1206, -1005, -804, -603, -402, -201, 0, 201, 402, 603, 804, 1005, 1206, 1406, 1607, 1808, 2009, 2209, 2410, 2610, 2811, 3011, 3211, 3411, 3611, 3811, 4011, 4210, 4409, 4608, 4807, 5006, 5205, 5403, 5601, 5799, 5997, 6195, 6392, 6589, 6786, 6982, 7179, 7375, 7571, 7766, 7961, 8156, 8351, 8545, 8739, 8932, 9126, 9319, 9511, 9703, 9895, 10087, 10278, 10469, 10659, 10849, 11038, 11227, 11416, 11604, 11792, 11980, 12166, 12353, 12539, 12724, 12909, 13094, 13278, 13462, 13645, 13827, 14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268, 15446, 15623, 15799, 15975, 16150, 16325, 16499, 16672, 16845, 17017, 17189, 17360, 17530, 17699, 17868, 18036, 18204, 18371, 18537, 18702, 18867, 19031, 19194, 19357, 19519, 19680, 19840, 20000, 20159, 20317, 20474, 20631, 20787, 20942, 21096, 21249, 21402, 21554, 21705, 21855, 22004, 22153, 22301, 22448, 22594, 22739, 22883, 23027, 23169, 23311, 23452, 23592, 23731, 23869, 24006, 24143, 24278, 24413, 24546, 24679, 24811, 24942, 25072, 25201, 25329, 25456, 25582, 25707, 25831, 25954, 26077, 26198, 26318, 26437, 26556, 26673, 26789, 26905, 27019, 27132, 27244, 27355, 27466, 27575, 27683, 27790, 27896, 28001, 28105, 28208, 28309, 28410, 28510, 28608, 28706, 28802, 28897, 28992, 29085, 29177, 29268, 29358, 29446, 29534, 29621, 29706, 29790, 29873, 29955, 30036, 30116, 30195, 30272, 30349, 30424, 30498, 30571, 30643, 30713, 30783, 30851, 30918, 30984, 31049, 31113, 31175, 31236, 31297, 31356, 31413, 31470, 31525, 31580, 31633, 31684, 31735, 31785, 31833, 31880, 31926, 31970, 32014, 32056, 32097, 32137, 32176, 32213, 32249, 32284, 32318, 32350, 32382, 32412, 32441, 32468, 32495, 32520, 32544, 32567, 32588, 32609, 32628, 32646, 32662, 32678, 32692, 32705, 32717, 32727, 32736, 32744, 32751, 32757, 32761, 32764, 32766 }; multimon-1.0/mkcostab.c0000644000310500031050000000370510271505162015121 0ustar bottomsbottoms/* * mkcostab.c -- cosine table generator * * Copyright (C) 1996 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------------------------------------------------- */ #include #include #include /* ---------------------------------------------------------------------- */ #define COSTABSIZE 0x400 /* ---------------------------------------------------------------------- */ int main(int argc, char *argv[]) { int i; FILE *fi, *ff; float f; if (!(fi = fopen("costabi.c", "w"))) exit(1); if (!(ff = fopen("costabf.c", "w"))) exit(1); fprintf(fi, "/*\n * This file is machine generated, DO NOT EDIT!\n */\n\n" "int costabi[%i] = {", COSTABSIZE); fprintf(ff, "/*\n * This file is machine generated, DO NOT EDIT!\n */\n\n" "float costabf[%i] = {", COSTABSIZE); for (i = 0; i < COSTABSIZE; i++) { if ((i & 3) == 0) fprintf(ff, "\n\t"); if ((i & 7) == 0) fprintf(fi, "\n\t"); f = cos(M_PI*2.0*i/COSTABSIZE); fprintf(ff, "%12.9f", f); fprintf(fi, "%6i", (int)(32767.0*f)); if (i < COSTABSIZE-1) { fprintf(ff, ", "); fprintf(fi, ", "); } } fprintf(ff, "\n};\n"); fprintf(fi, "\n};\n"); exit(0); }