FS-10510: [Build-System] Add mod_codec2, move libcodec2 from tree to download on windows.

This commit is contained in:
Andrey Volk 2017-07-18 18:32:10 +03:00
parent c237bd60f9
commit c1d964a0a5
326 changed files with 11467 additions and 60359 deletions

1
.gitignore vendored
View File

@ -252,3 +252,4 @@ libs/lua-*/
libs/g722_1-*/
libs/ilbc-*/
libs/broadvoice-*/
libs/libcodec2-*/

View File

@ -659,6 +659,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download iLBC", "libs\win32
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download broadvoice", "libs\win32\Download broadvoice.2015.vcxproj", "{46502007-0D94-47AC-A640-C2B5EEA98333}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcodec2", "libs\win32\libcodec2\libcodec2.2015.vcxproj", "{19E934D6-1484-41C8-9305-78DC42FD61F2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_codec2", "src\mod\codecs\mod_codec2\mod_codec2.vcxproj", "{CB4E68A1-8D19-4B5E-87B9-97A895E1BA17}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download libcodec2", "libs\win32\Download libcodec2.2015.vcxproj", "{9CFA562C-C611-48A7-90A2-BB031B47FE6D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
All|Win32 = All|Win32
@ -2977,6 +2983,42 @@ Global
{46502007-0D94-47AC-A640-C2B5EEA98333}.Release|Win32.Build.0 = Release|Win32
{46502007-0D94-47AC-A640-C2B5EEA98333}.Release|x64.ActiveCfg = Release|Win32
{46502007-0D94-47AC-A640-C2B5EEA98333}.Release|x64.Build.0 = Release|Win32
{19E934D6-1484-41C8-9305-78DC42FD61F2}.All|Win32.ActiveCfg = Release|Win32
{19E934D6-1484-41C8-9305-78DC42FD61F2}.All|Win32.Build.0 = Release|Win32
{19E934D6-1484-41C8-9305-78DC42FD61F2}.All|x64.ActiveCfg = Release|x64
{19E934D6-1484-41C8-9305-78DC42FD61F2}.All|x64.Build.0 = Release|x64
{19E934D6-1484-41C8-9305-78DC42FD61F2}.Debug|Win32.ActiveCfg = Debug|Win32
{19E934D6-1484-41C8-9305-78DC42FD61F2}.Debug|Win32.Build.0 = Debug|Win32
{19E934D6-1484-41C8-9305-78DC42FD61F2}.Debug|x64.ActiveCfg = Debug|x64
{19E934D6-1484-41C8-9305-78DC42FD61F2}.Debug|x64.Build.0 = Debug|x64
{19E934D6-1484-41C8-9305-78DC42FD61F2}.Release|Win32.ActiveCfg = Release|Win32
{19E934D6-1484-41C8-9305-78DC42FD61F2}.Release|Win32.Build.0 = Release|Win32
{19E934D6-1484-41C8-9305-78DC42FD61F2}.Release|x64.ActiveCfg = Release|x64
{19E934D6-1484-41C8-9305-78DC42FD61F2}.Release|x64.Build.0 = Release|x64
{CB4E68A1-8D19-4B5E-87B9-97A895E1BA17}.All|Win32.ActiveCfg = Release|Win32
{CB4E68A1-8D19-4B5E-87B9-97A895E1BA17}.All|Win32.Build.0 = Release|Win32
{CB4E68A1-8D19-4B5E-87B9-97A895E1BA17}.All|x64.ActiveCfg = Release|x64
{CB4E68A1-8D19-4B5E-87B9-97A895E1BA17}.All|x64.Build.0 = Release|x64
{CB4E68A1-8D19-4B5E-87B9-97A895E1BA17}.Debug|Win32.ActiveCfg = Debug|Win32
{CB4E68A1-8D19-4B5E-87B9-97A895E1BA17}.Debug|Win32.Build.0 = Debug|Win32
{CB4E68A1-8D19-4B5E-87B9-97A895E1BA17}.Debug|x64.ActiveCfg = Debug|x64
{CB4E68A1-8D19-4B5E-87B9-97A895E1BA17}.Debug|x64.Build.0 = Debug|x64
{CB4E68A1-8D19-4B5E-87B9-97A895E1BA17}.Release|Win32.ActiveCfg = Release|Win32
{CB4E68A1-8D19-4B5E-87B9-97A895E1BA17}.Release|Win32.Build.0 = Release|Win32
{CB4E68A1-8D19-4B5E-87B9-97A895E1BA17}.Release|x64.ActiveCfg = Release|x64
{CB4E68A1-8D19-4B5E-87B9-97A895E1BA17}.Release|x64.Build.0 = Release|x64
{9CFA562C-C611-48A7-90A2-BB031B47FE6D}.All|Win32.ActiveCfg = Release|Win32
{9CFA562C-C611-48A7-90A2-BB031B47FE6D}.All|Win32.Build.0 = Release|Win32
{9CFA562C-C611-48A7-90A2-BB031B47FE6D}.All|x64.ActiveCfg = Release|Win32
{9CFA562C-C611-48A7-90A2-BB031B47FE6D}.All|x64.Build.0 = Release|Win32
{9CFA562C-C611-48A7-90A2-BB031B47FE6D}.Debug|Win32.ActiveCfg = Debug|Win32
{9CFA562C-C611-48A7-90A2-BB031B47FE6D}.Debug|Win32.Build.0 = Debug|Win32
{9CFA562C-C611-48A7-90A2-BB031B47FE6D}.Debug|x64.ActiveCfg = Debug|Win32
{9CFA562C-C611-48A7-90A2-BB031B47FE6D}.Debug|x64.Build.0 = Debug|Win32
{9CFA562C-C611-48A7-90A2-BB031B47FE6D}.Release|Win32.ActiveCfg = Release|Win32
{9CFA562C-C611-48A7-90A2-BB031B47FE6D}.Release|Win32.Build.0 = Release|Win32
{9CFA562C-C611-48A7-90A2-BB031B47FE6D}.Release|x64.ActiveCfg = Release|Win32
{9CFA562C-C611-48A7-90A2-BB031B47FE6D}.Release|x64.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -3213,5 +3255,8 @@ Global
{36603FE1-253F-4C2C-AAB6-12927A626135} = {C120A020-773F-4EA3-923F-B67AF28B750D}
{53AADA60-DF12-46FF-BF94-566BBF849336} = {C120A020-773F-4EA3-923F-B67AF28B750D}
{46502007-0D94-47AC-A640-C2B5EEA98333} = {C120A020-773F-4EA3-923F-B67AF28B750D}
{19E934D6-1484-41C8-9305-78DC42FD61F2} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{CB4E68A1-8D19-4B5E-87B9-97A895E1BA17} = {F881ADA2-2F1A-4046-9FEB-191D9422D781}
{9CFA562C-C611-48A7-90A2-BB031B47FE6D} = {C120A020-773F-4EA3-923F-B67AF28B750D}
EndGlobalSection
EndGlobal

View File

@ -1 +0,0 @@
src/codebookvq.c

View File

View File

View File

@ -1,502 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
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 Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
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 and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
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 other code 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.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
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, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser 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 combine 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) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) 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.
d) 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.
e) 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 materials to be 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 with
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 Lesser 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.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see
<http://www.gnu.org/licenses/>.
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.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

View File

@ -1,94 +0,0 @@
AM_CFLAGS = -Isrc -fPIC -Wall -O3 -lm
AUTOMAKE_OPTIONS = gnu
NAME = codec2
AM_CPPFLAGS = $(AM_CFLAGS)
EXTRA_DIST = octave/glottal.m \
octave/lsp_pdf.m \
octave/phase.m \
octave/pl2.m \
octave/plinterp.m \
octave/plnlp.m \
octave/plpitch.m \
octave/postfilter.m \
octave/load_raw.m \
octave/phase2.m \
octave/pitch_test.m \
octave/plamp.m \
octave/pl.m \
octave/plphase.m \
octave/png.m \
octave/pulse.m \
raw/b0067.raw \
raw/forig_speex_8k.raw \
raw/hts1.raw \
raw/hts2.raw \
raw/mmt1.raw \
raw/morig_speex_8k.raw \
raw/f2400.raw \
raw/hts1a_g729a.raw \
raw/hts2a_g729a.raw \
raw/hts.raw \
raw/mmt1_speex_8k.raw \
raw/forig_g729a.raw \
raw/hts1a_gsm13k.raw \
raw/hts2a_gsm13k.raw \
raw/m2400.raw \
raw/morig_g729a.raw \
raw/forig_gsm13k.raw \
raw/hts1a.raw \
raw/hts2a.raw \
raw/mmt1_g729a.raw \
raw/morig_gsm13k.raw \
raw/forig.raw \
raw/hts1a_speex_8k.raw \
raw/hts2a_speex_8k.raw \
raw/mmt1_gsm13k.raw \
raw/morig.raw \
script/menu.sh \
script/playraw.sh \
script/raw2wav.sh \
script/wav2raw.sh \
wav/f2400.wav \
wav/hts1a_c2_v0.1.wav \
wav/hts1a.wav \
wav/hts2a_speex_8k.wav \
wav/mmt1_speex_8k.wav \
wav/morig.wav \
wav/forig_speex_8k.wav \
wav/hts1a_g729a.wav \
wav/hts2a_c2_v0.1.wav \
wav/hts2a.wav \
wav/mmt1.wav \
wav/forig.wav \
wav/hts1a_speex_8k.wav \
wav/hts2a_g729a.wav \
wav/m2400.wav \
wav/morig_speex_8k.wav \
src/globals.c \
unittest/lsp2.txt \
unittest/lsp7.txt \
unittest/lspd78.txt \
unittest/lsp3.txt \
unittest/lsp8.txt \
unittest/lspd910.txt \
unittest/lsp4.txt \
unittest/lsp9.txt \
unittest/lsp10.txt \
unittest/lsp5.txt \
unittest/lspd123.txt \
unittest/lsp1.txt \
unittest/lsp6.txt \
unittest/lspd456.txt \
src/codebook/lsp1.txt \
src/codebook/lsp2.txt \
src/codebook/lsp3.txt \
src/codebook/lsp4.txt \
src/codebook/lsp5.txt \
src/codebook/lsp6.txt \
src/codebook/lsp7.txt \
src/codebook/lsp8.txt \
src/codebook/lsp9.txt \
src/codebook/lsp10.txt
SUBDIRS = src unittest

View File

View File

@ -1,84 +0,0 @@
Codec 2 README
--------------
Codec 2 is an open source (LGPL licensed) speech codec for 2400 bit/s
and below. For more information please see:
http://rowetel.com/codec2.html
Also included is a FDMDV modem, see README_fdmdv.txt
Quickstart
----------
1/ Listen to Codec 2:
$ ./configure && make
$ cd src
$ ./c2demo ../raw/hts1a.raw hts1a_c2.raw
$ ../script/menu.sh ../raw/hts1a.raw hts1a_c2.raw
NOTE: For playback testing, menu.sh requires either the 'play',
'aplay' or 'ossplay' programs to be installed (see
http://sox.sourceforge.net/, http://www.alsa-project.org/, or
http://www.opensound.com/ respectively).
2/ Compress and Decompress a file:
$ ./c2enc 2400 ../raw/hts1a.raw hts1a_c2.bit
$ ./c2dec 2400 hts1a_c2.bit hts1a_c2.raw
3/ Same thing with pipes:
$ ./c2enc 1400 ../raw/hts1a.raw - | ./c2dec 1400 - - | play -t raw -r 8000 -s -2 -
Programs
--------
1/ c2demo encodes a file of speech samples, then decodes them and
saves the result.
2/ c2enc encodes a file of speech samples to a compressed file of
encoded bits.
3/ c2dec decodes a compressed file of bits to a file of speech
samples.
4/ c2sim is a simulation/development version of Codec 2. It allows
selective use of the various Codec 2 algorithms. For example
switching phase modelling or LSP quantisation on and off.
Debugging
---------
1/ For dump file support:
$ cd codec2
$ CFLAGS=-DDUMP ./configure
$ make clean && make
2/ To use gdb:
$ libtool --mode=execute gdb c2sim
Directories
-----------
fltk - FLTK GUI programs(s)
octave - Octave scripts used for visualising internal signals
during development
portaudio - Portaudio test programs
script - shell scripts for playing and converting raw files
src - C source code
raw - speech files in raw format (16 bits signed linear 8 kHz)
unittest - unit test source code
voicing - hand-estimated voicing files, used for development
wav - speech files in wave file format
win32 - Support for building Windows DLL version of Codec 2 and FDMDV libraries
TODO
----
[ ] Get win32/Makefile integrated into Automake system, such that if
i586-mingw32msvc exists the Win32 code gets automatically built.
[ ] Same for fltk & portaudio, build these conditionally if libs exist

View File

@ -1,199 +0,0 @@
README_fdmdv.txt
David Rowe
Created March 2012
Introduction
------------
A 1400 bit/s Frequency Division Multiplexed Digital Voice (FDMDV) modem
based on [1]. Used for digital audio over HF SSB.
The FDMDV modem was first implemented in GNU Octave, then ported to C.
Algorithm development is generally easier in Octave, but for real time
work we need the C version. Automated units tests ensure the
operation of the Octave and C versions are identical.
Quickstart
----------
$ cd codec2-dev
$ ./configure && make
$ cd src
1. Generate some test bits and modulate them:
$ ./fdmdv_get_test_bits test.c2 1400
$ ./fdmdv_mod test.c2 test.raw
$ play -r 8000 -s -2 test.raw
2. Two seconds of test frame data modulated and sent out of sound device:
$ ./fdmdv_get_test_bits - 2800 | ./fdmdv_mod - - | play -t raw -r 8000 -s -2 -
3. Send 14000 modulated bits (10 seconds) to the demod and count errors:
$ ./fdmdv_get_test_bits - 14000 | ./fdmdv_mod - - | ./fdmdv_demod - - demod_dump.txt | ./fdmdv_put_test_bits -
Use Octave to look at plots of 1 second (1400 bits) of modem operation:
$ cd ../octave
$ octave
octave:1> fdmdv_demod_c("../src/demod_dump.txt",1400)
4. Run Octave simulation of entire modem and AWGN channel:
$ cd ../octave
$ octave
octave:1> fdmdv_ut
5. NOTE: If you would like to play modem samples over the air please
convert the 8 kHz samples to 48 kHz. Many PC sound cards have
wildly inaccurate sample clock rates when set to 8 kHz, but seem to
perform OK when set for 48 kHz. If playing and recording files you
can use the sox utility:
$ sox -r 8000 -s -2 modem_sample_8kHz.raw -r 48000 modem_sample_48kHz.wav
For real time applications, the fdmdv.[ch] library includes functions to
convert between 48 and 8 kHz sample rates.
References
----------
[1] http://n1su.com/fdmdv/FDMDV_Docs_Rel_1_4b.pdf
[2] http://n1su.com/fdmdv/
[3] http://www.rowetel.com/blog/?p=2433 "Testing a FDMDV Modem"
[4] http://www.rowetel.com/blog/?p=2458 "FDMDV Modem Page" on David's web site
C Code
------
src/fdmdv_mod.c - C version of modulator that takes a file of bits and
converts it to a raw file of modulated samples.
src/fdmdv_demod.c - C version of demodulator that takes a raw file of
modulated samples and outputs a file of bits.
Optionally dumps demod states to a text file which
can be plotted using the Octave script
fdmdv_demod_c.m
src/fdmdv.h - Header file that exposes FDMDV C API functions. Include
this file in your application program.
src/fdmdv.c - C functions that implement the FDMDV modem.
src/fdmdv-internal.h - internal states and constants for FDMDV modem,
shouldn't be exposed to application program.
unittest/tfdmdv.c - Used to conjunction with unittest/tfdmdv.m to
automatically test C FDMDV functions against
Octave versions.
Octave Scripts
--------------
(Note these require some Octave packages to be installed, see
octave/README.txt).
fdmdv.m - Functions and variables that implement the Octave version of
the FDMDV modem.
fdmdv_ut.m - Unit test for fdmdv Octave code, useful while
developing algorithm. Includes tx/rx plus basic channel
simulation.
Typical run:
octave:6> fdmdv_ut
Eb/No (meas): 7.30 (8.29) dB
bits........: 2464
errors......: 20
BER.........: 0.0081
PAPR........: 13.54 dB
SNR.........: 4.0 dB
It also outputs lots of nice plots that show the
operation of the modem.
For a 1400 bit/s DQPSK modem we expect about 1% BER for
Eb/No = 7.3dB, which corresponds to SNR = 4dB (3kHz
noise BW). The extra dB of measured power is due to the
DBPSK pilot. Currently the noise generation code
doesn't take the pilot power into account, so in this
example the real SNR is actually 5dB.
fdmdv_mod.m - Octave version of modulator that outputs a raw file.
The modulator is driven by a test frame of bits. This
can then be played over a real channel or through a
channel simulator like PathSim. The sample rate can be
changed using "sox" to simulate differences in tx/rx
sample clocks.
To generate 10 seconds of modulated signal:
octave:8> fdmdv_mod("test.raw",1400*10);
fdmdv_demod.m - Demodulator program that takes a raw file as input,
and works out the bit error rate using the known test
frame. Can be used to test the demod performs with
off-air signals, or signals that have been passed
through a channel simulator.
To demodulate 2 seconds of the test.raw file generated
above:
octave:9> fdmdv_demod("test.raw",1400*2);
2464 bits 0 errors BER: 0.0000
It also produces several plots showing the internal
states of the demod. Useful for debugging and
observing what happens with various channels.
fdmdv_demod_c.m - Takes an output text file from the C demod
fdmdv_demod.c and produces plots and measures BER.
Useful for evaluating fdmdv_demod.c performance.
The plots produced are identical to the Octave
version fdmdv_demod.m, allowing direct comparison of
the C and Octave versions.
tfdmdv.m - Automatic tests that compare the Octave and C versions of
the FDMDV modem functions. First run unittest/tfdmdv, this
will generate a text file with test vectors from the C
version. Then run the Octave script tfdmdv and it will
generate Octave versions of the test vectors and compare
each vector with the C equivalent. Its plots the vectors
and and errors (green). Its also produces an automatic
check list based on test results. If the Octave or C modem
code is changed, this script should be used to ensure the
C and Octave versions remain identical.
Modelling sample clock errors using sox
---------------------------------------
This introduces a simulated 1000ppm error:
sox -r 8000 -s -2 mod_dqpsk.raw -s -2 mod_dqpsk_8008hz.raw rate -h 8008
TODO
----
[ ] implement ppm measurements in fdmdv_get_demod_stats()
[ ] try interfering sine wave
+ maybe swept
+ does modem fall over?
[ ] try non-flat channel, e.g. 3dB difference between hi and low tones
+ make sure all estimators keep working
[ ] test rx level sensitivity, i.e. 0 to 20dB attenuation
[ ] make fine freq indep of amplitude
+ use angle rather than imag coord
[ ] document use of fdmdv_ut and fdmdv_demod + PathSim
[ ] more positive form of sync reqd for DV frames?
+ like using coarse_fine==1 to decode valid DV frame bit?
+ when should we start decoding?
[ ] more robust track/acquite state machine?
+ e.g. hang on thru the fades?
[ ] PAPR idea
+ automatically tweak phases to reduce PAPR, e.g. slow variations in freq...
[ ] why is pilot noise_est twice as big as other carriers

View File

@ -1,109 +0,0 @@
README for codec2/asterisk
Asterisk Codec 2 support
Test Configuration
------------------
Codec 2 is used to trunk calls between two Asterisk boxes:
A - SIP phone - Asterisk A - Codec2 - Asterisk B - SIP Phone - B
The two SIP phones are configured for mulaw.
Building
---------
Asterisk must be patched so that the core understand Codec 2 frames.
1/ First install Codec 2:
david@cool:~$ svn co https://freetel.svn.sourceforge.net/svnroot/freetel/codec2-dev codec2-dev
david@cool:~/codec2-dev$ cd codec2-dev
david@cool:~/codec2-dev$ ./configure && make && sudo make install
david@bear:~/codec2-dev$ sudo ldconfig -v
david@cool:~/codec2-dev$ cd ~
2/ Then build Asterisk with Codec 2 support:
david@cool:~$ tar xvzf asterisk-1.8.9.0.tar.gz
david@cool:~/asterisk-1.8.9.0$ patch -p4 < ~/codec2-dev/asterisk/asterisk-codec2.patch
david@cool:~/asterisk-1.8.9.0$ cp ~/codec2-dev/asterisk/codec_codec2.c .
david@cool:~/asterisk-1.8.9.0$ cp ~/codec2-dev/asterisk/ex_codec2.h ./codecs
david@cool:~/asterisk-1.8.9.0$ ./configure && make ASTLDFLAGS=-lcodec2
david@cool:~/asterisk-1.8.9.0$ sudo make install
david@cool:~/asterisk-1.8.9.0$ sudo make samples
3/ Add this to the end of sip.conf on Asterisk A:
[6013]
type=friend
context=default
host=dynamic
user=6013
secret=6013
canreinvite=no
callerid=6013
disallow=all
allow=ulaw
[potato]
type=peer
username=potato
fromuser=potato
secret=password
context=default
disallow=all
dtmfmode=rfc2833
callerid=server
canreinvite=no
host=cool
allow=codec2
3/ Add this to the end of sip.conf on Asterisk B:
[6014]
type=friend
context=default
host=dynamic
user=6014
secret=6014
canreinvite=no
callerid=6014
disallow=all
allow=ulaw
[potato]
type=peer
username=potato
fromuser=potato
secret=password
context=default
disallow=all
dtmfmode=rfc2833
callerid=server
canreinvite=no
host=bear
allow=codec2
4/ Here is the [default] section of extensions.conf on Asterisk B:
[default]
exten => 6013,1,Dial(SIP/potato/6013)
;
; By default we include the demo. In a production system, you
; probably don't want to have the demo there.
;
;include => demo
5/ After booting see if the codec2_codec2.so module is loaded with "core show translate"
6/ To make a test call dial 6013 on the SIP phone connected to Asterisk B
7/ If codec_codec2.so won't load and you see "can't find codec2_create" try:
david@cool:~/asterisk-1.8.9.0$ touch codecs/codec_codec2.c
david@cool:~/asterisk-1.8.9.0$ make ASTLDFLAGS=-lcodec2
david@cool:~/asterisk-1.8.9.0$ sudo cp codecs/codec_codec2.so /usr/lib/asterisk/modules
david@cool:~/asterisk-1.8.9.0$ sudo asterisk -vvvcn

View File

@ -1,68 +0,0 @@
--- /home/david/asterisk-1.8.9.0-orig/include/asterisk/frame.h 2011-12-23 05:08:46.000000000 +1030
+++ /home/david/asterisk-1.8.9.0-codec2/include/asterisk/frame.h 2012-03-27 13:16:55.623452431 +1030
@@ -299,6 +299,7 @@
#define AST_FORMAT_G719 (1ULL << 32)
/*! SpeeX Wideband (16kHz) Free Compression */
#define AST_FORMAT_SPEEX16 (1ULL << 33)
+#define AST_FORMAT_CODEC2 (1ULL << 34)
/*! Raw mu-law data (G.711) */
#define AST_FORMAT_TESTLAW (1ULL << 47)
/*! Reserved bit - do not use */
--- /home/david/asterisk-1.8.9.0-orig/main/frame.c 2010-06-18 02:53:43.000000000 +0930
+++ /home/david/asterisk-1.8.9.0-codec2/main/frame.c 2012-03-28 15:16:16.975581316 +1030
@@ -102,6 +102,7 @@
{ AST_FORMAT_ADPCM, "adpcm" , 8000, "ADPCM", 40, 10, 300, 10, 20 }, /*!< codec_adpcm.c */
{ AST_FORMAT_SLINEAR, "slin", 8000, "16 bit Signed Linear PCM", 160, 10, 70, 10, 20, AST_SMOOTHER_FLAG_BE }, /*!< Signed linear */
{ AST_FORMAT_LPC10, "lpc10", 8000, "LPC10", 7, 20, 20, 20, 20 }, /*!< codec_lpc10.c */
+ { AST_FORMAT_CODEC2, "codec2", 8000, "Codec 2", 7, 20, 20, 20, 20 }, /*!< codec_codec2.c */
{ AST_FORMAT_G729A, "g729", 8000, "G.729A", 10, 10, 230, 10, 20, AST_SMOOTHER_FLAG_G729 }, /*!< Binary commercial distribution */
{ AST_FORMAT_SPEEX, "speex", 8000, "SpeeX", 10, 10, 60, 10, 20 }, /*!< codec_speex.c */
{ AST_FORMAT_SPEEX16, "speex16", 16000, "SpeeX 16khz", 10, 10, 60, 10, 20 }, /*!< codec_speex.c */
@@ -1475,6 +1476,9 @@
samples = 22 * 8;
samples += (((char *)(f->data.ptr))[7] & 0x1) * 8;
break;
+ case AST_FORMAT_CODEC2:
+ samples = 160 * (f->datalen / 7);
+ break;
case AST_FORMAT_ULAW:
case AST_FORMAT_ALAW:
case AST_FORMAT_TESTLAW:
@@ -1519,6 +1523,9 @@
case AST_FORMAT_GSM:
len = (samples / 160) * 33;
break;
+ case AST_FORMAT_CODEC2:
+ len = (samples / 160) * 7;
+ break;
case AST_FORMAT_G729A:
len = samples / 8;
break;
--- /home/david/asterisk-1.8.9.0-orig/main/channel.c 2011-12-17 10:21:13.000000000 +1030
+++ /home/david/asterisk-1.8.9.0-codec2/main/channel.c 2012-03-28 15:05:22.395293391 +1030
@@ -1075,6 +1075,7 @@
/*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
to use it */
AST_FORMAT_LPC10,
+ AST_FORMAT_CODEC2,
/*! G.729a is faster than 723 and slightly less expensive */
AST_FORMAT_G729A,
/*! Down to G.723.1 which is proprietary but at least designed for voice */
--- /home/david/asterisk-1.8.9.0-orig/main/rtp_engine.c 2011-12-30 01:43:03.000000000 +1030
+++ /home/david/asterisk-1.8.9.0-codec2/main/rtp_engine.c 2012-03-28 16:42:02.880872891 +1030
@@ -101,6 +101,7 @@
{{1, AST_FORMAT_SLINEAR}, "audio", "L16", 8000},
{{1, AST_FORMAT_SLINEAR16}, "audio", "L16", 16000},
{{1, AST_FORMAT_LPC10}, "audio", "LPC", 8000},
+ {{1, AST_FORMAT_CODEC2}, "audio", "CODEC2", 8000},
{{1, AST_FORMAT_G729A}, "audio", "G729", 8000},
{{1, AST_FORMAT_G729A}, "audio", "G729A", 8000},
{{1, AST_FORMAT_G729A}, "audio", "G.729", 8000},
@@ -178,6 +179,7 @@
[117] = {1, AST_FORMAT_SPEEX16},
[118] = {1, AST_FORMAT_SLINEAR16}, /* 16 Khz signed linear */
[121] = {0, AST_RTP_CISCO_DTMF}, /* Must be type 121 */
+ [121] = {1, AST_FORMAT_CODEC2},
};
int ast_rtp_engine_register2(struct ast_rtp_engine *engine, struct ast_module *module)

View File

@ -1,185 +0,0 @@
/*
* Codec 2 module for Asterisk.
*
* Credit: codec_gsm.c used as a starting point.
*
* Copyright (C) 2012 Ed W and David Rowe
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree.
*/
/*! \file
*
* \brief Translate between signed linear and Codec 2
*
* \ingroup codecs
*/
/*** MODULEINFO
<support_level>core</support_level>
***/
#include "asterisk.h"
#include "asterisk/translate.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/utils.h"
#include <codec2.h>
#define BUFFER_SAMPLES 8000
#define CODEC2_SAMPLES 160
#define CODEC2_FRAME_LEN 7
/* Sample frame data */
#include "asterisk/slin.h"
#include "ex_codec2.h"
struct codec2_translator_pvt { /* both codec2tolin and codec2togsm */
struct CODEC2 *codec2;
short buf[BUFFER_SAMPLES]; /* lintocodec2, temporary storage */
};
static int codec2_new(struct ast_trans_pvt *pvt)
{
struct codec2_translator_pvt *tmp = pvt->pvt;
tmp->codec2 = codec2_create(CODEC2_MODE_2400);
return 0;
}
/*! \brief decode and store in outbuf. */
static int codec2tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
{
struct codec2_translator_pvt *tmp = pvt->pvt;
int x;
int16_t *dst = pvt->outbuf.i16;
int flen = CODEC2_FRAME_LEN;
for (x=0; x < f->datalen; x += flen) {
unsigned char *src;
int len;
len = CODEC2_SAMPLES;
src = f->data.ptr + x;
codec2_decode(tmp->codec2, dst + pvt->samples, src);
pvt->samples += CODEC2_SAMPLES;
pvt->datalen += 2 * CODEC2_SAMPLES;
}
return 0;
}
/*! \brief store samples into working buffer for later decode */
static int lintocodec2_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
{
struct codec2_translator_pvt *tmp = pvt->pvt;
if (pvt->samples + f->samples > BUFFER_SAMPLES) {
ast_log(LOG_WARNING, "Out of buffer space\n");
return -1;
}
memcpy(tmp->buf + pvt->samples, f->data.ptr, f->datalen);
pvt->samples += f->samples;
return 0;
}
/*! \brief encode and produce a frame */
static struct ast_frame *lintocodec2_frameout(struct ast_trans_pvt *pvt)
{
struct codec2_translator_pvt *tmp = pvt->pvt;
int datalen = 0;
int samples = 0;
/* We can't work on anything less than a frame in size */
if (pvt->samples < CODEC2_SAMPLES)
return NULL;
while (pvt->samples >= CODEC2_SAMPLES) {
/* Encode a frame of data */
codec2_encode(tmp->codec2, (unsigned char*)(pvt->outbuf.c + datalen), tmp->buf + samples);
datalen += CODEC2_FRAME_LEN;
samples += CODEC2_SAMPLES;
pvt->samples -= CODEC2_SAMPLES;
}
/* Move the data at the end of the buffer to the front */
if (pvt->samples)
memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
return ast_trans_frameout(pvt, datalen, samples);
}
static void codec2_destroy_stuff(struct ast_trans_pvt *pvt)
{
struct codec2_translator_pvt *tmp = pvt->pvt;
if (tmp->codec2)
codec2_destroy(tmp->codec2);
}
static struct ast_translator codec2tolin = {
.name = "codec2tolin",
.srcfmt = AST_FORMAT_CODEC2,
.dstfmt = AST_FORMAT_SLINEAR,
.newpvt = codec2_new,
.framein = codec2tolin_framein,
.destroy = codec2_destroy_stuff,
.sample = codec2_sample,
.buffer_samples = BUFFER_SAMPLES,
.buf_size = BUFFER_SAMPLES * 2,
.desc_size = sizeof (struct codec2_translator_pvt ),
};
static struct ast_translator lintocodec2 = {
.name = "lintocodec2",
.srcfmt = AST_FORMAT_SLINEAR,
.dstfmt = AST_FORMAT_CODEC2,
.newpvt = codec2_new,
.framein = lintocodec2_framein,
.frameout = lintocodec2_frameout,
.destroy = codec2_destroy_stuff,
.sample = slin8_sample,
.desc_size = sizeof (struct codec2_translator_pvt ),
.buf_size = (BUFFER_SAMPLES * CODEC2_FRAME_LEN + CODEC2_SAMPLES - 1)/CODEC2_SAMPLES,
};
/*! \brief standard module glue */
static int reload(void)
{
return AST_MODULE_LOAD_SUCCESS;
}
static int unload_module(void)
{
int res;
res = ast_unregister_translator(&lintocodec2);
if (!res)
res = ast_unregister_translator(&codec2tolin);
return res;
}
static int load_module(void)
{
int res;
res = ast_register_translator(&codec2tolin);
if (!res)
res=ast_register_translator(&lintocodec2);
else
ast_unregister_translator(&codec2tolin);
if (res)
return AST_MODULE_LOAD_FAILURE;
return AST_MODULE_LOAD_SUCCESS;
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Codec 2 Coder/Decoder",
.load = load_module,
.unload = unload_module,
.reload = reload,
);

View File

@ -1,28 +0,0 @@
/*! \file
* \brief 8-bit raw data
*
* Copyright (C) 2012, 2012 Ed W and David Rowe
*
* Distributed under the terms of the GNU General Public License
*
*/
static uint8_t ex_codec2[] = {
0x3e,0x06,0x4a,0xbb,0x9e,0x40,0xc0
};
static struct ast_frame *codec2_sample(void)
{
static struct ast_frame f = {
.frametype = AST_FRAME_VOICE,
.subclass.codec = AST_FORMAT_CODEC2,
.datalen = sizeof(ex_codec2),
.samples = CODEC2_SAMPLES,
.mallocd = 0,
.offset = 0,
.src = __PRETTY_FUNCTION__,
.data.ptr = ex_codec2,
};
return &f;
}

View File

@ -1,11 +0,0 @@
#!/bin/sh
# Create patch for Codec 2 support inside Asterisk
ORIG=~/asterisk-1.8.9.0-orig
CODEC2=~/asterisk-1.8.9.0-codec2
diff -ruN $ORIG/include/asterisk/frame.h $CODEC2/include/asterisk/frame.h > asterisk-codec2.patch
diff -ruN $ORIG/main/frame.c $CODEC2/main/frame.c >> asterisk-codec2.patch
diff -ruN $ORIG/main/channel.c $CODEC2/main/channel.c >> asterisk-codec2.patch
diff -ruN $ORIG/main/rtp_engine.c $CODEC2/main/rtp_engine.c >> asterisk-codec2.patch

View File

@ -1,26 +0,0 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.59])
AC_INIT(codec2, 0.2, david@rowetel.com)
AM_INIT_AUTOMAKE
# Checks for programs.
AC_PROG_CC
AC_PROG_LIBTOOL
# Checks for libraries.
# FIXME: Replace `main' with a function in `-lm':
AC_CHECK_LIB([m], [main])
# Checks for header files.
AC_CHECK_HEADERS([stdlib.h string.h])
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_FUNC_MALLOC
AC_CHECK_FUNCS([floor pow sqrt])
AC_CONFIG_FILES([Makefile src/Makefile unittest/Makefile])
AC_OUTPUT

View File

@ -1,4 +0,0 @@
#! /bin/sh
srcpath=$(dirname $0 2>/dev/null ) || srcpath="."
$srcpath/configure "$@" --disable-shared --with-pic

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 552 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -1 +0,0 @@
s(n)=A_1cos(\omega_0+\phi_1)+A_2cos(2\omega_0+\phi_2)+...+A_Lcos(L\omega_0+\phi_L)

View File

@ -1,19 +0,0 @@
# Requires FLTK 1.3 & Portaudio V19
FLTK_VER = $(shell fltk-config --api-version)
ifneq ($(FLTK_VER),1.3)
$(error Must use FLTK version 1.3, you have $(FLTK_VER))
endif
FLTK_CFLAGS += $(shell fltk-config --ldstaticflags)
CFLAGS = -O3 -g -Wall
LIBS = ../src/.libs/libcodec2.a -lm -lrt -lportaudio -pthread
LC2POC_C = fl_fdmdv.cxx
all: fl_fdmdv
fl_fdmdv: Makefile $(LC2POC_C)
g++ $(LC2POC_C) -I../src/ -o fl_fdmdv $(CFLAGS) $(FLTK_CFLAGS) $(LIBS)
clean:
rm -f fl_fdmdv

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +0,0 @@
README.txt
For codec2/octave directory
Created 24 June 2012 by David Rowe
1/ To support some of the Octave scripts (in particular fdmdv) in this
directory the following Octave packages need to be installed:
control image miscellaneous optim signal specfun struct
2/ Download these tar balls from:
http://octave.sourceforge.net/packages.php
3/ Install each package from the Octave command line with:
octave:3> pkg install package_file_name.tar.gz

View File

@ -1,43 +0,0 @@
% av_imp.m
% David Rowe Aug 2012
% Averages the impulse response samples
function imp = av_imp(imp_filename, period_in_secs, st, en)
f = fopen(imp_filename,"rb");
s = fread(f, Inf, "short")';
Fs = 8000;
n = period_in_secs * Fs;
[r c] = size(s);
imp = zeros(1,n);
for i=1:n:c-n
imp = imp + s(i:i+n-1);
endfor
% user supplies start and end samples after viweing plot
if (nargin == 4)
imp = imp(st:en);
end
% normalise
imp /= sqrt(sum(imp .^ 2));
[h w] = freqz(imp, 1, 4000);
figure(1);
clf;
plot(imp);
figure(2);
clf;
subplot(211)
plot(10*log10(abs(h)))
subplot(212)
plot(angle(h))
endfunction

View File

@ -1,98 +0,0 @@
% cbphase.m
% David Rowe Aug 2012
% Used to experiment with critical band phase perception and smoothing
function cbphase
Wo = 100.0*pi/4000;
L = floor(pi/Wo);
A = zeros(1,L);
phi = zeros(1,L);
% three harmonics in this band
b = 4; a = b-1; c = b+1;
% set up phases and mags for 2nd order system (see phasesecord.m)
wres = b*Wo;
phi(a) = 3*pi/4 + wres;
phi(b) = pi/2 + wres;
phi(c) = pi/4 + wres;
A(a) = 0.707;
A(b) = 1;
A(c) = 0.707;
% add linear component
phi(1) = pi;
phi(2:L) = phi(2:L) + (2:L)*phi(1);
phi = phi - 2*pi*(floor(phi/(2*pi)) + 0.5);
N = 16000;
Nplot = 250;
s = zeros(1,N);
for m=a:c
s_m = A(m)*cos(m*Wo*(0:(N-1)) + phi(m));
s = s + s_m;
endfor
figure(2);
clf;
subplot(211)
plot((1:L)*Wo*4000/pi, A,'+');
subplot(212)
plot((1:L)*Wo*4000/pi, phi,'+');
%v = A(a)*exp(j*phi(a)) + A(b)*exp(j*phi(b)) + A(c)*exp(j*phi(c));
%compass(v,"r")
%hold off;
% est phi1
diff = phi(b) - phi(a)
sumi = sin(diff);
sumr = cos(diff);
diff = phi(c) - phi(b)
sumi += sin(diff);
sumr += cos(diff);
phi1_ = atan2(sumi, sumr)
s_v = cos(Wo*(0:(N-1)) + phi1_);
figure(1);
clf;
subplot(211)
plot(s(1:Nplot));
hold on;
plot(s_v(1:Nplot),"r");
hold off;
% build (hopefully) perceptually similar phase
phi_(a) = a*phi1_;
phi_(b) = b*phi1_;
phi_(c) = c*phi1_;
s_ = zeros(1,N);
for m=a:c
s_m = A(m)*cos(m*Wo*(0:(N-1)) + phi_(m));
s_ = s_ + s_m;
endfor
subplot(212)
plot(s_(1:Nplot));
gain = 8000;
fs=fopen("orig_ph.raw","wb");
fwrite(fs,gain*s,"short");
fclose(fs);
fs=fopen("mod_ph.raw","wb");
fwrite(fs,gain*s_,"short");
fclose(fs);
endfunction

View File

@ -1,108 +0,0 @@
% Copyright David Rowe 2012
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
% codec2_demo.m
% Designed as an educational tool to explain the operation of Codec 2
% for conference and user group presentations on a projector. An
% alternative to static overhead slides.
%
% Derived from codec2-dev/octave/plamp.m
%
% usage:
% octave:1> plamp("../src/hts2a",40)
%
% Then press:
% c - to cycle through the wavform being displayed on the figure
% n - next frame
% b - back one frame
%
% tip: hold down n or b to animate the display
%
% The text files used as input are generated using c2sim:
%
% /codec2-dev/src$ c2sim ../raw/hts2a.raw --dump hts2a
%
% The Codec 2 README explains how to build c2sim with dump files
% enabled.
function codec2_demo(samname, f)
sn_name = strcat(samname,"_sn.txt");
Sn = load(sn_name);
sw_name = strcat(samname,"_sw.txt");
Sw = load(sw_name);
model_name = strcat(samname,"_model.txt");
model = load(model_name);
figure(1);
k = ' ';
wf = "Sn";
do
if strcmp(wf,"Sn")
clf;
s = [ Sn(2*f-1,:) Sn(2*f,:) ];
plot(s);
axis([1 length(s) -20000 20000]);
end
if (strcmp(wf,"Sw"))
clf;
plot((0:255)*4000/256, Sw(f,:),";Sw;");
end
if strcmp(wf,"SwAm")
Wo = model(f,1);
L = model(f,2);
Am = model(f,3:(L+2));
plot((0:255)*4000/256, Sw(f,:),";Sw;");
hold on;
plot((1:L)*Wo*4000/pi, 20*log10(Am),"+;Am;r");
axis([1 4000 -10 80]);
hold off;
end
if strcmp(wf,"Am")
Wo = model(f,1);
L = model(f,2);
Am = model(f,3:(L+2));
plot((1:L)*Wo*4000/pi, 20*log10(Am),"+;Am;r");
axis([1 4000 -10 80]);
end
% interactive menu
printf("\rframe: %d menu: n-next b-back w-cycle window q-quit", f);
fflush(stdout);
k = kbhit();
if (k == 'n')
f = f + 1;
end
if (k == 'b')
f = f - 1;
end
if (k == 'w')
if strcmp(wf,"Sn")
next_wf = "Sw";
end
if strcmp(wf,"Sw")
next_wf = "SwAm";
end
if strcmp(wf,"SwAm")
next_wf = "Am";
end
if strcmp(wf,"Am")
next_wf = "Sn";
end
wf = next_wf;
end
until (k == 'q')
printf("\n");
endfunction

View File

@ -1,54 +0,0 @@
% cspec.m
% David Rowe Aug 2012
% Used to compare spectromgrams while experimenting with phase
function cspec(s1,s2)
f1 = fopen(s1,"rb");
s1 = fread(f1,Inf,"short");
f2 = fopen(s2,"rb");
s2 = fread(f2,Inf,"short");
Fs = 8000;
spec_win = 512;
state = 's1';
do
if strcmp(state,'s1')
spec(s1,Fs,spec_win);
%title(s1);
end
if strcmp(state,'s2')
spec(s2,Fs,spec_win);
%title(s2);
end
if strcmp(state,'diff')
spec(s1-s2,Fs,spec_win);
%title("difference");
end
printf("\rstate: %s space-toggle d-diff q-quit", state);
fflush(stdout);
k = kbhit();
if k == ' '
if strcmp(state,"diff")
next_state = 's1';
end
if strcmp(state,"s1")
next_state = 's2';
end
if strcmp(state,'s2')
next_state = 's1';
end
end
if k == 'd'
next_state = 'diff';
end
state = next_state;
until (k == 'q')
printf("\n");
endfunction

View File

@ -1,935 +0,0 @@
% fdmdv.m
%
% Functions that implement a Frequency Divison Multiplexed Modem for
% Digital Voice (FDMDV) over HF channels.
%
% Copyright David Rowe 2012
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
% reqd to mak sure we get same random bits at mod and demod
rand('state',1);
randn('state',1);
% Constants
global Fs = 8000; % sample rate in Hz
global T = 1/Fs; % sample period in seconds
global Rs = 50; % symbol rate in Hz
global Nc = 14; % number of carriers
global Nb = 2; % Bits/symbol for QPSK modulation
global Rb = Nc*Rs*Nb; % bit rate
global M = Fs/Rs; % oversampling factor
global Nsym = 6; % number of symbols to filter over
global Fsep = 75; % Separation between carriers (Hz)
global Fcentre = 1200; % Centre frequency, Nc/2 carriers below this, N/c carriers above (Hz)
global Nt = 5; % number of symbols we estimate timing over
global P = 4; % oversample factor used for rx symbol filtering
global Nfilter = Nsym*M;
global Nfiltertiming = M+Nfilter+M;
alpha = 0.5;
global snr_coeff = 0.9 % SNR est averaging filter coeff
% root raised cosine (Root Nyquist) filter
global gt_alpha5_root;
gt_alpha5_root = gen_rn_coeffs(alpha, T, Rs, Nsym, M);
% Functions ----------------------------------------------------
% generate Nc+1 QPSK symbols from vector of (1,Nc*Nb) input bits. The
% Nc+1 symbol is the +1 -1 +1 .... BPSK sync carrier
function tx_symbols = bits_to_qpsk(prev_tx_symbols, tx_bits, modulation)
global Nc;
global Nb;
global pilot_bit;
% re-arrange as (Nc,Nb) matrix
tx_bits_matrix = zeros(Nc,Nb);
tx_bits_matrix(1:Nc,1) = tx_bits(1:Nb:Nb*Nc);
tx_bits_matrix(1:Nc,2) = tx_bits(2:Nb:Nb*Nc);
if (strcmp(modulation,'dqpsk'))
% map to (Nc,1) DQPSK symbols
for c=1:Nc
msb = tx_bits_matrix(c,1); lsb = tx_bits_matrix(c,2);
if ((msb == 0) && (lsb == 0))
tx_symbols(c) = prev_tx_symbols(c);
endif
if ((msb == 0) && (lsb == 1))
tx_symbols(c) = j*prev_tx_symbols(c);
endif
if ((msb == 1) && (lsb == 0))
tx_symbols(c) = -prev_tx_symbols(c);
endif
if ((msb == 1) && (lsb == 1))
tx_symbols(c) = -j*prev_tx_symbols(c);
endif
end
else
% QPSK mapping
tx_symbols = -1 + 2*tx_bits_matrix(:,1) - j + 2j*tx_bits_matrix(:,2);
endif
% +1 -1 +1 -1 BPSK sync carrier, once filtered becomes two spectral
% lines at +/- Rs/2
if pilot_bit
tx_symbols(Nc+1) = -prev_tx_symbols(Nc+1);
else
tx_symbols(Nc+1) = prev_tx_symbols(Nc+1);
end
if pilot_bit
pilot_bit = 0;
else
pilot_bit = 1;
end
endfunction
% Given Nc*Nb bits construct M samples (1 symbol) of Nc filtered
% symbols streams
function tx_baseband = tx_filter(tx_symbols)
global Nc;
global M;
global tx_filter_memory;
global Nfilter;
global gt_alpha5_root;
tx_baseband = zeros(Nc+1,M);
% tx filter each symbol, generate M filtered output samples for each symbol.
% Efficient polyphase filter techniques used as tx_filter_memory is sparse
tx_filter_memory(:,Nfilter) = sqrt(2)/2*tx_symbols;
for i=1:M
tx_baseband(:,i) = M*tx_filter_memory(:,M:M:Nfilter) * gt_alpha5_root(M-i+1:M:Nfilter)';
end
tx_filter_memory(:,1:Nfilter-M) = tx_filter_memory(:,M+1:Nfilter);
tx_filter_memory(:,Nfilter-M+1:Nfilter) = zeros(Nc+1,M);
endfunction
% Construct FDM signal by frequency shifting each filtered symbol
% stream. Returns complex signal so we can apply frequency offsets
% easily.
function tx_fdm = fdm_upconvert(tx_filt)
global Fs;
global M;
global Nc;
global Fsep;
global phase_tx;
global freq;
tx_fdm = zeros(1,M);
% Nc/2 tones below centre freq
for c=1:Nc/2
for i=1:M
phase_tx(c) = phase_tx(c) * freq(c);
tx_fdm(i) = tx_fdm(i) + tx_filt(c,i)*phase_tx(c);
end
end
% Nc/2 tones above centre freq
for c=Nc/2+1:Nc
for i=1:M
phase_tx(c) = phase_tx(c) * freq(c);
tx_fdm(i) = tx_fdm(i) + tx_filt(c,i)*phase_tx(c);
end
end
% add centre pilot tone
c = Nc+1;
for i=1:M
phase_tx(c) = phase_tx(c) * freq(c);
pilot(i) = 2*tx_filt(c,i)*phase_tx(c);
tx_fdm(i) = tx_fdm(i) + pilot(i);
end
% Scale such that total Carrier power C of real(tx_fdm) = Nc. This
% excludes the power of the pilot tone.
% We return the complex (single sided) signal to make frequency
% shifting for the purpose of testing easier
tx_fdm = 2*tx_fdm;
endfunction
% Frequency shift each modem carrier down to Nc+1 baseband signals
function rx_baseband = fdm_downconvert(rx_fdm, nin)
global Fs;
global M;
global Nc;
global Fsep;
global phase_rx;
global freq;
rx_baseband = zeros(1,nin);
% Nc/2 tones below centre freq
for c=1:Nc/2
for i=1:nin
phase_rx(c) = phase_rx(c) * freq(c);
rx_baseband(c,i) = rx_fdm(i)*phase_rx(c)';
end
end
% Nc/2 tones above centre freq
for c=Nc/2+1:Nc
for i=1:nin
phase_rx(c) = phase_rx(c) * freq(c);
rx_baseband(c,i) = rx_fdm(i)*phase_rx(c)';
end
end
% Pilot
c = Nc+1;
for i=1:nin
phase_rx(c) = phase_rx(c) * freq(c);
rx_baseband(c,i) = rx_fdm(i)*phase_rx(c)';
end
endfunction
% Receive filter each baseband signal at oversample rate P
function rx_filt = rx_filter(rx_baseband, nin)
global Nc;
global M;
global P;
global rx_filter_memory;
global Nfilter;
global gt_alpha5_root;
global Fsep;
rx_filt = zeros(Nc+1,nin*P/M);
% rx filter each symbol, generate P filtered output samples for each symbol.
% Note we keep memory at rate M, it's just the filter output at rate P
N=M/P;
j=1;
for i=1:N:nin
rx_filter_memory(:,Nfilter-N+1:Nfilter) = rx_baseband(:,i:i-1+N);
rx_filt(:,j) = rx_filter_memory * gt_alpha5_root';
rx_filter_memory(:,1:Nfilter-N) = rx_filter_memory(:,1+N:Nfilter);
j+=1;
end
endfunction
% LPF and peak pick part of freq est, put in a function as we call it twice
function [foff imax pilot_lpf S] = lpf_peak_pick(pilot_baseband, pilot_lpf, nin)
global M;
global Npilotlpf;
global Npilotcoeff;
global Fs;
global Mpilotfft;
global pilot_coeff;
% LPF cutoff 200Hz, so we can handle max +/- 200 Hz freq offset
pilot_lpf(1:Npilotlpf-nin) = pilot_lpf(nin+1:Npilotlpf);
j = 1;
for i = Npilotlpf-nin+1:Npilotlpf
pilot_lpf(i) = pilot_baseband(j:j+Npilotcoeff-1) * pilot_coeff';
j++;
end
% decimate to improve DFT resolution, window and DFT
Mpilot = Fs/(2*200); % calc decimation rate given new sample rate is twice LPF freq
h = hanning(Npilotlpf);
s = pilot_lpf(1:Mpilot:Npilotlpf) .* h(1:Mpilot:Npilotlpf)';
s = [s zeros(1,Mpilotfft-Npilotlpf/Mpilot)];
S = fft(s, Mpilotfft);
% peak pick and convert to Hz
[imax ix] = max(S);
r = 2*200/Mpilotfft; % maps FFT bin to frequency in Hz
if ix > Mpilotfft/2
foff = (ix - Mpilotfft - 1)*r;
else
foff = (ix - 1)*r;
endif
endfunction
% Estimate frequency offset of FDM signal using BPSK pilot. This is quite
% sensitive to pilot tone level wrt other carriers
function [foff S1 S2] = rx_est_freq_offset(rx_fdm, pilot, pilot_prev, nin)
global M;
global Npilotbaseband;
global pilot_baseband1;
global pilot_baseband2;
global pilot_lpf1;
global pilot_lpf2;
% down convert latest nin samples of pilot by multiplying by
% ideal BPSK pilot signal we have generated locally. This
% peak of the resulting signal is sensitive to the time shift between
% the received and local version of the pilot, so we do it twice at
% different time shifts and choose the maximum.
pilot_baseband1(1:Npilotbaseband-nin) = pilot_baseband1(nin+1:Npilotbaseband);
pilot_baseband2(1:Npilotbaseband-nin) = pilot_baseband2(nin+1:Npilotbaseband);
for i=1:nin
pilot_baseband1(Npilotbaseband-nin+i) = rx_fdm(i) * conj(pilot(i));
pilot_baseband2(Npilotbaseband-nin+i) = rx_fdm(i) * conj(pilot_prev(i));
end
[foff1 max1 pilot_lpf1 S1] = lpf_peak_pick(pilot_baseband1, pilot_lpf1, nin);
[foff2 max2 pilot_lpf2 S2] = lpf_peak_pick(pilot_baseband2, pilot_lpf2, nin);
if max1 > max2
foff = foff1;
else
foff = foff2;
end
endfunction
% Estimate optimum timing offset, re-filter receive symbols
function [rx_symbols rx_timing env] = rx_est_timing(rx_filt, rx_baseband, nin)
global M;
global Nt;
global Nc;
global rx_filter_mem_timing;
global rx_baseband_mem_timing;
global P;
global Nfilter;
global Nfiltertiming;
global gt_alpha5_root;
% nin adjust
% --------------------------------
% 120 -1 (one less rate P sample)
% 160 0 (nominal)
% 200 1 (one more rate P sample)
adjust = P - nin*P/M;
% update buffer of Nt rate P filtered symbols
rx_filter_mem_timing(:,1:(Nt-1)*P+adjust) = rx_filter_mem_timing(:,P+1-adjust:Nt*P);
rx_filter_mem_timing(:,(Nt-1)*P+1+adjust:Nt*P) = rx_filt(:,:);
% sum envelopes of all carriers
env = sum(abs(rx_filter_mem_timing(:,:))); % use all Nc+1 carriers for timing
%env = abs(rx_filter_mem_timing(Nc+1,:)); % just use BPSK pilot
[n m] = size(env);
% The envelope has a frequency component at the symbol rate. The
% phase of this frequency component indicates the timing. So work out
% single DFT at frequency 2*pi/P
x = env * exp(-j*2*pi*(0:m-1)/P)';
% map phase to estimated optimum timing instant at rate M
% the M/4 part was adjusted by experiment, I know not why....
rx_timing = angle(x)*M/(2*pi) + M/4;
if (rx_timing > M)
rx_timing -= M;
end
if (rx_timing < -M)
rx_timing += M;
end
% rx_baseband_mem_timing contains M + Nfilter + M samples of the
% baseband signal at rate M this enables us to resample the filtered
% rx symbol with M sample precision once we have rx_timing
rx_baseband_mem_timing(:,1:Nfiltertiming-nin) = rx_baseband_mem_timing(:,nin+1:Nfiltertiming);
rx_baseband_mem_timing(:,Nfiltertiming-nin+1:Nfiltertiming) = rx_baseband;
% sample right in the middle of the timing estimator window, by filtering
% at rate M
s = round(rx_timing) + M;
rx_symbols = rx_baseband_mem_timing(:,s+1:s+Nfilter) * gt_alpha5_root';
endfunction
% Phase estimation function - probably won't work over a HF channel
% Tries to operate over a single symbol but uses phase information from
% all Nc carriers which should increase the SNR of phase estimate.
% Maybe phase is coherent over a couple of symbols in HF channel,not
% sure but it's worth 3dB so worth experimenting or using coherent as
% an option.
function rx_phase = rx_est_phase(prev_rx_symbols, rx_symbols)
% modulation strip
rx_phase = angle(sum(rx_symbols .^ 4))/4;
endfunction
% convert symbols back to an array of bits
function [rx_bits sync_bit f_err phase_difference] = qpsk_to_bits(prev_rx_symbols, rx_symbols, modulation)
global Nc;
global Nb;
global Nb;
if (strcmp(modulation,'dqpsk'))
% extra 45 degree clockwise lets us use real and imag axis as
% decision boundaries
phase_difference = zeros(Nc+1,1);
phase_difference(1:Nc) = rx_symbols(1:Nc) .* conj(prev_rx_symbols(1:Nc)) * exp(j*pi/4);
% map (Nc,1) DQPSK symbols back into an (1,Nc*Nb) array of bits
for c=1:Nc
d = phase_difference(c);
if ((real(d) >= 0) && (imag(d) >= 0))
msb = 0; lsb = 0;
endif
if ((real(d) < 0) && (imag(d) >= 0))
msb = 0; lsb = 1;
endif
if ((real(d) < 0) && (imag(d) < 0))
msb = 1; lsb = 0;
endif
if ((real(d) >= 0) && (imag(d) < 0))
msb = 1; lsb = 1;
endif
rx_bits(2*(c-1)+1) = msb;
rx_bits(2*(c-1)+2) = lsb;
end
% Extract DBPSK encoded Sync bit
phase_difference(Nc+1,1) = rx_symbols(Nc+1) .* conj(prev_rx_symbols(Nc+1));
if (real(phase_difference(Nc+1)) < 0)
sync_bit = 1;
f_err = imag(phase_difference(Nc+1));
else
sync_bit = 0;
f_err = -imag(phase_difference(Nc+1));
end
% pilot carrier gets an extra pi/4 rotation to make it consistent with
% other carriers, as we need it for snr_update and scatter diagram
phase_difference(Nc+1) *= exp(j*pi/4);
else
% map (Nc,1) QPSK symbols back into an (1,Nc*Nb) array of bits
rx_bits(1:Nb:Nc*Nb) = real(rx_symbols) > 0;
rx_bits(2:Nb:Nc*Nb) = imag(rx_symbols) > 0;
endif
endfunction
% given phase differences update estimates of signal and noise levels
function [sig_est noise_est] = snr_update(sig_est, noise_est, phase_difference)
global snr_coeff;
global Nc;
% mag of each symbol is distance from origin, this gives us a
% vector of mags, one for each carrier.
s = abs(phase_difference);
% signal mag estimate for each carrier is a smoothed version
% of instantaneous magntitude, this gives us a vector of smoothed
% mag estimates, one for each carrier.
sig_est = snr_coeff*sig_est + (1 - snr_coeff)*s;
% noise mag estimate is distance of current symbol from average
% location of that symbol. We reflect all symbols into the first
% quadrant for convenience.
refl_symbols = abs(real(phase_difference)) + j*abs(imag(phase_difference));
n = abs(exp(j*pi/4)*sig_est - refl_symbols);
% noise mag estimate for each carrier is a smoothed version of
% instantaneous noise mag, this gives us a vector of smoothed
% noise power estimates, one for each carrier.
noise_est = snr_coeff*noise_est + (1 - snr_coeff)*n;
endfunction
% calculate current SNR estimate (3000Hz noise BW)
function snr_dB = calc_snr(sig_est, noise_est)
global Rs;
% find total signal power by summing power in all carriers
S = sum(sig_est .^2);
SdB = 10*log10(S);
% Average noise mag across all carriers and square to get an average
% noise power. This is an estimate of the noise power in Rs = 50Hz of
% BW (note for raised root cosine filters Rs is the noise BW of the
% filter)
N50 = mean(noise_est).^2;
N50dB = 10*log10(N50);
% Now multiply by (3000 Hz)/(50 Hz) to find the total noise power in
% 3000 Hz
N3000dB = N50dB + 10*log10(3000/Rs);
snr_dB = SdB - N3000dB;
endfunction
% returns nbits from a repeating sequence of random data
function bits = get_test_bits(nbits)
global Ntest_bits; % length of test sequence
global current_test_bit;
global test_bits;
for i=1:nbits
bits(i) = test_bits(current_test_bit++);
if (current_test_bit > Ntest_bits)
current_test_bit = 1;
endif
end
endfunction
% Accepts nbits from rx and attempts to sync with test_bits sequence.
% if sync OK measures bit errors
function [sync bit_errors] = put_test_bits(rx_bits)
global Ntest_bits; % length of test sequence
global test_bits;
global rx_test_bits_mem;
% Append to our memory
[m n] = size(rx_bits);
rx_test_bits_mem(1:Ntest_bits-n) = rx_test_bits_mem(n+1:Ntest_bits);
rx_test_bits_mem(Ntest_bits-n+1:Ntest_bits) = rx_bits;
% see how many bit errors we get when checked against test sequence
bit_errors = sum(xor(test_bits,rx_test_bits_mem));
% if less than a thresh we are aligned and in sync with test sequence
ber = bit_errors/Ntest_bits;
sync = 0;
if (ber < 0.2)
sync = 1;
endif
endfunction
% Generate M samples of DBPSK pilot signal for Freq offset estimation
function [pilot_fdm bit symbol filter_mem phase] = generate_pilot_fdm(bit, symbol, filter_mem, phase, freq)
global M;
global Nfilter;
global gt_alpha5_root;
% +1 -1 +1 -1 DBPSK sync carrier, once filtered becomes two spectral
% lines at +/- Rs/2
if bit
symbol = -symbol;
else
symbol = symbol;
end
if bit
bit = 0;
else
bit = 1;
end
% filter DPSK symbol to create M baseband samples
filter_mem(Nfilter) = (sqrt(2)/2)*symbol;
for i=1:M
tx_baseband(i) = M*filter_mem(M:M:Nfilter) * gt_alpha5_root(M-i+1:M:Nfilter)';
end
filter_mem(1:Nfilter-M) = filter_mem(M+1:Nfilter);
filter_mem(Nfilter-M+1:Nfilter) = zeros(1,M);
% upconvert
for i=1:M
phase = phase * freq;
pilot_fdm(i) = sqrt(2)*2*tx_baseband(i)*phase;
end
endfunction
% Generate a 4M sample vector of DBPSK pilot signal. As the pilot signal
% is periodic in 4M samples we can then use this vector as a look up table
% for pilot signal generation in the demod.
function pilot_lut = generate_pilot_lut()
global Nc;
global Nfilter;
global M;
global freq;
% pilot states
pilot_rx_bit = 0;
pilot_symbol = sqrt(2);
pilot_freq = freq(Nc+1);
pilot_phase = 1;
pilot_filter_mem = zeros(1, Nfilter);
%prev_pilot = zeros(M,1);
pilot_lut = [];
F=8;
for f=1:F
[pilot pilot_rx_bit pilot_symbol pilot_filter_mem pilot_phase] = generate_pilot_fdm(pilot_rx_bit, pilot_symbol, pilot_filter_mem, pilot_phase, pilot_freq);
%prev_pilot = pilot;
pilot_lut = [pilot_lut pilot];
end
% discard first 4 symbols as filter memory is filling, just keep last
% four symbols
pilot_lut = pilot_lut(4*M+1:M*F);
endfunction
% grab next pilot samples for freq offset estimation at demod
function [pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, nin)
global M;
global pilot_lut;
for i=1:nin
pilot(i) = pilot_lut(pilot_lut_index);
pilot_lut_index++;
if pilot_lut_index > 4*M
pilot_lut_index = 1;
end
prev_pilot(i) = pilot_lut(prev_pilot_lut_index);
prev_pilot_lut_index++;
if prev_pilot_lut_index > 4*M
prev_pilot_lut_index = 1;
end
end
endfunction
% Change the sample rate by a small amount, for example 1000ppm (ratio
% = 1.001). Always returns nout samples in buf_out, but uses a
% variable number of input samples nin to accomodate the change in
% sample rate. nin is nominally set to nout, but may use nout +/- 2
% samples to accomodate the different sample rates. buf_in should be
% of length nout+6 samples to accomodate this, and buf_in should be
% updated externally based on the nin returned each time. "ratio" is
% Fs_in/Fs_out, for example 48048/48000 = 1.001 (+1000ppm) or
% 47952/48000 = 0.999 (-1000ppm). Uses linear interpolation to
% perform the resampling. This requires a highly over-sampled signal,
% for example 48000Hz sample rate for the modem signal centred on
% 1kHz, otherwise linear interpolation will have a low pass filter effect
% (for example an 8000Hz sample rate for modem signal centred on 1kHz
% would cause problems).
function [buf_out t nin] = resample(buf_in, t, ratio, nout)
for i=1:nout
c = floor(t);
a = t - c;
b = 1 - a;
buf_out(i) = buf_in(c)*b + buf_in(c+1)*a;
t += ratio;
end
t -= nout;
% adjust nin and t so that on next call we start with 3 < t < 4,
% this gives us +/- 2 samples room to move before we hit start or
% end of buf_in
delta = floor(t - 3);
nin = nout + delta;
t -= delta;
endfunction
% freq offset state machine. Moves between acquire and track states based
% on BPSK pilot sequence. Freq offset estimator occasionally makes mistakes
% when used continuously. So we use it until we have acquired the BPSK pilot,
% then switch to a more robust tracking algorithm. If we lose sync we switch
% back to acquire mode for fast-requisition.
function [track state] = freq_state(sync_bit, state)
% acquire state, look for 6 symbol 010101 sequence from sync bit
next_state = state;
if state == 0
if sync_bit == 0
next_state = 1;
end
end
if state == 1
if sync_bit == 1
next_state = 2;
else
next_state = 0;
end
end
if state == 2
if sync_bit == 0
next_state = 3;
else
next_state = 0;
end
end
if state == 3
if sync_bit == 1
next_state = 4;
else
next_state = 0;
end
end
if state == 4
if sync_bit == 0
next_state = 5;
else
next_state = 0;
end
end
if state == 5
if sync_bit == 1
next_state = 6;
else
next_state = 0;
end
end
% states 6 and above are track mode, make sure we keep getting 0101 sync bit sequence
if state == 6
if sync_bit == 0
next_state = 7;
else
next_state = 0;
end
end
if state == 7
if sync_bit == 1
next_state = 6;
else
next_state = 0;
end
end
state = next_state;
if state >= 6
track = 1;
else
track = 0;
end
endfunction
% Save test bits to a text file in the form of a C array
function test_bits_file(filename)
global test_bits;
global Ntest_bits;
f=fopen(filename,"wt");
fprintf(f,"/* Generated by test_bits_file() Octave function */\n\n");
fprintf(f,"const int test_bits[]={\n");
for m=1:Ntest_bits-1
fprintf(f," %d,\n",test_bits(m));
endfor
fprintf(f," %d\n};\n",test_bits(Ntest_bits));
fclose(f);
endfunction
% Saves RN filter coeffs to a text file in the form of a C array
function rn_file(filename)
global gt_alpha5_root;
global Nfilter;
f=fopen(filename,"wt");
fprintf(f,"/* Generated by rn_file() Octave function */\n\n");
fprintf(f,"const float gt_alpha5_root[]={\n");
for m=1:Nfilter-1
fprintf(f," %g,\n",gt_alpha5_root(m));
endfor
fprintf(f," %g\n};\n",gt_alpha5_root(Nfilter));
fclose(f);
endfunction
function pilot_coeff_file(filename)
global pilot_coeff;
global Npilotcoeff;
f=fopen(filename,"wt");
fprintf(f,"/* Generated by pilot_coeff_file() Octave function */\n\n");
fprintf(f,"const float pilot_coeff[]={\n");
for m=1:Npilotcoeff-1
fprintf(f," %g,\n",pilot_coeff(m));
endfor
fprintf(f," %g\n};\n",pilot_coeff(Npilotcoeff));
fclose(f);
endfunction
% Saves hanning window coeffs to a text file in the form of a C array
function hanning_file(filename)
global Npilotlpf;
h = hanning(Npilotlpf);
f=fopen(filename,"wt");
fprintf(f,"/* Generated by hanning_file() Octave function */\n\n");
fprintf(f,"const float hanning[]={\n");
for m=1:Npilotlpf-1
fprintf(f," %g,\n", h(m));
endfor
fprintf(f," %g\n};\n", h(Npilotlpf));
fclose(f);
endfunction
function png_file(fig, pngfilename)
figure(fig);
pngname = sprintf("%s.png",pngfilename);
print(pngname, '-dpng', "-S500,500")
pngname = sprintf("%s_large.png",pngfilename);
print(pngname, '-dpng', "-S800,600")
endfunction
% Initialise ----------------------------------------------------
global pilot_bit;
pilot_bit = 0; % current value of pilot bit
global tx_filter_memory;
tx_filter_memory = zeros(Nc+1, Nfilter);
global rx_filter_memory;
rx_filter_memory = zeros(Nc+1, Nfilter);
% phasors used for up and down converters
global freq;
freq = zeros(Nc+1,1);
for c=1:Nc/2
carrier_freq = (-Nc/2 - 1 + c)*Fsep + Fcentre;
freq(c) = exp(j*2*pi*carrier_freq/Fs);
end
for c=Nc/2+1:Nc
carrier_freq = (-Nc/2 + c)*Fsep + Fcentre;
freq(c) = exp(j*2*pi*carrier_freq/Fs);
end
freq(Nc+1) = exp(j*2*pi*Fcentre/Fs);
% Spread initial FDM carrier phase out as far as possible. This
% helped PAPR for a few dB. We don't need to adjust rx phase as DQPSK
% takes care of that.
global phase_tx;
%phase_tx = ones(Nc+1,1);
phase_tx = exp(j*2*pi*(0:Nc)/(Nc+1));
global phase_rx;
phase_rx = ones(Nc+1,1);
% Freq offset estimator constants
global Mpilotfft = 256;
global Npilotcoeff = 30; % number of pilot LPF coeffs
global pilot_coeff = fir1(Npilotcoeff-1, 200/(Fs/2))'; % 200Hz LPF
global Npilotbaseband = Npilotcoeff + M + M/P; % number of pilot baseband samples reqd for pilot LPF
global Npilotlpf = 4*M; % number of samples we DFT pilot over, pilot est window
% pilot LUT, used for copy of pilot at rx
global pilot_lut;
pilot_lut = generate_pilot_lut();
pilot_lut_index = 1;
prev_pilot_lut_index = 3*M+1;
% Freq offset estimator states
global pilot_baseband1;
global pilot_baseband2;
pilot_baseband1 = zeros(1, Npilotbaseband); % pilot baseband samples
pilot_baseband2 = zeros(1, Npilotbaseband); % pilot baseband samples
global pilot_lpf1
global pilot_lpf2
pilot_lpf1 = zeros(1, Npilotlpf); % LPF pilot samples
pilot_lpf2 = zeros(1, Npilotlpf); % LPF pilot samples
% Timing estimator states
global rx_filter_mem_timing;
rx_filter_mem_timing = zeros(Nc+1, Nt*P);
global rx_baseband_mem_timing;
rx_baseband_mem_timing = zeros(Nc+1, Nfiltertiming);
% Test bit stream constants
global Ntest_bits = Nc*Nb*4; % length of test sequence
global test_bits = rand(1,Ntest_bits) > 0.5;
% Test bit stream state variables
global current_test_bit = 1;
current_test_bit = 1;
global rx_test_bits_mem;
rx_test_bits_mem = zeros(1,Ntest_bits);

View File

@ -1,217 +0,0 @@
% fdmdv_demod.m
%
% Demodulator function for FDMDV modem (Octave version). Requires
% 8kHz sample rate raw files as input
%
% Copyright David Rowe 2012
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
function fdmdv_demod(rawfilename, nbits, pngname)
fdmdv; % include modem code
modulation = 'dqpsk';
fin = fopen(rawfilename, "rb");
gain = 1000;
frames = nbits/(Nc*Nb);
prev_rx_symbols = ones(Nc+1,1);
foff_phase = 1;
% BER stats
total_bit_errors = 0;
total_bits = 0;
bit_errors_log = [];
sync_log = [];
test_frame_sync_log = [];
test_frame_sync_state = 0;
% SNR states
sig_est = zeros(Nc+1,1);
noise_est = zeros(Nc+1,1);
% logs of various states for plotting
rx_symbols_log = [];
rx_timing_log = [];
foff_log = [];
rx_fdm_log = [];
snr_est_log = [];
% misc states
nin = M; % timing correction for sample rate differences
foff = 0;
track_log = [];
track = 0;
fest_state = 0;
% Main loop ----------------------------------------------------
for f=1:frames
% obtain nin samples of the test input signal
for i=1:nin
rx_fdm(i) = fread(fin, 1, "short")/gain;
end
rx_fdm_log = [rx_fdm_log rx_fdm(1:nin)];
% frequency offset estimation and correction
[pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, nin);
[foff_coarse S1 S2] = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, nin);
if track == 0
foff = foff_coarse;
end
foff_log = [ foff_log foff ];
foff_rect = exp(j*2*pi*foff/Fs);
for i=1:nin
foff_phase *= foff_rect';
rx_fdm(i) = rx_fdm(i)*foff_phase;
end
% baseband processing
rx_baseband = fdm_downconvert(rx_fdm, nin);
rx_filt = rx_filter(rx_baseband, nin);
[rx_symbols rx_timing] = rx_est_timing(rx_filt, rx_baseband, nin);
rx_timing_log = [rx_timing_log rx_timing];
nin = M;
if rx_timing > 2*M/P
nin += M/P;
end
if rx_timing < 0;
nin -= M/P;
end
if strcmp(modulation,'dqpsk')
rx_symbols_log = [rx_symbols_log rx_symbols.*conj(prev_rx_symbols)*exp(j*pi/4)];
else
rx_symbols_log = [rx_symbols_log rx_symbols];
endif
[rx_bits sync f_err pd] = qpsk_to_bits(prev_rx_symbols, rx_symbols, modulation);
[sig_est noise_est] = snr_update(sig_est, noise_est, pd);
snr_est = calc_snr(sig_est, noise_est);
snr_est_log = [snr_est_log snr_est];
foff -= 0.5*f_err;
prev_rx_symbols = rx_symbols;
sync_log = [sync_log sync];
% freq est state machine
[track fest_state] = freq_state(sync, fest_state);
track_log = [track_log track];
% count bit errors if we find a test frame
[test_frame_sync bit_errors] = put_test_bits(rx_bits);
if (test_frame_sync == 1)
total_bit_errors = total_bit_errors + bit_errors;
total_bits = total_bits + Ntest_bits;
bit_errors_log = [bit_errors_log bit_errors/Ntest_bits];
else
bit_errors_log = [bit_errors_log 0];
end
% test frame sync state machine, just for more informative plots
next_test_frame_sync_state = test_frame_sync_state;
if (test_frame_sync_state == 0)
if (test_frame_sync == 1)
next_test_frame_sync_state = 1;
test_frame_count = 0;
end
end
if (test_frame_sync_state == 1)
% we only expect another test_frame_sync pulse every 4 symbols
test_frame_count++;
if (test_frame_count == 4)
test_frame_count = 0;
if ((test_frame_sync == 0))
next_test_frame_sync_state = 0;
end
end
end
test_frame_sync_state = next_test_frame_sync_state;
test_frame_sync_log = [test_frame_sync_log test_frame_sync_state];
end
% ---------------------------------------------------------------------
% Print Stats
% ---------------------------------------------------------------------
ber = total_bit_errors / total_bits;
printf("%d bits %d errors BER: %1.4f\n",total_bits, total_bit_errors, ber);
% ---------------------------------------------------------------------
% Plots
% ---------------------------------------------------------------------
xt = (1:frames)/Rs;
secs = frames/Rs;
figure(1)
clf;
[n m] = size(rx_symbols_log);
plot(real(rx_symbols_log(1:Nc+1,15:m)),imag(rx_symbols_log(1:Nc+1,15:m)),'+')
axis([-2 2 -2 2]);
title('Scatter Diagram');
figure(2)
clf;
subplot(211)
plot(xt, rx_timing_log)
title('timing offset (samples)');
subplot(212)
plot(xt, foff_log, '-;freq offset;')
hold on;
plot(xt, track_log*75, 'r;course-fine;');
hold off;
title('Freq offset (Hz)');
grid
figure(3)
clf;
subplot(211)
[a b] = size(rx_fdm_log);
xt1 = (1:b)/Fs;
plot(xt1, rx_fdm_log);
title('Rx FDM Signal');
subplot(212)
spec(rx_fdm_log,8000);
title('FDM Rx Spectrogram');
figure(4)
clf;
subplot(311)
stem(xt, sync_log)
axis([0 secs 0 1.5]);
title('BPSK Sync')
subplot(312)
stem(xt, bit_errors_log);
title('Bit Errors for test frames')
subplot(313)
plot(xt, test_frame_sync_log);
axis([0 secs 0 1.5]);
title('Test Frame Sync')
figure(5)
clf;
plot(xt, snr_est_log);
title('SNR Estimates')
endfunction

View File

@ -1,128 +0,0 @@
% fdmdv_demod_c.m
%
% Plots Octave dump file information from C FDMDV demodulator program,
% to give a similar set of plots to fdmdv_demod.m. Useful for off
% line analysis of demod performance.
%
% Copyright David Rowe 2012
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
function fdmdv_demod_c(dumpfilename, bits)
fdmdv; % include modem code
frames = bits/(Nc*Nb);
load(dumpfilename);
% BER stats
total_bit_errors = 0;
total_bits = 0;
bit_errors_log = [];
sync_log = [];
test_frame_sync_log = [];
test_frame_sync_state = 0;
% Run thru received bits to look for test pattern
bits_per_frame = Nc*Nb;
for f=1:frames
rx_bits = rx_bits_log_c((f-1)*bits_per_frame+1:f*bits_per_frame);
% count bit errors if we find a test frame
[test_frame_sync bit_errors] = put_test_bits(rx_bits);
if (test_frame_sync == 1)
total_bit_errors = total_bit_errors + bit_errors;
total_bits = total_bits + Ntest_bits;
bit_errors_log = [bit_errors_log bit_errors/Ntest_bits];
else
bit_errors_log = [bit_errors_log 0];
end
% test frame sync state machine, just for more informative plots
next_test_frame_sync_state = test_frame_sync_state;
if (test_frame_sync_state == 0)
if (test_frame_sync == 1)
next_test_frame_sync_state = 1;
test_frame_count = 0;
end
end
if (test_frame_sync_state == 1)
% we only expect another test_frame_sync pulse every 4 symbols
test_frame_count++;
if (test_frame_count == 4)
test_frame_count = 0;
if ((test_frame_sync == 0))
next_test_frame_sync_state = 0;
end
end
end
test_frame_sync_state = next_test_frame_sync_state;
test_frame_sync_log = [test_frame_sync_log test_frame_sync_state];
end
% ---------------------------------------------------------------------
% Plots
% ---------------------------------------------------------------------
xt = (1:frames)/Rs;
secs = frames/Rs;
figure(1)
clf;
plot(real(rx_symbols_log_c(1:Nc+1,15:frames)),imag(rx_symbols_log_c(1:Nc+1,15:frames)),'+')
axis([-2 2 -2 2]);
title('Scatter Diagram');
figure(2)
clf;
subplot(211)
plot(xt, rx_timing_log_c(1:frames))
title('timing offset (samples)');
subplot(212)
plot(xt, foff_log_c(1:frames), '-;freq offset;')
hold on;
plot(xt, coarse_fine_log_c(1:frames)*75, 'r;course-fine;');
hold off;
title('Freq offset (Hz)');
grid
figure(3)
clf;
subplot(211)
b = M*frames;
xt1 = (1:b)/Fs;
plot(xt1, rx_fdm_log_c(1:b));
title('Rx FDM Signal');
subplot(212)
spec(rx_fdm_log_c(1:b),8000);
title('FDM Rx Spectrogram');
figure(4)
clf;
subplot(311)
stem(xt, sync_bit_log_c(1:frames))
axis([0 secs 0 1.5]);
title('BPSK Sync')
subplot(312)
stem(xt, bit_errors_log);
title('Bit Errors for test frames')
subplot(313)
plot(xt, test_frame_sync_log);
axis([0 secs 0 1.5]);
title('Test Frame Sync')
figure(5)
clf;
plot(xt, snr_est_log_c(1:frames));
title('SNR Estimates')
endfunction

View File

@ -1,32 +0,0 @@
% fdmdv_mod.m
%
% Modulator function for FDMDV modem, uses test frames as input and
% outputs a raw file of 16 bit shorts at a sample rate of 8 kHz.
%
% Copyright David Rowe 2012
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
function tx_fdm = fdmdv_mod(rawfilename, nbits)
fdmdv; % include modem code
frames = floor(nbits/(Nc*Nb))
tx_fdm = [];
gain = 1000; % Scale up to 16 bit shorts
prev_tx_symbols = ones(Nc+1,1);
for i=1:frames
tx_bits = get_test_bits(Nc*Nb);
tx_symbols = bits_to_qpsk(prev_tx_symbols, tx_bits,'dqpsk');
prev_tx_symbols = tx_symbols;
tx_baseband = tx_filter(tx_symbols);
tx_fdm = [tx_fdm real(fdm_upconvert(tx_baseband))];
end
tx_fdm *= gain;
fout = fopen(rawfilename,"wb");
fwrite(fout, tx_fdm, "short");
fclose(fout);
endfunction

View File

@ -1,318 +0,0 @@
% fdmdv_ut.m
%
% Unit Test program for FDMDV modem. Useful for general development as it has
% both tx and rx sides, and basic AWGN channel simulation.
%
% Copyright David Rowe 2012
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
fdmdv; % load modem code
% Simulation Parameters --------------------------------------
frames = 25;
EbNo_dB = 7.3;
Foff_hz = 0;
modulation = 'dqpsk';
hpa_clip = 150;
% ------------------------------------------------------------
tx_filt = zeros(Nc,M);
rx_symbols_log = [];
rx_phase_log = 0;
rx_timing_log = 0;
tx_pwr = 0;
noise_pwr = 0;
rx_fdm_log = [];
rx_baseband_log = [];
rx_bits_offset = zeros(Nc*Nb*2);
prev_tx_symbols = ones(Nc+1,1);
prev_rx_symbols = ones(Nc+1,1);
ferr = 0;
foff = 0;
foff_log = [];
tx_baseband_log = [];
tx_fdm_log = [];
% BER stats
total_bit_errors = 0;
total_bits = 0;
bit_errors_log = [];
sync_log = [];
test_frame_sync_log = [];
test_frame_sync_state = 0;
% SNR estimation states
sig_est = zeros(Nc+1,1);
noise_est = zeros(Nc+1,1);
% fixed delay simuation
Ndelay = M+20;
rx_fdm_delay = zeros(Ndelay,1);
% ---------------------------------------------------------------------
% Eb/No calculations. We need to work out Eb/No for each FDM carrier.
% Total power is sum of power in all FDM carriers
% ---------------------------------------------------------------------
C = 1; % power of each FDM carrier (energy/sample). Total Carrier power should = Nc*C = Nc
N = 1; % total noise power (energy/sample) of noise source across entire bandwidth
% Eb = Carrier power * symbol time / (bits/symbol)
% = C *(1/Rs) / 2
Eb_dB = 10*log10(C) - 10*log10(Rs) - 10*log10(2);
No_dBHz = Eb_dB - EbNo_dB;
% Noise power = Noise spectral density * bandwidth
% Noise power = Noise spectral density * Fs/2 for real signals
N_dB = No_dBHz + 10*log10(Fs/2);
Ngain_dB = N_dB - 10*log10(N);
Ngain = 10^(Ngain_dB/20);
% C/No = Carrier Power/noise spectral density
% = power per carrier*number of carriers / noise spectral density
CNo_dB = 10*log10(C) + 10*log10(Nc) - No_dBHz;
% SNR in equivalent 3000 Hz SSB channel
B = 3000;
SNR = CNo_dB - 10*log10(B);
% freq offset simulation states
phase_offset = 1;
freq_offset = exp(j*2*pi*Foff_hz/Fs);
foff_phase = 1;
t = 0;
foff = 0;
fest_state = 0;
track = 0;
track_log = [];
% ---------------------------------------------------------------------
% Main loop
% ---------------------------------------------------------------------
for f=1:frames
% -------------------
% Modulator
% -------------------
tx_bits = get_test_bits(Nc*Nb);
tx_symbols = bits_to_qpsk(prev_tx_symbols, tx_bits, modulation);
prev_tx_symbols = tx_symbols;
tx_baseband = tx_filter(tx_symbols);
tx_baseband_log = [tx_baseband_log tx_baseband];
tx_fdm = fdm_upconvert(tx_baseband);
tx_pwr = 0.9*tx_pwr + 0.1*real(tx_fdm)*real(tx_fdm)'/(M);
% -------------------
% Channel simulation
% -------------------
% frequency offset
%Foff_hz += 1/Rs;
Foff = Foff_hz;
for i=1:M
% Time varying freq offset
%Foff = Foff_hz + 100*sin(t*2*pi/(300*Fs));
%t++;
freq_offset = exp(j*2*pi*Foff/Fs);
phase_offset *= freq_offset;
tx_fdm(i) = phase_offset*tx_fdm(i);
end
tx_fdm = real(tx_fdm);
% HPA non-linearity
tx_fdm(find(abs(tx_fdm) > hpa_clip)) = hpa_clip;
tx_fdm_log = [tx_fdm_log tx_fdm];
rx_fdm = tx_fdm;
% AWGN noise
noise = Ngain*randn(1,M);
noise_pwr = 0.9*noise_pwr + 0.1*noise*noise'/M;
rx_fdm += noise;
rx_fdm_log = [rx_fdm_log rx_fdm];
% Delay
rx_fdm_delay(1:Ndelay-M) = rx_fdm_delay(M+1:Ndelay);
rx_fdm_delay(Ndelay-M+1:Ndelay) = rx_fdm;
%rx_fdm_delay = rx_fdm;
% -------------------
% Demodulator
% -------------------
% frequency offset estimation and correction, need to call rx_est_freq_offset even in track
% mode to keep states updated
[pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, M);
[foff_course S1 S2] = rx_est_freq_offset(rx_fdm_delay, pilot, prev_pilot, M);
if track == 0
foff = foff_course;
end
foff_log = [ foff_log foff ];
foff_rect = exp(j*2*pi*foff/Fs);
for i=1:M
foff_phase *= foff_rect';
rx_fdm_delay(i) = rx_fdm_delay(i)*foff_phase;
end
% baseband processing
rx_baseband = fdm_downconvert(rx_fdm_delay(1:M), M);
rx_baseband_log = [rx_baseband_log rx_baseband];
rx_filt = rx_filter(rx_baseband, M);
[rx_symbols rx_timing] = rx_est_timing(rx_filt, rx_baseband, M);
rx_timing_log = [rx_timing_log rx_timing];
%rx_phase = rx_est_phase(rx_symbols);
%rx_phase_log = [rx_phase_log rx_phase];
%rx_symbols = rx_symbols*exp(j*rx_phase);
[rx_bits sync foff_fine pd] = qpsk_to_bits(prev_rx_symbols, rx_symbols, modulation);
if strcmp(modulation,'dqpsk')
%rx_symbols_log = [rx_symbols_log rx_symbols.*conj(prev_rx_symbols)*exp(j*pi/4)];
rx_symbols_log = [rx_symbols_log pd];
else
rx_symbols_log = [rx_symbols_log rx_symbols];
endif
foff -= 0.5*ferr;
prev_rx_symbols = rx_symbols;
sync_log = [sync_log sync];
% freq est state machine
[track fest_state] = freq_state(sync, fest_state);
track_log = [track_log track];
% Update SNR est
[sig_est noise_est] = snr_update(sig_est, noise_est, pd);
% count bit errors if we find a test frame
% Allow 15 frames for filter memories to fill and time est to settle
[test_frame_sync bit_errors] = put_test_bits(rx_bits);
if test_frame_sync == 1
total_bit_errors = total_bit_errors + bit_errors;
total_bits = total_bits + Ntest_bits;
bit_errors_log = [bit_errors_log bit_errors];
else
bit_errors_log = [bit_errors_log 0];
end
% test frame sync state machine, just for more informative plots
next_test_frame_sync_state = test_frame_sync_state;
if (test_frame_sync_state == 0)
if (test_frame_sync == 1)
next_test_frame_sync_state = 1;
test_frame_count = 0;
end
end
if (test_frame_sync_state == 1)
% we only expect another test_frame_sync pulse every 4 symbols
test_frame_count++;
if (test_frame_count == 4)
test_frame_count = 0;
if ((test_frame_sync == 0))
next_test_frame_sync_state = 0;
end
end
end
test_frame_sync_state = next_test_frame_sync_state;
test_frame_sync_log = [test_frame_sync_log test_frame_sync_state];
end
% ---------------------------------------------------------------------
% Print Stats
% ---------------------------------------------------------------------
ber = total_bit_errors / total_bits;
% Peak to Average Power Ratio calcs from http://www.dsplog.com
papr = max(tx_fdm_log.*conj(tx_fdm_log)) / mean(tx_fdm_log.*conj(tx_fdm_log));
papr_dB = 10*log10(papr);
% Note Eb/No set point is for Nc data carriers only, exclduing pilot.
% This is convenient for testing BER versus Eb/No. Measured Eb/No
% includes power of pilot. Similar for SNR, first number is SNR excluding
% pilot pwr for Eb/No set point, 2nd value is measured SNR which will be a little
% higher as pilot power is included.
printf("Eb/No (meas): %2.2f (%2.2f) dB\n", EbNo_dB, 10*log10(0.25*tx_pwr*Fs/(Rs*Nc*noise_pwr)));
printf("bits........: %d\n", total_bits);
printf("errors......: %d\n", total_bit_errors);
printf("BER.........: %1.4f\n", ber);
printf("PAPR........: %1.2f dB\n", papr_dB);
printf("SNR...(meas): %2.2f (%2.2f) dB\n", SNR, calc_snr(sig_est, noise_est));
% ---------------------------------------------------------------------
% Plots
% ---------------------------------------------------------------------
figure(1)
clf;
[n m] = size(rx_symbols_log);
plot(real(rx_symbols_log(1:Nc+1,15:m)),imag(rx_symbols_log(1:Nc+1,15:m)),'+')
axis([-3 3 -3 3]);
title('Scatter Diagram');
figure(2)
clf;
subplot(211)
plot(rx_timing_log)
title('timing offset (samples)');
subplot(212)
plot(foff_log, '-;freq offset;')
hold on;
plot(track_log*75, 'r;course-fine;');
hold off;
title('Freq offset (Hz)');
figure(3)
clf;
subplot(211)
plot(real(tx_fdm_log));
title('FDM Tx Signal');
subplot(212)
Nfft=Fs;
S=fft(rx_fdm_log,Nfft);
SdB=20*log10(abs(S));
plot(SdB(1:Fs/4))
title('FDM Rx Spectrum');
figure(4)
clf;
subplot(311)
stem(sync_log)
axis([0 frames 0 1.5]);
title('BPSK Sync')
subplot(312)
stem(bit_errors_log);
title('Bit Errors for test frames')
subplot(313)
plot(test_frame_sync_log);
axis([0 frames 0 1.5]);
title('Test Frame Sync')

View File

@ -1,40 +0,0 @@
% gen_rn_coeffs.m
% David Rowe 13 april 2012
%
% Generate root raised cosine (Root Nyquist) filter coefficients
% thanks http://www.dsplog.com/db-install/wp-content/uploads/2008/05/raised_cosine_filter.m
function coeffs = gen_rn_coeffs(alpha, T, Rs, Nsym, M)
Ts = 1/Rs;
n = -Nsym*Ts/2:T:Nsym*Ts/2;
Nfilter = Nsym*M;
Nfiltertiming = M+Nfilter+M;
sincNum = sin(pi*n/Ts); % numerator of the sinc function
sincDen = (pi*n/Ts); % denominator of the sinc function
sincDenZero = find(abs(sincDen) < 10^-10);
sincOp = sincNum./sincDen;
sincOp(sincDenZero) = 1; % sin(pix/(pix) =1 for x =0
cosNum = cos(alpha*pi*n/Ts);
cosDen = (1-(2*alpha*n/Ts).^2);
cosDenZero = find(abs(cosDen)<10^-10);
cosOp = cosNum./cosDen;
cosOp(cosDenZero) = pi/4;
gt_alpha5 = sincOp.*cosOp;
Nfft = 4096;
GF_alpha5 = fft(gt_alpha5,Nfft)/M;
% sqrt causes stop band to be amplified, this hack pushes it down again
for i=1:Nfft
if (abs(GF_alpha5(i)) < 0.02)
GF_alpha5(i) *= 0.001;
endif
end
GF_alpha5_root = sqrt(abs(GF_alpha5)) .* exp(j*angle(GF_alpha5));
ifft_GF_alpha5_root = ifft(GF_alpha5_root);
coeffs = real((ifft_GF_alpha5_root(1:Nfilter)));
endfunction

View File

@ -1,29 +0,0 @@
% glottal.m
% David Rowe 12 Sep 2009
% Matlab script to generate the phase spectra of a glottal pulse
% lpc10 pulse from spandsp. When the file glottal.c was used as a part of the
% excitation phase component in phase.c, phase_synth_zero_order(), no difference
% in speech quality was apparent. So left out of code for now.
sh=12
kexc = [ 8, -16, 26, -48, 86, -162, 294, -502, 718, -728, 184 672, -610, -672, 184, 728, 718, 502, 294, 162, 86, 48, 26, 16, 8];
kexc = shift(kexc,sh);
kexc = [kexc(1:sh) zeros(1,512-25) kexc(sh+1:25)];
figure(1)
clf
plot(kexc)
figure(2)
G = fft(kexc);
subplot(211)
plot((1:256)*(4000/256),unwrap(angle(G(1:256))))
subplot(212)
plot(20*log10(abs(G)))
f=fopen("glottal.c","wt");
fprintf(f,"const float glottal[]={\n");
for m=1:255
fprintf(f," %f,\n",angle(G(m)));
endfor
fprintf(f," %f};\n",angle(G(256)));
fclose(f);

View File

@ -1,12 +0,0 @@
% hp_filt.m
% David Rowe 20 Feb 2012
function hp_filt(in_file, out_file)
fin = fopen(in_file,"rb");
s = fread(fin,Inf,"short");
b = fir1(256, 300/4000, "high");
freqz(b);
s_hpf = filter(b,1,s);
fout = fopen(out_file,"wb");
fwrite(fout, s_hpf, "short");
endfunction

View File

@ -1,8 +0,0 @@
% load_raw.m
% David Rowe 7 Oct 2009
function s = load_raw(fn)
fs=fopen(fn,"rb");
s = fread(fs,Inf,"short");
plot(s)
endfunction

View File

@ -1,46 +0,0 @@
% lpcpf.m
% David Rowe Aug 27 2012
% Experiments with LPC post filtering
function lpcpf(ak_filename, f)
aks = load(ak_filename);
ak = aks(f,:);
[tmp p] = size(ak);
p -= 1;
A = freqz(1,ak, 4000);
AdB = 20*log10(abs(A));
gamma = 0.5;
gammas = gamma .^ (0:p);
W = freqz(ak .* gammas,1, 4000);
WdB = 20*log10(abs(W));
beta = 0.2;
R = abs(freqz(ak .* gammas, ak, 4000));
%P = (R/max(R)) .^ beta;
P = R .^ beta;
AP = abs(A) .* P;
eA = sum(abs(A) .^ 2);
eAP = sum(AP .^ 2);
gain = sqrt(eA/eAP)
AP *= gain;
PdB = 20*log10(P);
APdB = 20*log10(AP);
10*log10(sum(AP .^ 2))/10*log10(sum(abs(A) .^ 2))
figure(1);
clf;
plot(AdB);
hold on;
plot(WdB,'g');
plot(PdB,'r');
plot(APdB,'b.');
hold off;
endfunction

View File

@ -1,91 +0,0 @@
% lsp_pdf.m
% David Rowe 2 Oct 2009
% Plots histograms (PDF estimates) of LSP training data
function lsp_pdf(lsp)
[r,c] = size(lsp);
% LSPs
figure(1);
clf;
[x,y] = hist(lsp(:,1),100);
plot(y*4000/pi,x,"+;1;");
hold on;
for i=2:5
[x,y] = hist(lsp(:,i),100);
legend = sprintf("+%d;%d;",i,i);
plot(y*4000/pi,x,legend);
endfor
for i=6:c
[x,y] = hist(lsp(:,i),100);
legend = sprintf("+%d;%d;",i-5,i);
plot(y*4000/pi,x,legend);
endfor
hold off;
grid;
% LSP differences
figure(2);
clf;
subplot(211)
[x,y] = hist(lsp(:,1),100);
plot(y*4000/pi,x,"1;1;");
hold on;
for i=2:5
[x,y] = hist(lsp(:,i) - lsp(:,i-1),100);
legend = sprintf("%d;%d;",i,i);
plot(y*4000/pi,x,legend);
endfor
hold off;
grid;
subplot(212)
[x,y] = hist(lsp(:,6)-lsp(:,5),100);
plot(y*4000/pi,x,"1;6;");
hold on;
for i=7:c
[x,y] = hist(lsp(:,i) - lsp(:,i-1),100);
legend = sprintf("%d;%d;",i-5,i);
plot(y*4000/pi,x,legend);
endfor
hold off;
grid;
% LSP differences delta from last frame
lspd(:,1) = lsp(:,1);
lspd(:,2:10) = lsp(:,2:10) - lsp(:,1:9);
[m,n] = size(lspd);
lspdd = lspd(5:m,:) - lspd(1:m-4,:);
figure(3);
clf;
subplot(211)
for i=1:5
[x,y] = hist(lspdd(:,i),100);
legend = sprintf("%d;%d;",i,i);
plot(y*4000/pi,x,legend);
hold on;
endfor
hold off;
grid;
axis([-200 200 0 35000]);
subplot(212)
for i=6:10
[x,y] = hist(lspdd(:,i),100);
legend = sprintf("%d;%d;",i-5,i);
plot(y*4000/pi,x,legend);
hold on;
endfor
hold off;
grid;
axis([-200 200 0 16000]);
figure(4);
clf;
plot((4000/pi)*(lsp(2:r,3)-lsp(1:r-1,3)))
endfunction

View File

@ -1,40 +0,0 @@
% lspwarp.m
% David Rowe Sep 2012
%
% Experimenting with non-linear LSP frequency axis for LSP quantisation
% Plots a scaled mel axis.
1;
function mel = freq2mel(f)
mel = 70*log10(1 + f/700);
endfunction
function freq = mel2freq(m)
freq = 700*(10 ^ (m/70) - 1);
endfunction
x = []; y = [];
for freq = 100:25:4000
mel = freq2mel(freq);
x = [x freq];
y = [y mel];
end
plot(x,y)
grid
mel_start = floor(freq2mel(100));
mel_end = floor(freq2mel(4000));
x = []; y = [];
for mel=mel_start:mel_end
freq = mel2freq(mel);
x = [x freq];
y = [y mel];
end
hold on;
plot(x,y, '+')
hold off;

View File

@ -1,56 +0,0 @@
% phase.m
% David Rowe August 2009
% experiments with phase for sinusoidal codecs
function phase(samname, F0, png)
Wo=2*pi*F0/8000;
P=2*pi/Wo;
L = floor(pi/Wo);
Nsam = 16000;
N = 80;
F = Nsam/N;
A = 10000/L;
phi = zeros(1,L);
s = zeros(1,Nsam);
for m=floor(L/2):L
phi_off(m) = -m*Wo*8;
end
for f=1:F
phi(1) = phi(1) + Wo*N;
phi(1) = mod(phi(1),2*pi);
for m=1:L
phi(m) = m*phi(1);
end
x = zeros(1,N);
for m=1:L
x = x + A*cos(m*Wo*(0:(N-1)) + phi(m));
endfor
s((f-1)*N+1:f*N) = x;
endfor
figure(1);
clf;
plot(s(1:250));
fs=fopen(samname,"wb");
fwrite(fs,s,"short");
fclose(fs);
if (nargin == 3)
% small image to fit blog
__gnuplot_set__ terminal png size 450,300
ss = sprintf("__gnuplot_set__ output \"%s.png\"", samname);
eval(ss)
replot;
% for some reason I need this to stop large plot getting wiped
__gnuplot_set__ output "/dev/null"
endif
endfunction

View File

@ -1,57 +0,0 @@
% phase2.m
% David Rowe Sep 2009
% experiments with phase for sinusoidal codecs, looking at phase
% of excitation with real Am samples from hts1
function phase2(samname, png)
N = 16000;
f=43;
model = load("../src/hts1a_phase_model.txt");
phase = load("../src/hts1a_phase_phase.txt");
Wo = model(f,1);
P=2*pi/Wo;
L = model(f,2);
A = model(f,3:(L+2));
phi = phase(f,1:L);
phi = zeros(1,L);
phi(3) = -pi/2;
phi(4) = -pi/4;
phi(5) = pi/2;
s = zeros(1,N);
for m=3:5
s_m = A(m)*cos(m*Wo*(0:(N-1)) + phi(m));
s = s + s_m;
endfor
figure(1);
clf;
plot(s(1:250));
figure(2);
clf;
subplot(211)
plot((1:L)*Wo*4000/pi, 20*log10(A),'+');
subplot(212)
plot((1:L)*Wo*4000/pi, phi,'+');
fs=fopen(samname,"wb");
fwrite(fs,s,"short");
fclose(fs);
if (nargin == 2)
% small image to fit blog
__gnuplot_set__ terminal png size 450,300
ss = sprintf("__gnuplot_set__ output \"%s.png\"", samname);
eval(ss)
replot;
% for some reason I need this to stop large plot getting wiped
__gnuplot_set__ output "/dev/null"
endif
endfunction

View File

@ -1,47 +0,0 @@
% phasesecord.m
% David Rowe Aug 2012
% Used to experiment with aproximations of phase of 2nd order systems
function phasesecord(w,beta)
a = [1 -2*cos(w)*beta beta*beta];
b = 1;
[h w1] = freqz(b,a);
figure(1)
subplot(211)
plot(abs(h))
subplot(212)
plot(angle(h))
% for beta close to 1, we approximate 3 dB points as 1-beta above
% and below the resonance freq. Note this fails if w=0 as there is a
% double pole. Lets sample the freq response at the 3dB points and
% w:
ws = [w-(1-beta) w w+(1-beta)];
[h w1] = freqz(b,a,ws);
% gain as a fraction of max, should be 3dB. Within 1.3 dB or for w > pi/8,
% gets innacurate near w=0 due to 2nd pole
printf("mag measured...:"); printf("% 4.3f ", abs(h)/max(abs(h)));
% measured angle, 45 deg from angle at w
printf("\nangle measured.: "); printf("% 5.3f ", angle(h));
% Our estimate of angle, (pi+w) is phase at resonance, at lower 3dB
% phase is pi/4 ahead, at upper 3B pi/4 behind. -pi/2 is contribution of
% other pole at at -w to phase
ph_lower = (pi+w) + pi/4 - pi/2;
ph_res =(pi+w) - pi/2;
ph_upper = (pi+w) - pi/4 - pi/2;
ph_ests = [ph_lower ph_res ph_upper];
ph_ests = ph_ests - 2*pi*(floor(ph_ests/(2*pi)) + 0.5);
printf("\nangle estimated:"); printf("% 5.3f ", ph_ests);
printf("\n");
endfunction

View File

@ -1,39 +0,0 @@
% pitch_test.m
% David Rowe Sep 2009
% Constructs a sequence to test the pitch estimator
function pitch_test(samname)
M=320;
F=200;
fs=fopen(samname,"wb");
f0 = 100;
for f=1:200
Wo=2*pi*f0/8000;
P=2*pi/Wo;
L = floor(pi/Wo);
A = 10000/L;
phi = zeros(1,L);
s = zeros(1,M);
for m=1:L
s = s + A*cos(m*Wo*(0:(M-1)) + phi(m));
endfor
figure(1);
clf;
plot(s);
fwrite(fs,s,"short");
f0 = f0 + 5;
if (f0 > 400)
f0 = 100;
endif
endfor
fclose(fs);
endfunction

View File

@ -1,45 +0,0 @@
% Copyright David Rowe 2009
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
% Plots a raw speech sample file, you can optionally specify the start and end
% samples and create a large and small PNGs
function pl(samname1, start_sam, end_sam, pngname)
fs=fopen(samname1,"rb");
s=fread(fs,Inf,"short");
st = 1;
en = length(s);
if (nargin >= 2)
st = start_sam;
endif
if (nargin >= 3)
en = end_sam;
endif
figure(1);
clf;
plot(s(st:en));
axis([1 en-st 1.1*min(s) 1.1*max(s)]);
if (nargin == 4)
% small image
__gnuplot_set__ terminal png size 420,300
ss = sprintf("__gnuplot_set__ output \"%s.png\"", pngname);
eval(ss)
replot;
% larger image
__gnuplot_set__ terminal png size 800,600
ss = sprintf("__gnuplot_set__ output \"%s_large.png\"", pngname);
eval(ss)
replot;
endif
endfunction

View File

@ -1,50 +0,0 @@
% Copyright David Rowe 2009
% This program is distributed under the terms of the GNU General Public License
% Version 2
function pl2(samname1, samname2, start_sam, end_sam, pngname)
fs1=fopen(samname1,"rb");
s1=fread(fs1,Inf,"short");
fs2=fopen(samname2,"rb");
s2=fread(fs2,Inf,"short");
st = 1;
en = length(s1);
if (nargin >= 3)
st = start_sam;
endif
if (nargin >= 4)
en = end_sam;
endif
figure(1);
clf;
subplot(211);
l1 = strcat("r;",samname1,";");
plot(s1(st:en), l1);
axis([1 en-st min(s1(st:en)) max(s1(st:en))]);
subplot(212);
l2 = strcat("r;",samname2,";");
plot(s2(st:en),l2);
axis([1 en-st min(s1(st:en)) max(s1(st:en))]);
if (nargin == 5)
% small image
__gnuplot_set__ terminal png size 420,300
s = sprintf("__gnuplot_set__ output \"%s.png\"", pngname);
eval(s)
replot;
% larger image
__gnuplot_set__ terminal png size 800,600
s = sprintf("__gnuplot_set__ output \"%s_large.png\"", pngname);
eval(s)
replot;
endif
endfunction

View File

@ -1,197 +0,0 @@
% Copyright David Rowe 2009
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
% Plot ampltiude modelling information from dump files.
function plamp(samname, f, samname2)
% switch some stuff off to unclutter display
plot_lsp = 0;
plot_snr = 0;
plot_vsnr = 0;
plot_sw = 0;
plot_pw = 0;
sn_name = strcat(samname,"_sn.txt");
Sn = load(sn_name);
sw_name = strcat(samname,"_sw.txt");
Sw = load(sw_name);
sw__name = strcat(samname,"_sw_.txt");
if (file_in_path(".",sw__name))
Sw_ = load(sw__name);
endif
ew_name = strcat(samname,"_ew.txt");
if (file_in_path(".",ew_name))
Ew = load(ew_name);
endif
rk_name = strcat(samname,"_rk.txt");
if (file_in_path(".",rk_name))
Rk = load(rk_name);
endif
model_name = strcat(samname,"_model.txt");
model = load(model_name);
modelq_name = strcat(samname,"_qmodel.txt");
if (file_in_path(".",modelq_name))
modelq = load(modelq_name);
endif
pw_name = strcat(samname,"_pw.txt");
if (file_in_path(".",pw_name))
Pw = load(pw_name);
endif
lsp_name = strcat(samname,"_lsp.txt");
if (file_in_path(".",lsp_name))
lsp = load(lsp_name);
endif
phase_name = strcat(samname,"_phase.txt");
if (file_in_path(".",phase_name))
phase = load(phase_name);
endif
phase_name_ = strcat(samname,"_phase_.txt");
if (file_in_path(".",phase_name_))
phase_ = load(phase_name_);
endif
snr_name = strcat(samname,"_snr.txt");
if (file_in_path(".",snr_name))
snr = load(snr_name);
endif
% optional second file, for exploring post filter
model2q_name = " ";
if nargin == 3
model2q_name = strcat(samname2,"_qmodel.txt");
if file_in_path(".",modelq_name)
model2q = load(model2q_name);
end
end
Ew_on = 1;
k = ' ';
do
figure(1);
clf;
% s = [ Sn(2*(f-2)-1,:) Sn(2*(f-2),:) ];
s = [ Sn(2*f-1,:) Sn(2*f,:) ];
size(s);
plot(s);
axis([1 length(s) -20000 20000]);
figure(2);
Wo = model(f,1);
L = model(f,2);
Am = model(f,3:(L+2));
plot((1:L)*Wo*4000/pi, 20*log10(Am),";Am;r");
axis([1 4000 -10 80]);
hold on;
if plot_sw
plot((0:255)*4000/256, Sw(f,:),";Sw;");
end
if (file_in_path(".",modelq_name))
Amq = modelq(f,3:(L+2));
plot((1:L)*Wo*4000/pi, 20*log10(Amq),";Amq;g" );
if (file_in_path(".",pw_name) && plot_pw)
plot((0:255)*4000/256, 10*log10(Pw(f,:)),";Pw;c");
endif
signal = Am * Am';
noise = (Am-Amq) * (Am-Amq)';
snr1 = 10*log10(signal/noise);
Am_err_label = sprintf(";Am error SNR %4.2f dB;m",snr1);
plot((1:L)*Wo*4000/pi, 20*log10(Amq) - 20*log10(Am), Am_err_label);
endif
if file_in_path(".",model2q_name)
Amq2 = model2q(f,3:(L+2));
plot((1:L)*Wo*4000/pi, 20*log10(Amq2),";Amq2;m" );
end
if (file_in_path(".",snr_name) && plot_vsnr)
snr_label = sprintf(";Voicing SNR %4.2f dB;",snr(f));
plot(1,1,snr_label);
endif
% phase model - determine SNR and error spectrum for phase model 1
if (file_in_path(".",phase_name_))
orig = Am.*exp(j*phase(f,1:L));
synth = Am.*exp(j*phase_(f,1:L));
signal = orig * orig';
noise = (orig-synth) * (orig-synth)';
snr_phase = 10*log10(signal/noise);
%phase_err_label = sprintf(";phase_err SNR %4.2f dB;",snr_phase);
%plot((1:L)*Wo*4000/pi, 20*log10(orig-synth), phase_err_label);
endif
if (file_in_path(".",lsp_name) && plot_lsp)
for l=1:10
plot([lsp(f,l)*4000/pi lsp(f,l)*4000/pi], [60 80], 'r');
endfor
endif
hold off;
%if (file_in_path(".",phase_name))
%figure(3);
%plot((1:L)*Wo*4000/pi, phase(f,1:L), ";phase;");
%axis;
%if (file_in_path(".",phase_name_))
%hold on;
%plot((1:L)*Wo*4000/pi, phase_(f,1:L), ";phase_;");
%hold off;
%endif
%figure(2);
%endif
% interactive menu
printf("\rframe: %d menu: n-next b-back p-png q-quit e-toggle Ew", f);
fflush(stdout);
k = kbhit();
if (k == 'n')
f = f + 1;
endif
if (k == 'b')
f = f - 1;
endif
if (k == 'e')
if (Ew_on == 1)
Ew_on = 0;
else
Ew_on = 1;
endif
endif
% optional print to PNG
if (k == 'p')
figure(1);
pngname = sprintf("%s_%d_sn.png",samname,f);
print(pngname, '-dpng', "-S500,500")
pngname = sprintf("%s_%d_sn_large.png",samname,f);
print(pngname, '-dpng', "-S800,600")
figure(2);
pngname = sprintf("%s_%d_sw.png",samname,f);
print(pngname, '-dpng', "-S500,500")
pngname = sprintf("%s_%d_sw_large.png",samname,f);
print(pngname, '-dpng', "-S1200,800")
endif
until (k == 'q')
printf("\n");
endfunction

View File

@ -1,11 +0,0 @@
load ../unittest/tinterp_prev.txt;
load ../unittest/tinterp_interp.txt;
load ../unittest/tinterp_next.txt;
clf;
plot(tinterp_prev(:,1), 20.0*log10(tinterp_prev(:,2)),";prev;")
hold on;
plot(tinterp_interp(:,1), 20.0*log10(tinterp_interp(:,2)),'g+-;interp;')
plot(tinterp_next(:,1), 20.0*log10(tinterp_next(:,2)),'ro-;next;')
hold off;
axis([0 pi 0 80])

View File

@ -1,150 +0,0 @@
% Copyright David Rowe 2012
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
% Plot amplitude modelling information from dump files to test and develop
% LPC post filter.
function pllpcpf(samname, f)
% switch some stuff off to unclutter display
plot_Am = 0;
plot_Amq = 0;
plot_err = 0;
plot_lsp = 0;
plot_snr = 0;
plot_vsnr = 0;
plot_sw = 0;
plot_pw = 1;
plot_pwb = 1;
plot_rw = 1;
sn_name = strcat(samname,"_sn.txt");
Sn = load(sn_name);
sw_name = strcat(samname,"_sw.txt");
Sw = load(sw_name);
sw__name = strcat(samname,"_sw_.txt");
if (file_in_path(".",sw__name))
Sw_ = load(sw__name);
endif
model_name = strcat(samname,"_model.txt");
model = load(model_name);
modelq_name = strcat(samname,"_qmodel.txt");
if (file_in_path(".",modelq_name))
modelq = load(modelq_name);
endif
% Pw (LPC synth filter spectrum) before post filter
pwb_name = strcat(samname,"_pwb.txt");
if (file_in_path(".",pwb_name))
Pwb = load(pwb_name);
endif
% Rw (Post filter spectrum)
rw_name = strcat(samname,"_rw.txt");
if (file_in_path(".",rw_name))
Rw = load(rw_name);
endif
% Pw (LPC synth filter spectrum) after post filter
pw_name = strcat(samname,"_pw.txt");
if (file_in_path(".",pw_name))
Pw = load(pw_name);
endif
Ew_on = 1;
k = ' ';
do
figure(1);
clf;
s = [ Sn(2*f-1,:) Sn(2*f,:) ];
size(s);
plot(s);
axis([1 length(s) -20000 20000]);
figure(2);
clf;
Wo = model(f,1);
L = model(f,2);
Am = model(f,3:(L+2));
if plot_Am
plot((1:L)*Wo*4000/pi, 20*log10(Am),";Am;r");
end
axis([1 4000 -10 80]);
hold on;
if plot_sw
plot((0:255)*4000/256, Sw(f,:),";Sw;");
end
if (file_in_path(".",modelq_name))
Amq = modelq(f,3:(L+2));
if plot_Amq
plot((1:L)*Wo*4000/pi, 20*log10(Amq),";Amq;g" );
end
if (file_in_path(".",pwb_name) && plot_pwb)
plot((0:255)*4000/256, 10*log10(Pwb(f,:)),";Pwb;r");
endif
if (file_in_path(".",rw_name) && plot_rw)
plot((0:255)*4000/256, 10*log10(Rw(f,:)),";Rw;b");
endif
if (file_in_path(".",pw_name) && plot_pw)
plot((0:255)*4000/256, 10*log10(Pw(f,:)),";Pw;g.");
endif
signal = Am * Am';
noise = (Am-Amq) * (Am-Amq)';
snr1 = 10*log10(signal/noise);
Am_err_label = sprintf(";Am error SNR %4.2f dB;m",snr1);
if plot_err
plot((1:L)*Wo*4000/pi, 20*log10(Amq) - 20*log10(Am), Am_err_label);
end
endif
hold off;
% interactive menu
printf("\rframe: %d menu: n-next b-back p-png q-quit", f);
fflush(stdout);
k = kbhit();
if (k == 'n')
f = f + 1;
endif
if (k == 'b')
f = f - 1;
endif
% optional print to PNG
if (k == 'p')
figure(1);
pngname = sprintf("%s_%d_sn.png",samname,f);
print(pngname, '-dpng', "-S500,500")
pngname = sprintf("%s_%d_sn_large.png",samname,f);
print(pngname, '-dpng', "-S800,600")
figure(2);
pngname = sprintf("%s_%d_sw.png",samname,f);
print(pngname, '-dpng', "-S500,500")
pngname = sprintf("%s_%d_sw_large.png",samname,f);
print(pngname, '-dpng', "-S1200,800")
endif
until (k == 'q')
printf("\n");
endfunction

View File

@ -1,46 +0,0 @@
% Copyright David Rowe 2010
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
% Plots a bunch of information related to LSP quantisation:
% - speech file
% - LSPs before and after quantisation
% - SNR for each frame
%
% Note: there is a 160 sample (two frame delay) from the when a sample
% enters the input buffer until it is at the centre of the analysis window
function pllsp(rawfile,
dumpfile_prefix_lpc_only,
dumpfile_prefix_lsp,
start_f, end_f)
fs=fopen(rawfile,"rb");
s=fread(fs,Inf,"short");
lpc_snr_name = strcat(dumpfile_prefix_lpc_only,"_lpc_snr.txt");
lpc10_snr = load(lpc_snr_name);
lpc_snr_name = strcat(dumpfile_prefix_lsp,"_lpc_snr.txt");
lsp_snr = load(lpc_snr_name);
lsp_name = strcat(dumpfile_prefix_lsp,"_lsp.txt");
lsps = load(lsp_name);
[m,n]=size(lsps);
lsp = lsps(1:2:m,:);
lsp_ = lsps(2:2:m,:);
figure(1);
clf;
subplot(211);
sp = s((start_f-2)*80:(end_f-2)*80);
plot(sp);
subplot(212);
plot(lpc10_snr((start_f+1):end_f)-lsp_snr((start_f+1):end_f));
figure(2);
plot((4000/pi)*lsp((start_f+1):end_f,:));
hold on;
plot((4000/pi)*lsp_((start_f+1):end_f,:),'+-');
hold off;
endfunction

View File

@ -1,27 +0,0 @@
% pllspdt.m
% Copyright David Rowe 2010
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
% Test script to plot differences in LSps between frames
function pllspdt(rawfile,dumpfile_prefix_lsp,lspn, start_f, end_f)
fs=fopen(rawfile,"rb");
s=fread(fs,Inf,"short");
lsp_name = strcat(dumpfile_prefix_lsp,"_lsp.txt");
lsps = load(lsp_name);
[m,n]=size(lsps);
lsp = lsps(1:2:m,:);
lsp_ = lsps(2:2:m,:);
lspdt = lsp(2:m/2,:) - lsp(1:m/2-1,:);
figure(1);
clf;
sp = s((start_f-2)*80:(end_f-2)*80);
plot(sp);
figure(2);
plot((4000/pi)*lspdt((start_f+1):end_f,lspn));
endfunction

View File

@ -1,134 +0,0 @@
% Copyright David Rowe 2009
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
% Plot NLP states from dump files.
function plnlp(samname, f)
sn_name = strcat(samname,"_sn.txt");
Sn = load(sn_name);
sw_name = strcat(samname,"_sw.txt");
Sw = load(sw_name);
fw_name = strcat(samname,"_fw.txt");
if (file_in_path(".",fw_name))
fw = load(fw_name);
endif
e_name = strcat(samname,"_e.txt");
if (file_in_path(".",e_name))
e = load(e_name);
endif
p_name = strcat(samname,".p");
if (file_in_path(".",p_name))
p = load(p_name);
endif
sq_name = strcat(samname,"_sq.txt");
if (file_in_path(".",sq_name))
sq = load(sq_name);
endif
dec_name = strcat(samname,"_dec.txt");
if (file_in_path(".",dec_name))
dec = load(dec_name);
endif
do
figure(1);
clf;
s = [ Sn(2*f-1,:) Sn(2*f,:) ];
plot(s, ";Sn;");
grid
axis([1 length(s) -20000 20000]);
figure(2);
plot((0:255)*4000/256, Sw(f,:),";Sw;");
grid
axis([1 4000 -10 80]);
hold on;
f0 = 8000/p(f);
Wo = 2*pi/p(f);
L = floor(pi/Wo);
f0_label = sprintf("b;P=%3.1f F0=%3.0f;",p(f),f0);
for m=1:L-1
plot([ m*Wo*4000/pi m*Wo*4000/pi], [10 60], 'b');
endfor
plot([ L*Wo*4000/pi L*Wo*4000/pi], [10 60], f0_label);
hold off;
if (file_in_path(".",fw_name))
figure(3);
if (file_in_path(".",e_name))
subplot(211);
endif
plot((0:255)*800/256, fw(f,:)/max(fw(f,:)), ";Fw;");
axis([1 400 0 1]);
if (file_in_path(".",e_name))
subplot(212);
e_concat = [ e(2*f-1,:) e(2*f,:) ];
plot(e_concat(1:400)/max(e_concat(1:400)), "+;MBE E(f);");
axis([1 400 0 1]);
endif
endif
if (file_in_path(".",sq_name))
figure(4);
sq_concat = [ sq(2*f-1,:) sq(2*f,:) ];
axis
plot(sq_concat, ";sq;");
endif
if (file_in_path(".",dec_name))
figure(5);
plot(dec(f,:), ";dec;");
endif
figure(2);
% interactive menu
printf("\rframe: %d menu: n-next b-back p-png q-quit ", f);
fflush(stdout);
k = kbhit();
if (k == 'n')
f = f + 1;
endif
if (k == 'b')
f = f - 1;
endif
% optional print to PNG
if (k == 'p')
pngname = sprintf("%s_%d",samname,f);
% small image
__gnuplot_set__ terminal png size 420,300
ss = sprintf("__gnuplot_set__ output \"%s.png\"", pngname);
eval(ss)
replot;
% larger image
__gnuplot_set__ terminal png size 800,600
ss = sprintf("__gnuplot_set__ output \"%s_large.png\"", pngname);
eval(ss)
replot;
% for some reason I need this to stop large plot getting wiped
__gnuplot_set__ output "/dev/null"
endif
until (k == 'q')
printf("\n");
endfunction

View File

@ -1,198 +0,0 @@
% Copyright David Rowe 2009
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
% Plot phase modelling information from dump files.
function plphase(samname, f)
sn_name = strcat(samname,"_sn.txt");
Sn = load(sn_name);
sw_name = strcat(samname,"_sw.txt");
Sw = load(sw_name);
model_name = strcat(samname,"_model.txt");
model = load(model_name);
sw__name = strcat(samname,"_sw_.txt");
if (file_in_path(".",sw__name))
Sw_ = load(sw__name);
endif
pw_name = strcat(samname,"_pw.txt");
if (file_in_path(".",pw_name))
Pw = load(pw_name);
endif
ak_name = strcat(samname,"_ak.txt");
if (file_in_path(".",ak_name))
ak = load(ak_name);
endif
phase_name = strcat(samname,"_phase.txt");
if (file_in_path(".",phase_name))
phase = load(phase_name);
endif
phase_name_ = strcat(samname,"_phase_.txt");
if (file_in_path(".",phase_name_))
phase_ = load(phase_name_);
endif
snr_name = strcat(samname,"_snr.txt");
if (file_in_path(".",snr_name))
snr = load(snr_name);
endif
sn_name_ = strcat(samname,".raw");
if (file_in_path(".",sn_name_))
fs_ = fopen(sn_name_,"rb");
sn_ = fread(fs_,Inf,"short");
endif
k = ' ';
do
figure(1);
clf;
s = [ Sn(2*f-1,:) Sn(2*f,:) ];
plot(s);
grid;
axis([1 length(s) -20000 20000]);
if (k == 'p')
pngname = sprintf("%s_%d_sn",samname,f);
png(pngname);
endif
figure(2);
Wo = model(f,1);
L = model(f,2);
Am = model(f,3:(L+2));
plot((1:L)*Wo*4000/pi, 20*log10(Am),"r;Am;");
axis([1 4000 -10 80]);
hold on;
plot((0:255)*4000/256, Sw(f,:),";Sw;");
grid;
if (file_in_path(".",sw__name))
plot((0:255)*4000/256, Sw_(f,:),"g;Sw_;");
endif
if (file_in_path(".",pw_name))
plot((0:255)*4000/256, 10*log10(Pw(f,:)),";Pw;");
endif
if (file_in_path(".",snr_name))
snr_label = sprintf(";phase SNR %4.2f dB;",snr(f));
plot(1,1,snr_label);
endif
% phase model - determine SNR and error spectrum for phase model 1
if (file_in_path(".",phase_name_))
orig = Am.*exp(j*phase(f,1:L));
synth = Am.*exp(j*phase_(f,1:L));
signal = orig * orig';
noise = (orig-synth) * (orig-synth)';
snr_phase = 10*log10(signal/noise);
phase_err_label = sprintf("g;phase_err SNR %4.2f dB;",snr_phase);
plot((1:L)*Wo*4000/pi, 20*log10(orig-synth), phase_err_label);
endif
hold off;
if (k == 'p')
pngname = sprintf("%s_%d_sw",samname,f);
png(pngname);
endif
if (file_in_path(".",phase_name))
figure(3);
plot((1:L)*Wo*4000/pi, phase(f,1:L)*180/pi, "-o;phase;");
axis;
if (file_in_path(".", phase_name_))
hold on;
plot((1:L)*Wo*4000/pi, phase_(f,1:L)*180/pi, "g;phase after;");
grid
hold off;
endif
if (k == 'p')
pngname = sprintf("%s_%d_phase",samname,f);
png(pngname);
endif
endif
% synthesised speech
if (file_in_path(".",sn_name_))
figure(4);
s_ = sn_((f-3)*80+1:(f+1)*80);
plot(s_);
axis([1 length(s_) -20000 20000]);
if (k == 'p')
pngname = sprintf("%s_%d_sn_",samname,f)
png(pngname);
endif
endif
if (file_in_path(".",ak_name))
figure(5);
axis;
akw = ak(f,:);
weight = 1.0 .^ (0:length(akw)-1);
akw = akw .* weight;
H = 1./fft(akw,8000);
subplot(211);
plot(20*log10(abs(H(1:4000))),";LPC mag spec;");
grid;
subplot(212);
plot(angle(H(1:4000))*180/pi,";LPC phase spec;");
grid;
if (k == 'p')
% stops multimode errors from gnuplot, I know not why...
figure(2);
figure(5);
pngname = sprintf("%s_%d_lpc",samname,f);
png(pngname);
endif
endif
% autocorrelation function to research voicing est
%M = length(s);
%sw = s .* hanning(M)';
%for k=0:159
% R(k+1) = sw(1:320-k) * sw(1+k:320)';
%endfor
%figure(4);
%R_label = sprintf(";R(k) %3.2f;",max(R(20:159))/R(1));
%plot(R/R(1),R_label);
%grid
figure(2);
% interactive menu
printf("\rframe: %d menu: n-next b-back p-png q-quit ", f);
fflush(stdout);
k = kbhit();
if (k == 'n')
f = f + 1;
endif
if (k == 'b')
f = f - 1;
endif
% optional print to PNG
if (k == 'p')
pngname = sprintf("%s_%d",samname,f);
png(pngname);
endif
until (k == 'q')
printf("\n");
endfunction

View File

@ -1,36 +0,0 @@
% Copyright David Rowe 2009
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
% plpitch.m
% Plots two pitch tracks on top of each other, used for comparing pitch
% estimators
function plpitch(pitch1_name, pitch2_name, start_fr, end_fr)
pitch1 = load(pitch1_name);
pitch2 = load(pitch2_name);
st = 1;
en = length(pitch1);
if (nargin >= 3)
st = start_fr;
endif
if (nargin >= 4)
en = end_fr;
endif
figure(1);
clf;
l1 = strcat("r;",pitch1_name,";")
l1
st
en
plot(pitch1(st:en), l1);
axis([1 en-st 20 160]);
l2 = strcat("g;",pitch2_name,";");
hold on;
plot(pitch2(st:en),l2);
hold off;
endfunction

View File

@ -1,65 +0,0 @@
% Copyright David Rowe 2009
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
% Plot two sparse phase prediction error text files.
% Generate data from print_pred_error, print_pred_error_sparse_wo_correction1 etc
function plppe(ppe1_file, ppe2_file, f)
ppe1 = load(ppe1_file);
ppe2 = load(ppe2_file);
std1 = std(nonzeros(ppe1(:,40:80)));
std2 = std(nonzeros(ppe2(:,40:80)));
printf("std dev for %s is %4.3f\n", ppe1_file, std1);
printf("std dev for %s is %4.3f\n", ppe2_file, std2);
figure(1);
clf;
subplot(211)
hist(nonzeros(ppe1(:,40:80)),20);
subplot(212)
hist(nonzeros(ppe2(:,40:80)),20);
k = ' ';
do
figure(2);
clf;
subplot(211)
L = length(nonzeros(ppe1(f,:)));
x = (1:L)*4000/L;
std1 = std(nonzeros(ppe1(f,:)));
legend = sprintf(";std dev %4.3f;", std1);
plot(x, nonzeros(ppe1(f,:)),legend);
axis([0 4000 -pi pi]);
subplot(212)
std2 = std(nonzeros(ppe2(f,:)));
legend = sprintf(";std dev %4.3f;", std2);
plot(x, nonzeros(ppe2(f,:)),legend);
axis([0 4000 -pi pi]);
% interactive menu
printf("\rframe: %d menu: n-next b-back p-png q-quit ", f);
fflush(stdout);
k = kbhit();
if (k == 'n')
f = f + 1;
endif
if (k == 'b')
f = f - 1;
endif
% optional print to PNG
if (k == 'p')
pngname = sprintf("%s_%d",samname,f);
png(pngname);
endif
until (k == 'q')
printf("\n");
endfunction

View File

@ -1,35 +0,0 @@
% Copyright David Rowe 2010
% This program is distributed under the terms of the GNU General Public License
% Version 2
% plots the difference of two files
function plsub(samname1, samname2, start_sam, end_sam, pngname)
fs1=fopen(samname1,"rb");
s1=fread(fs1,Inf,"short");
fs2=fopen(samname2,"rb");
s2=fread(fs2,Inf,"short");
st = 1;
en = length(s1);
if (nargin >= 3)
st = start_sam;
endif
if (nargin >= 4)
en = end_sam;
endif
figure(1);
clf;
l1 = strcat("r;",samname1,";");
plot(s1(st:en) - s2(st:en), l1);
%axis([1 en-st min(s1(st:en)) max(s1(st:en))]);
if (nargin == 5)
pngname = sprintf("%s.png",pngname);
print(pngname, '-dpng', "-S500,500")
pngname = sprintf("%s_large.png",pngname);
print(pngname, '-dpng', "-S800,600")
endif
endfunction

View File

@ -1,89 +0,0 @@
% Copyright David Rowe 2009
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
% Plot voicing information from sample and dump files.
%
% samfilename is the raw source file, e.g. "../raw/hts1a.raw"
% samname is the dumpfile prefix, e.g. "../src/hts1a"
%
% There is a 160 sample (two frame delay) from the when a sample
% enters the input buffer until it is at the centre of the analysis window
function plvoicing(samfilename, samname, start_f, end_f, pngname)
fs=fopen(samfilename,"rb");
s=fread(fs,Inf,"short");
snr_name = strcat(samname,"_snr.txt");
snr = load(snr_name);
model_name = strcat(samname,"_model.txt");
model = load(model_name);
Wo = model((start_f+1):end_f,1);
F0 = Wo*4000/pi;
dF0 = F0(1:length(Wo)-1) - F0(2:length(Wo));
% work out LP and HP energy
for f=(start_f+1):end_f
L = model(f,2);
Am = model(f,3:(L+2));
L2 = floor(L/2);
elow = Am(1:L2) * Am(1:L2)';
ehigh = Am(L2:L) * Am(L2:L)';
erat(f-(start_f+1)+1) = 10*log10(elow/ehigh);
endfor
figure(1);
clf;
sp = s((start_f-2)*80:(end_f-2)*80);
plot(sp);
hold on;
vhigh = snr((start_f+1):end_f) > 7;
vlow = snr((start_f+1):end_f) > 4;
% test correction based on erat
vlowadj = vlow;
for f=1:length(erat)-1
if (vlow(f) == 0)
if (erat(f) > 10)
vlowadj(f) = 1;
endif
endif
if (vlow(f) == 1)
if (erat(f) < -10)
vlowadj(f) = 0;
endif
if (abs(dF0(f)) > 15)
vlowadj(f) = 0;
endif
endif
endfor
x = 1:(end_f-start_f);
plot(x*80,snr((start_f+1):end_f)*1000,';SNRdB x 1000;g+');
plot(x*80,-8000 + vhigh*2000,';7dB thresh;g');
plot(x*80,-11000 + vlowadj*2000,';vlow with corr;g');
plot(x*80,erat*1000,';elow/ehigh in dB;r');
plot(x*80,-14000 + vlow*2000,';4dB thresh;r');
hold off;
grid
if (nargin == 5)
print(pngname, "-dpng", "-S500,500")
endif
figure(2)
Wo = model((start_f+1):end_f,1);
F0 = Wo*4000/pi;
dF0 = F0(1:length(Wo)-1) - F0(2:length(Wo));
%plot(dF0,'+--')
%hold on;
%plot([ 1 length(dF0) ], [10 10] ,'r')
%plot([ 1 length(dF0) ], [-10 -10] ,'r')
%axis([1 length(dF0) -50 50])
%hold off;
plot(F0,'+--')
endfunction

View File

@ -1,25 +0,0 @@
% Copyright David Rowe 2009
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
% Replot current plot as a png, generates small and large versions
function png(pngname)
% small image
__gnuplot_set__ terminal png size 420,300
ss = sprintf("__gnuplot_set__ output \"%s.png\"", pngname);
eval(ss)
replot;
% larger image
__gnuplot_set__ terminal png size 800,600
ss = sprintf("__gnuplot_set__ output \"%s_large.png\"", pngname);
eval(ss)
replot;
% for some reason I need this to stop large plot getting wiped
__gnuplot_set__ output "/dev/null"
endfunction

View File

@ -1,24 +0,0 @@
% Copyright David Rowe 2009
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
% Plot postfilter doing its thing
function postfilter(samname)
p = load(samname);
figure(1);
plot(p(:,1),";energy;");
hold on;
plot(p(:,2),";bg_est;");
hold off;
grid;
pngname=sprintf("%s_postfilter_1", samname);
png(pngname);
figure(2);
plot(p(:,3),";% unvoiced;");
grid;
pngname=sprintf("%s_postfilter_2", samname);
png(pngname);
endfunction

View File

@ -1,37 +0,0 @@
% pulse.m
% David Rowe August 2009
%
% Experiments with human pulse perception for sinusoidal codecs
function pulse(samname)
A = 1000;
K = 16000;
N = 80;
frames = K/N;
s = zeros(1,K);
for f=1:frames
% lets try placing np random pulses in every frame
P = 20 + (160-20)*rand(1,1);
Wo = 2*pi/P;
L = floor(pi/Wo);
sf = zeros(1,N);
for m=1:L/2:L
pos = floor(rand(1,1)*N)+1;
%pos = 50;
for l=m:m+L/2-1
sf = sf + A*cos(l*Wo*((f-1)*N+1:f*N) - pos*l*Wo);
endfor
endfor
s((f-1)*N+1:f*N) = sf;
endfor
plot(s(1:250));
fs=fopen(samname,"wb");
fwrite(fs,s,"short");
fclose(fs);
endfunction

View File

@ -1,101 +0,0 @@
% sd.m
% David Rowe Aug 2012
% Plots the spectal distorion between twofiles of LPCs. Used for LSP
% quantisation tuning.
function sd(raw_filename, dump_file_prefix, f)
ak1_filename = sprintf("%s_ak.txt", dump_file_prefix);
ak2_filename = sprintf("%s_ak_.txt", dump_file_prefix);
ak1 = load(ak1_filename);
ak2 = load(ak2_filename);
[ak1_r, ak1_c] = size(ak1);
[ak2_r, ak2_c] = size(ak1);
frames = max([ak1_r ak2_r]);
sd = zeros(1,frames);
Ndft = 512;
A1 = zeros(frames, Ndft);
A2 = zeros(frames, Ndft);
% initial helicopter view of all frames
for i = 1:frames
A1(i,:) = -20*log10(abs(fft(ak1(i,:),Ndft)));
A2(i,:) = -20*log10(abs(fft(ak2(i,:),Ndft)));
sd(i) = sum((A1(i,:) - A2(i,:)).^2)/Ndft;
end
printf("sd av %3.2f dB*dB\n", sum(sd)/frames);
figure(1);
clf;
subplot(211)
fs=fopen(raw_filename,"rb");
s = fread(fs,Inf,"short");
plot(s);
subplot(212)
plot(sd);
% now enter single step mode so we can analyse each frame
sn_name = strcat(dump_file_prefix,"_sn.txt");
Sn = load(sn_name);
lsp1_filename = sprintf("%s_lsp.txt", dump_file_prefix);
lsp2_filename = sprintf("%s_lsp_.txt", dump_file_prefix);
lsp1 = load(lsp1_filename);
lsp2 = load(lsp2_filename);
weights_filename = sprintf("%s_weights.txt", dump_file_prefix);
if file_in_path(".",weights_filename)
weights = load(weights_filename);
end
k = ' ';
do
figure(2);
clf;
subplot(211)
s = [ Sn(2*f-1,:) Sn(2*f,:) ];
size(s);
plot(s);
axis([1 length(s) -20000 20000]);
subplot(212);
plot((1:Ndft/2)*4000/(Ndft/2), A1(f,1:(Ndft/2)),";A1;r");
axis([1 4000 -20 40]);
hold on;
plot((1:Ndft/2)*4000/(Ndft/2), A2(f,1:(Ndft/2)),";A2;");
if file_in_path(".",weights_filename)
plot(lsp1(f,:)*4000/pi, weights(f,:),";weights;g+");
end
for l=1:10
plot([lsp1(f,l)*4000/pi lsp1(f,l)*4000/pi], [0 -10], 'r');
plot([lsp2(f,l)*4000/pi lsp2(f,l)*4000/pi], [-10 -20], 'b');
endfor
plot(0,0,';lsp1;r');
plot(0,0,';lsp2;b');
sd_str = sprintf(";sd %3.2f dB*dB;", sd(f));
plot(0,0,sd_str);
hold off;
% interactive menu
printf("\rframe: %d menu: n-next b-back q-quit", f);
fflush(stdout);
k = kbhit();
if (k == 'n')
f = f + 1;
endif
if (k == 'b')
f = f - 1;
endif
until (k == 'q')
printf("\n");
endfunction

View File

@ -1,86 +0,0 @@
% spec.m
% Jean Marc Valin
%
% Spectrogram function for Octave
%
% Copyright (c) John-Marc Valin 2012
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions
% are met:
%
% - Redistributions of source code must retain the above copyright
% notice, this list of conditions and the following disclaimer.
%
% - Redistributions in binary form must reproduce the above copyright
% notice, this list of conditions and the following disclaimer in the
% documentation and/or other materials provided with the distribution.
%
% - Neither the name of Jean Marc Valin nor the names of its
% contributors may be used to endorse or promote products derived from
% this software without specific prior written permission.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
% ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
% LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
% A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
% CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
% PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
% LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function X = spec(x, Fs, framesize, start, stop)
gr=[zeros(1024,1),[0:1023]'/1023,.68*[0:1023]'/1023];
%gr=[.4*[0:1023]'/1023,[0:1023]'/1023,.68*[0:1023]'/1023];
%t=[0:1023]'/1023;
%t=(1+.25*t-cos(pi*t))/2.25;
%gr = [zeros(1024,1),t,.68*t];
%colormap(gr);
if nargin < 2 || isempty(Fs)
Fs = 44100;
end
if nargin < 3 || isempty(framesize)
framesize = 2048;
endif
offset = framesize/4;
X = 20*log10(abs(specgram(x, framesize, 48000, blackmanharris(framesize)', framesize-offset)));
XM=max(max(X));
X = max(XM-120,X);
%size(X)
F = -[framesize/2-1:-1:0]/framesize*Fs;
%F = [0:127]/128*24000;
T=[1:size(X,2)]/Fs*offset;
%imagesc(X(end:-1:1,:));
if nargin < 4 || isempty(start)
istart=1;
else
istart = round(start*Fs/offset);
end
if nargin < 5 || isempty(stop)
istop = size(X,2);
else
istop = round(stop*Fs/offset);
endif
istart = max(1,istart);
istop = min(istop, size(X,2));
imagesc(T(1+istart:istop), F, X(end:-1:1,1+istart:istop));
X = X(:,1+istart:istop);

View File

@ -1,306 +0,0 @@
% tfdmdv.m
%
% Octave script that tests the C port of the FDMDV modem. This script loads
% the output of unittest/tfdmdv.c and compares it to the output of the
% reference versions of the same functions written in Octave.
%
% Copyright David Rowe 2012
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
fdmdv; % load modem code
% Generate reference vectors using Octave implementation of FDMDV modem
global passes;
global fails;
passes = fails = 0;
frames = 25;
prev_tx_symbols = ones(Nc+1,1);
prev_rx_symbols = ones(Nc+1,1);
foff_phase_rect = 1;
coarse_fine = 0;
fest_state = 0;
channel = [];
channel_count = 0;
next_nin = M;
sig_est = zeros(Nc+1,1);
noise_est = zeros(Nc+1,1);
% Octave outputs we want to collect for comparison to C version
tx_bits_log = [];
tx_symbols_log = [];
tx_baseband_log = [];
tx_fdm_log = [];
pilot_baseband1_log = [];
pilot_baseband2_log = [];
pilot_lpf1_log = [];
pilot_lpf2_log = [];
S1_log = [];
S2_log = [];
foff_coarse_log = [];
foff_fine_log = [];
foff_log = [];
rx_baseband_log = [];
rx_filt_log = [];
env_log = [];
rx_timing_log = [];
rx_symbols_log = [];
rx_bits_log = [];
sync_bit_log = [];
coarse_fine_log = [];
nin_log = [];
sig_est_log = [];
noise_est_log = [];
for f=1:frames
% modulator
tx_bits = get_test_bits(Nc*Nb);
tx_bits_log = [tx_bits_log tx_bits];
tx_symbols = bits_to_qpsk(prev_tx_symbols, tx_bits, 'dqpsk');
prev_tx_symbols = tx_symbols;
tx_symbols_log = [tx_symbols_log tx_symbols];
tx_baseband = tx_filter(tx_symbols);
tx_baseband_log = [tx_baseband_log tx_baseband];
tx_fdm = fdm_upconvert(tx_baseband);
tx_fdm_log = [tx_fdm_log tx_fdm];
% channel
nin = next_nin;
%nin = 120;
%nin = M;
%if (f == 3)
% nin = 120;
%elseif (f == 4)
% nin = 200;
%else
% nin = M;
%end
channel = [channel real(tx_fdm)];
channel_count += M;
rx_fdm = channel(1:nin);
channel = channel(nin+1:channel_count);
channel_count -= nin;
% demodulator
[pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, nin);
[foff_coarse S1 S2] = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, nin);
if coarse_fine == 0
foff = foff_coarse;
end
foff_coarse_log = [foff_coarse_log foff_coarse];
pilot_baseband1_log = [pilot_baseband1_log pilot_baseband1];
pilot_baseband2_log = [pilot_baseband2_log pilot_baseband2];
pilot_lpf1_log = [pilot_lpf1_log pilot_lpf1];
pilot_lpf2_log = [pilot_lpf2_log pilot_lpf2];
S1_log = [S1_log S1];
S2_log = [S2_log S2];
foff_rect = exp(j*2*pi*foff/Fs);
for i=1:nin
foff_phase_rect *= foff_rect';
rx_fdm_fcorr(i) = rx_fdm(i)*foff_phase_rect;
end
rx_baseband = fdm_downconvert(rx_fdm_fcorr, nin);
rx_baseband_log = [rx_baseband_log rx_baseband];
rx_filt = rx_filter(rx_baseband, nin);
rx_filt_log = [rx_filt_log rx_filt];
[rx_symbols rx_timing env] = rx_est_timing(rx_filt, rx_baseband, nin);
env_log = [env_log env];
rx_timing_log = [rx_timing_log rx_timing];
rx_symbols_log = [rx_symbols_log rx_symbols];
next_nin = M;
if rx_timing > 2*M/P
next_nin += M/P;
end
if rx_timing < 0;
next_nin -= M/P;
end
nin_log = [nin_log nin];
[rx_bits sync_bit foff_fine pd] = qpsk_to_bits(prev_rx_symbols, rx_symbols, 'dqpsk');
[sig_est noise_est] = snr_update(sig_est, noise_est, pd);
sig_est_log = [sig_est_log sig_est];
noise_est_log = [noise_est_log noise_est];
prev_rx_symbols = rx_symbols;
rx_bits_log = [rx_bits_log rx_bits];
foff_fine_log = [foff_fine_log foff_fine];
sync_bit_log = [sync_bit_log sync_bit];
foff -= 0.5*foff_fine;
foff_log = [foff_log foff];
% freq est state machine
[coarse_fine fest_state] = freq_state(sync_bit, fest_state);
coarse_fine_log = [coarse_fine_log coarse_fine];
end
% Compare to the output from the C version
load ../unittest/tfdmdv_out.txt
% Helper functions to plot output of C verson and difference between Octave and C versions
function stem_sig_and_error(plotnum, subplotnum, sig, error, titlestr, axisvec)
figure(plotnum)
subplot(subplotnum)
stem(sig);
hold on;
stem(error,'g');
hold off;
if nargin == 6
axis(axisvec);
end
title(titlestr);
endfunction
function plot_sig_and_error(plotnum, subplotnum, sig, error, titlestr, axisvec)
figure(plotnum)
subplot(subplotnum)
plot(sig);
hold on;
plot(error,'g');
hold off;
if nargin == 6
axis(axisvec);
end
title(titlestr);
endfunction
% ---------------------------------------------------------------------------------------
% Plot output and test each C function
% ---------------------------------------------------------------------------------------
% fdmdv_get_test_bits() & bits_to_dqpsk_symbols()
n = 28;
stem_sig_and_error(1, 211, tx_bits_log_c(1:n), tx_bits_log(1:n) - tx_bits_log_c(1:n), 'tx bits', [1 n -1.5 1.5])
stem_sig_and_error(1, 212, real(tx_symbols_log_c(1:n/2)), real(tx_symbols_log(1:n/2) - tx_symbols_log_c(1:n/2)), 'tx symbols real', [1 n/2 -1.5 1.5])
% tx_filter()
diff = tx_baseband_log - tx_baseband_log_c;
c=15;
plot_sig_and_error(2, 211, real(tx_baseband_log_c(c,:)), real(sum(diff)), 'tx baseband real')
plot_sig_and_error(2, 212, imag(tx_baseband_log_c(c,:)), imag(sum(diff)), 'tx baseband imag')
% fdm_upconvert()
plot_sig_and_error(3, 211, real(tx_fdm_log_c), real(tx_fdm_log - tx_fdm_log_c), 'tx fdm real')
plot_sig_and_error(3, 212, imag(tx_fdm_log_c), imag(tx_fdm_log - tx_fdm_log_c), 'tx fdm imag')
% generate_pilot_lut()
plot_sig_and_error(4, 211, real(pilot_lut_c), real(pilot_lut - pilot_lut_c), 'pilot lut real')
plot_sig_and_error(4, 212, imag(pilot_lut_c), imag(pilot_lut - pilot_lut_c), 'pilot lut imag')
% rx_est_freq_offset()
st=1; en = 3*Npilotbaseband;
plot_sig_and_error(5, 211, real(pilot_baseband1_log(st:en)), real(pilot_baseband1_log(st:en) - pilot_baseband1_log_c(st:en)), 'pilot baseband1 real' )
plot_sig_and_error(5, 212, real(pilot_baseband2_log(st:en)), real(pilot_baseband2_log(st:en) - pilot_baseband2_log_c(st:en)), 'pilot baseband2 real' )
st=1; en = 3*Npilotlpf;
plot_sig_and_error(6, 211, real(pilot_lpf1_log(st:en)), real(pilot_lpf1_log(st:en) - pilot_lpf1_log_c(st:en)), 'pilot lpf1 real' )
plot_sig_and_error(6, 212, real(pilot_lpf2_log(st:en)), real(pilot_lpf2_log(st:en) - pilot_lpf2_log_c(st:en)), 'pilot lpf2 real' )
plot_sig_and_error(7, 211, real(S1_log), real(S1_log - S1_log_c), 'S1 real' )
plot_sig_and_error(7, 212, imag(S1_log), imag(S1_log - S1_log_c), 'S1 imag' )
plot_sig_and_error(8, 211, real(S2_log), real(S2_log - S2_log_c), 'S2 real' )
plot_sig_and_error(8, 212, imag(S2_log), imag(S2_log - S2_log_c), 'S2 imag' )
plot_sig_and_error(9, 211, foff_coarse_log, foff_coarse_log - foff_coarse_log_c, 'Coarse Freq Offset' )
plot_sig_and_error(9, 212, foff_fine_log, foff_fine_log - foff_fine_log_c, 'Fine Freq Offset' )
plot_sig_and_error(10, 211, foff_log, foff_log - foff_log_c, 'Freq Offset' )
plot_sig_and_error(10, 212, coarse_fine_log, coarse_fine_log - coarse_fine_log_c, 'Freq Est Coarse(0) Fine(1)', [1 frames -0.5 1.5] )
c=15;
plot_sig_and_error(11, 211, real(rx_baseband_log(c,:)), real(rx_baseband_log(c,:) - rx_baseband_log_c(c,:)), 'Rx baseband real' )
plot_sig_and_error(11, 212, imag(rx_baseband_log(c,:)), imag(rx_baseband_log(c,:) - rx_baseband_log_c(c,:)), 'Rx baseband imag' )
plot_sig_and_error(12, 211, real(rx_filt_log(c,:)), real(rx_filt_log(c,:) - rx_filt_log_c(c,:)), 'Rx filt real' )
plot_sig_and_error(12, 212, imag(rx_filt_log(c,:)), imag(rx_filt_log(c,:) - rx_filt_log_c(c,:)), 'Rx filt imag' )
st=1; en=3*Nt*P;
plot_sig_and_error(13, 211, env_log(st:en), env_log(st:en) - env_log_c(st:en), 'env' )
stem_sig_and_error(13, 212, real(rx_symbols_log(c,:)), real(rx_symbols_log(c,:) - rx_symbols_log_c(c,:)), 'rx symbols' )
st=10*28;
en = 12*28;
plot_sig_and_error(14, 211, rx_timing_log, rx_timing_log - rx_timing_log_c, 'Rx Timing' )
stem_sig_and_error(14, 212, sync_bit_log_c, sync_bit_log - sync_bit_log_c, 'Sync bit', [1 n -1.5 1.5])
stem_sig_and_error(15, 211, rx_bits_log_c(st:en), rx_bits_log(st:en) - rx_bits_log_c(st:en), 'RX bits', [1 en-st -1.5 1.5])
stem_sig_and_error(15, 212, nin_log_c, nin_log - nin_log_c, 'nin')
c = 1;
plot_sig_and_error(16, 211, sig_est_log(c,:), sig_est_log(c,:) - sig_est_log_c(c,:), 'sig est for SNR' )
plot_sig_and_error(16, 212, noise_est_log(c,:), noise_est_log(c,:) - noise_est_log_c(c,:), 'noise est for SNR' )
% ---------------------------------------------------------------------------------------
% AUTOMATED CHECKS ------------------------------------------
% ---------------------------------------------------------------------------------------
function check(a, b, test_name)
global passes;
global fails;
[m n] = size(a);
printf("%s", test_name);
for i=1:(25-length(test_name))
printf(".");
end
printf(": ");
if sum(abs(a - b))/n < 1E-3
printf("OK\n");
passes++;
else
printf("FAIL\n");
fails++;
end
endfunction
check(tx_bits_log, tx_bits_log_c, 'tx_bits');
check(tx_symbols_log, tx_symbols_log_c, 'tx_symbols');
check(tx_baseband_log, tx_baseband_log_c, 'tx_baseband');
check(tx_fdm_log, tx_fdm_log_c, 'tx_fdm');
check(pilot_lut, pilot_lut_c, 'pilot_lut');
check(pilot_baseband1_log, pilot_baseband1_log_c, 'pilot lpf1');
check(pilot_baseband2_log, pilot_baseband2_log_c, 'pilot lpf2');
check(S1_log, S1_log_c, 'S1');
check(S2_log, S2_log_c, 'S2');
check(foff_coarse_log, foff_coarse_log_c, 'foff_coarse');
check(foff_fine_log, foff_fine_log_c, 'foff_fine');
check(foff_log, foff_log_c, 'foff');
check(rx_baseband_log, rx_baseband_log_c, 'rx baseband');
check(rx_filt_log, rx_filt_log_c, 'rx filt');
check(env_log, env_log_c, 'env');
check(rx_timing_log, rx_timing_log_c, 'rx_timing');
check(rx_symbols_log, rx_symbols_log_c, 'rx_symbols');
check(rx_bits_log, rx_bits_log_c, 'rx bits');
check(sync_bit_log, sync_bit_log_c, 'sync bit');
check(coarse_fine_log, coarse_fine_log_c, 'coarse_fine');
check(nin_log, nin_log_c, 'nin');
check(sig_est_log, sig_est_log_c, 'sig_est');
check(noise_est_log, noise_est_log_c, 'noise_est');
printf("\npasses: %d fails: %d\n", passes, fails);

View File

@ -1,49 +0,0 @@
% tget-spec.m
%
% Used in conjunction with src/fdmdv_demod to test the
% fdmdv_get_rx_spectrum() function.
%
% codec2-dev/src$ ./fdmdv_demod fdmdv_mod.raw tmp.c2 dump.txt
% octave:3> tget_spec("../src/dump.txt")
%
% Copyright David Rowe 2012
% This program is distributed under the terms of the GNU General Public License
% Version 2
%
function tfft_log(dumpfilename)
load(dumpfilename);
[rows cols] = size(rx_spec_log_c);
Fs = 8000; low_freq = 0; high_freq = 2500;
res = (Fs/2)/cols;
st_bin = low_freq/res + 1;
en_bin = high_freq/res;
xaxis = (st_bin:en_bin)*res;
f_start = 2; f_end = 100;
beta = 0.1;
av = zeros(f_end, en_bin-st_bin+1);
for r=f_start:f_end
x = (1-beta)*av(r-1,:) + beta*rx_spec_log_c(r,st_bin:en_bin);
av(r,:) = x;
end
% spectrogram (waterfall)
figure(1)
clf;
imagesc(av,[-40 0]);
% animated spectrum display
figure(2)
clf;
for r=f_start:f_end
plot(xaxis, av(r,:))
axis([ low_freq high_freq -40 0])
sleep(0.1)
end
endfunction

View File

@ -1,52 +0,0 @@
% twotone.m
% David Rowe Aug 2012
% Used to experiment with combining phase of two tones
function cbphase
Wo = 100.0*pi/4000;
L = floor(pi/Wo);
phi = zeros(1,L);
% two harmonics
a = 20; b = 21;
% set up phases to whatever
phi(a) = -pi;
phi(b) = -pi/2;
% synthesis the two-tone signal
N = 16000;
Nplot = 250;
s = zeros(1,N);
for m=a:b
s_m = cos(m*Wo*(0:(N-1)) + phi(m));
s = s + s_m;
endfor
% now our theory says that this signal should be the same perceptually
phi_(a) = (phi(a) - phi(b))/2;
phi_(b) = (phi(b) - phi(a))/2;
s_ = zeros(1,N);
for m=a:b
s_m = cos(m*Wo*(0:(N-1)) + phi_(m));
s_ = s_ + s_m;
endfor
% plot them and see if envelope has the same phase, but "carriers"
% have different phase
figure(1);
clf;
subplot(211);
plot(s(1:Nplot));
subplot(212);
plot(s_(1:Nplot),'r');
endfunction

View File

@ -1,76 +0,0 @@
% twotone1.m
% David Rowe Aug 17 2012
%
% Used to experiment with combining phase of two tones. This version
% sets up a complete synthetic speech signal then tries to combine the
% phase of high frequency tones. Lets see if we can do this and keep perceptual
% nature of signal the same.
function twotone1
% hts1a frame 47
Wo = 0.093168;
L = 33;
%A = [69.626907 460.218536 839.677429 2577.498047 972.647888 712.755066 489.048553 364.830536 409.230652 371.767487 489.112854 893.127014 2447.596680 752.878113 475.720520 234.452271 248.161606 232.171051 202.669891 323.914490 678.749451 362.958038 211.652512 170.764435 148.631790 169.261673 272.254150 176.872375 67.344391 99.022301 60.812035 34.319073 14.864757];
A = zeros(1,L)*100;
phi = [1.560274 1.508063 -1.565184 1.289117 -2.547365 1.412528 -1.303992 3.121130 1.087573 -1.158161 -2.928007 0.995093 -2.614023 0.246136 -2.267406 2.143802 -0.273431 -2.266897 1.685171 -0.668712 2.699722 -1.151891 2.406379 -0.046192 -2.718611 0.761067 -2.305014 0.133172 -1.428978 1.492630 -1.668385 1.539734 -1.336615];
%phi = zeros(1,L);
st = floor(L/2);
%st = 1;
A(st:st+5) = 1000;
% now set up phase of signal with phase of upper frequency harmonic
% pairs combined
phi_ = phi;
for m=floor(L/2):2:L
phi_(m) = (phi(m) - phi(m+1))/2;
phi_(m+1) = (phi(m+1) - phi(m))/2;
%phi_(m+1) = 0;
end
% synthesise the signals
N = 16000;
Nplot = 250;
s = zeros(1,N);
for m=st:L
s_m = A(m)*cos(m*Wo*(0:(N-1)) + phi(m));
s = s + s_m;
endfor
s_ = zeros(1,N);
for m=st:L
s_m = A(m)*cos(m*Wo*(0:(N-1)) + phi_(m));
s_ = s_ + s_m;
endfor
% plot them, expect to see similar time domain waveforms
figure(1);
clf;
subplot(211);
plot(s(1:Nplot));
subplot(212);
plot(s_(1:Nplot),'r');
figure(2);
clf;
subplot(211);
plot(s(1:Nplot)-s_(1:Nplot));
% save to disk
gain = 1;
fs=fopen("twotone1_orig.raw","wb");
fwrite(fs,gain*s,"short");
fclose(fs);
fs=fopen("twotone1_comb.raw","wb");
fwrite(fs,gain*s_,"short");
fclose(fs);
endfunction

View File

@ -1,26 +0,0 @@
% undersample.m
% David Rowe 5 Nov 2012
% Testing algorithms for plotting undersampled data for fdmdv2 waveform displays
fs=fopen("../raw/hts1a.raw","rb");
s = fread(fs,Inf,"short");
Fs1=8000;
Fs2=200;
M=Fs1/Fs2;
samples=length(s)/M;
s1=zeros(1,2*samples);
for b=1:samples
st = (b-1)*M + 1;
en = b*M;
s1(2*b-1) = max(s(st:en));
s1(2*b) = min(s(st:en));
end
subplot(211)
plot(s)
subplot(212)
plot(s1);

View File

@ -1,298 +0,0 @@
111.627907
97.959183
97.959183
97.959183
87.272736
78.048775
112.280701
120.000008
61.538464
68.817207
84.210526
90.140846
90.140846
90.140846
101.587303
80.000000
72.727272
95.522392
90.140846
90.140846
101.587303
90.140846
85.333336
86.486488
91.428574
91.428574
91.428574
91.428574
91.428574
90.140846
86.486488
86.486488
85.333336
85.333336
85.333336
81.012657
74.418610
71.111115
71.111115
71.111115
71.111115
68.085106
68.085106
67.368423
67.368423
70.329674
70.329674
70.329674
71.111115
74.418610
74.418610
75.294121
79.012352
85.333336
96.969704
111.627907
111.627907
120.000008
111.627907
104.347832
104.347832
97.959183
104.347832
104.347832
104.347832
104.347832
104.347832
104.347832
104.347832
104.347832
97.959183
97.959183
112.280701
112.280701
96.969704
96.969704
96.969704
110.344841
104.347832
97.959183
97.959183
104.347832
97.959183
104.347832
120.000008
104.347832
120.000008
120.000008
97.959183
83.116882
75.294121
71.910118
71.910110
71.910110
71.910110
75.294121
76.190483
80.000008
80.000008
84.210526
85.333336
90.140846
101.587303
108.474571
104.347832
120.000008
120.000008
104.347832
104.347832
71.111115
88.888893
75.294121
111.627907
120.000008
120.000008
97.959183
111.627907
111.627907
111.627907
97.959183
92.307693
92.307693
92.307693
92.307693
120.000008
111.627907
111.627907
86.486488
85.333336
85.333336
90.140846
95.522392
101.587311
101.587311
104.918037
104.347832
104.347832
111.627907
120.000008
97.959183
104.347832
111.627907
88.888893
80.000000
81.012657
85.333336
85.333336
86.486488
91.428574
90.140846
91.428574
96.969704
96.969704
95.522392
95.522392
95.522392
96.969704
96.969704
98.461533
104.918022
97.959183
97.959183
97.959183
104.347832
120.000008
120.000008
92.307693
92.307693
77.108429
79.012344
75.294121
75.294121
76.190483
76.190483
80.000008
81.012657
85.333336
85.333336
85.333336
85.333336
85.333336
90.140846
90.140846
91.428574
96.969704
98.461533
120.000008
120.000008
104.347832
97.959183
97.959183
104.918037
120.000008
120.000008
120.000008
104.347832
92.307693
72.727272
72.727272
76.190483
84.210533
88.888901
120.000008
104.347832
120.000008
120.000008
111.627907
92.307693
97.959183
97.959183
111.627907
120.000008
120.000008
97.959183
97.959183
104.347832
104.347832
104.347832
111.627907
120.000008
97.959183
104.347832
97.959183
97.959183
84.210526
94.117653
96.969704
110.344841
120.000008
97.959183
97.959183
104.347832
97.959183
104.347832
97.959183
97.959183
111.627907
120.000008
92.307693
92.307693
98.461533
98.461533
104.918022
111.627907
111.627907
92.307693
97.959183
92.307693
92.307693
92.307693
92.307693
92.307693
57.657658
90.140846
90.140846
95.522392
101.587311
101.587311
108.474586
111.627907
97.959183
111.627907
120.000008
92.307693
74.418610
74.418610
74.418610
74.418610
76.190483
72.727280
76.190483
76.190483
69.565224
66.666672
54.700855
56.637169
56.637169
71.910110
90.140846
90.140846
72.727272
72.727272
72.727272
72.727272
55.172413
57.142857
55.172413
90.140846
95.522392
101.587311
101.587311
71.910110
74.418610
46.376812
40.000000
95.522392
0
0

View File

@ -1,300 +0,0 @@
0.0000000e+000
9.2753623e+001
5.4237288e+001
8.5906040e+001
7.0329670e+001
5.5652174e+001
5.4237288e+001
5.4935622e+001
5.4700855e+001
7.5739645e+001
7.3563218e+001
1.2307692e+002
1.1428571e+002
7.3563218e+001
7.7108434e+001
1.8550725e+002
1.2673267e+002
1.0847458e+002
7.8527607e+001
8.8888889e+001
8.3116883e+001
8.1012658e+001
1.0756303e+002
1.3061224e+002
4.8301887e+001
4.7940075e+001
4.8120301e+001
4.9230769e+001
4.9420849e+001
4.6886447e+001
4.2953020e+001
3.9263804e+001
3.7869822e+001
3.5457064e+001
3.4224599e+001
3.3333333e+001
3.2820513e+001
3.2000000e+001
3.1295844e+001
2.9906542e+001
2.9493088e+001
2.9090909e+001
2.8699552e+001
2.8131868e+001
2.7826087e+001
2.7826087e+001
2.7826087e+001
2.8193833e+001
2.7467811e+001
2.6890756e+001
5.4468085e+001
5.4237288e+001
6.4974619e+001
1.0756303e+002
8.8888889e+001
1.0406504e+002
4.4599303e+001
5.4468085e+001
3.6260623e+001
3.6260623e+001
8.1012658e+001
7.0329670e+001
1.2929293e+002
9.9224806e+001
4.3097643e+001
4.4137931e+001
4.5714286e+001
4.7407407e+001
4.8301887e+001
4.9230769e+001
4.9420849e+001
5.0996016e+001
5.1405622e+001
5.1405622e+001
5.2244898e+001
5.2459016e+001
5.2459016e+001
5.2244898e+001
5.3333333e+001
5.2459016e+001
5.2244898e+001
5.1405622e+001
5.1405622e+001
5.1200000e+001
5.0996016e+001
5.0196078e+001
4.9230769e+001
4.9230769e+001
4.9230769e+001
4.9420849e+001
4.9230769e+001
4.9042146e+001
9.8461538e+001
1.0158730e+002
5.1821862e+001
9.0140845e+001
1.0491803e+002
1.4382022e+002
5.2459016e+001
5.2459016e+001
1.2929293e+002
1.6410256e+002
8.0000000e+001
7.3563218e+001
1.0158730e+002
9.9224806e+001
4.9042146e+001
4.9042146e+001
4.9042146e+001
5.9259259e+001
1.4382022e+002
7.2316384e+001
1.0847458e+002
1.1228070e+002
1.6202532e+002
8.1528662e+001
7.2727273e+001
1.8550725e+002
6.0093897e+001
1.0847458e+002
8.9510490e+001
7.1508380e+001
4.0125392e+001
4.0634921e+001
4.0634921e+001
4.0251572e+001
4.0506329e+001
4.3986254e+001
4.0506329e+001
9.8461538e+001
5.6140351e+001
6.5641026e+001
5.4237288e+001
1.1636364e+002
3.4316354e+001
3.4972678e+001
3.7758112e+001
4.0634921e+001
4.0506329e+001
4.1290323e+001
4.2524917e+001
4.3389831e+001
4.4599303e+001
4.4912281e+001
4.6545455e+001
4.7232472e+001
4.8301887e+001
4.9230769e+001
4.9420849e+001
5.0393701e+001
5.1405622e+001
5.3333333e+001
5.3112033e+001
1.1034483e+002
9.7709924e+001
1.4382022e+002
5.0996016e+001
5.1821862e+001
5.0996016e+001
5.2032520e+001
5.3112033e+001
5.3556485e+001
5.4468085e+001
5.5652174e+001
5.4700855e+001
5.4700855e+001
5.4935622e+001
5.4700855e+001
5.4700855e+001
5.4468085e+001
5.4468085e+001
5.4468085e+001
5.4468085e+001
5.3333333e+001
5.1405622e+001
5.0996016e+001
5.0000000e+001
4.8120301e+001
4.8669202e+001
4.7058824e+001
4.6376812e+001
4.5070423e+001
4.4912281e+001
4.4137931e+001
4.2809365e+001
4.2666667e+001
4.2105263e+001
4.1423948e+001
4.1290323e+001
4.1290323e+001
4.1290323e+001
4.0634921e+001
4.0634921e+001
4.0634921e+001
4.0634921e+001
4.0764331e+001
4.1423948e+001
4.2953020e+001
4.5551601e+001
1.7534247e+002
4.7232472e+001
1.3763441e+002
1.3061224e+002
4.5551601e+001
4.3686007e+001
4.8669202e+001
9.4117647e+001
8.1012658e+001
1.1228070e+002
1.3617021e+002
4.3097643e+001
4.3835616e+001
4.6376812e+001
4.6545455e+001
4.6043165e+001
4.8301887e+001
4.9042146e+001
4.9420849e+001
5.1200000e+001
5.1405622e+001
5.2244898e+001
1.2929293e+002
1.2929293e+002
1.5238095e+002
1.5238095e+002
1.3913043e+002
9.0140845e+001
1.0940171e+002
9.0140845e+001
1.2307692e+002
8.9510490e+001
6.9565217e+001
7.3142857e+001
1.1034483e+002
7.8048780e+001
7.2727273e+001
1.0078740e+002
1.0940171e+002
1.1743119e+002
8.7074830e+001
1.8550725e+002
6.5306122e+001
1.3617021e+002
5.2674897e+001
1.0940171e+002
1.5238095e+002
1.4065934e+002
1.0756303e+002
1.0406504e+002
5.0793651e+001
4.9420849e+001
4.4444444e+001
7.0329670e+001
7.2727273e+001
7.4418605e+001
1.1636364e+002
1.0406504e+002
1.2307692e+002
1.2549020e+002
1.7297297e+002
4.5878136e+001
4.9805447e+001
6.2745098e+001
9.2086331e+001
9.1428571e+001
5.7142857e+001
4.8484848e+001
4.1157556e+001
2.2857143e+001
3.0046948e+001
9.4814815e+001
5.7918552e+001
9.0140845e+001
7.4418605e+001
7.4418605e+001
5.4700855e+001
9.5522388e+001
7.4853801e+001
9.4117647e+001
9.5522388e+001
9.9224806e+001
8.1012658e+001
1.1851852e+002
6.8817204e+001
8.5906040e+001
6.7015707e+001
4.3537415e+001
6.5306122e+001
3.1295844e+001
7.5739645e+001
6.2135922e+001
9.9224806e+001
5.7657658e+001
5.2244898e+001
5.8447489e+001
0.0000000e+000
0.0000000e+000
0.0000000e+000
0.0000000e+000
0.0000000e+000

View File

@ -1,23 +0,0 @@
# Makefile for Portaudio test programs
# Requires Portaudio V19
CFLAGS = -g -Wall -I../src
LIBS = -lm -lportaudio -pthread
SRC = ../src/fdmdv.c ../src/kiss_fft.c ../src/fifo.c
all: pa_rec pa_play pa_recplay pa_impresp
pa_rec: Makefile pa_rec.c $(SRC)
gcc $(CFLAGS) pa_rec.c $(SRC) -o pa_rec $(LIBS)
pa_play: Makefile pa_play.c $(SRC)
gcc $(CFLAGS) pa_play.c $(SRC) -o pa_play $(LIBS)
pa_recplay: Makefile pa_recplay.c $(SRC)
gcc $(CFLAGS) pa_recplay.c $(SRC) -o pa_recplay $(LIBS)
pa_impresp: Makefile pa_impresp.c $(SRC)
gcc $(CFLAGS) pa_impresp.c $(SRC) -o pa_impresp $(LIBS)
clean:
rm -f pa_rec pa_play pa_recplay

View File

@ -1,254 +0,0 @@
/*
pa_impresp.c
David Rowe
August 29 2012
Measures the impulse reponse of the path between the speaker and
microphone. Used to explore why Codec audio quality is
different through a speaker and headphones.
Modified from pa_playrec.c
*/
/*
* $Id: paex_record.c 1752 2011-09-08 03:21:55Z philburk $
*
* This program uses the PortAudio Portable Audio Library.
* For more information see: http://www.portaudio.com
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "portaudio.h"
#include "fdmdv.h"
#define SAMPLE_RATE 48000 /* 48 kHz sampling rate rec. as we
can trust accuracy of sound
card */
#define N8 160 /* processing buffer size at 8 kHz */
#define N48 (N8*FDMDV_OS) /* processing buffer size at 48 kHz */
#define MEM8 (FDMDV_OS_TAPS/FDMDV_OS)
#define NUM_CHANNELS 2 /* I think most sound cards prefer
stereo, we will convert to mono
as we sample */
#define IMPULSE_AMP 16384 /* amplitide of impulse */
#define IMPULSE_PERIOD 0.1 /* period (dly between impulses) in secs */
/* state information passed to call back */
typedef struct {
float in48k[FDMDV_OS_TAPS + N48];
float in8k[MEM8 + N8];
FILE *fimp;
float *impulse_buf;
int impulse_buf_length;
int impulse_sample_count;
int framesLeft;
} paTestData;
/*
This routine will be called by the PortAudio engine when audio is
required. It may be called at interrupt level on some machines so
don't do anything that could mess up the system like calling
malloc() or free().
*/
static int callback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
int i;
short *rptr = (short*)inputBuffer;
short *wptr = (short*)outputBuffer;
float *in8k = data->in8k;
float *in48k = data->in48k;
float out8k[N8];
float out48k[N48];
short out48k_short[N48];
short out8k_short[N8];
(void) timeInfo;
(void) statusFlags;
assert(inputBuffer != NULL);
/* just use left channel */
for(i=0; i<framesPerBuffer; i++,rptr+=2)
data->in48k[i+FDMDV_OS_TAPS] = *rptr;
/* downsample and update filter memory */
fdmdv_48_to_8(out8k, &in48k[FDMDV_OS_TAPS], N8);
for(i=0; i<FDMDV_OS_TAPS; i++)
in48k[i] = in48k[i+framesPerBuffer];
/* write impulse response to disk */
for(i=0; i<N8; i++)
out8k_short[i] = out8k[i];
fwrite(out8k_short, sizeof(short), N8, data->fimp);
/* play side, read from impulse buffer */
for(i=0; i<N8; i++) {
in8k[MEM8+i] = data->impulse_buf[data->impulse_sample_count];
data->impulse_sample_count++;
if (data->impulse_sample_count == data->impulse_buf_length)
data->impulse_sample_count = 0;
}
/* upsample and update filter memory */
fdmdv_8_to_48(out48k, &in8k[MEM8], N8);
for(i=0; i<MEM8; i++)
in8k[i] = in8k[i+N8];
assert(outputBuffer != NULL);
/* write signal to both channels */
for(i=0; i<N48; i++)
out48k_short[i] = (short)out48k[i];
for(i=0; i<framesPerBuffer; i++,wptr+=2) {
wptr[0] = out48k_short[i];
wptr[1] = out48k_short[i];
}
data->framesLeft -= framesPerBuffer;
if (data->framesLeft > 0)
return paContinue;
else
return paComplete;
}
int main(int argc, char *argv[])
{
PaStreamParameters inputParameters, outputParameters;
PaStream* stream;
PaError err = paNoError;
paTestData data;
int i, numSecs;
if (argc != 3) {
printf("usage: %s impulseRawFile time(s)\n", argv[0]);
exit(0);
}
data.fimp = fopen(argv[1], "wb");
if (data.fimp == NULL) {
printf("Error opening impulse output file %s\n", argv[1]);
exit(1);
}
numSecs = atoi(argv[2]);
data.framesLeft = numSecs * SAMPLE_RATE;
/* init filter states */
for(i=0; i<MEM8; i++)
data.in8k[i] = 0.0;
for(i=0; i<FDMDV_OS_TAPS; i++)
data.in48k[i] = 0.0;
/* init imupulse */
data.impulse_buf_length = IMPULSE_PERIOD*(SAMPLE_RATE/FDMDV_OS);
printf("%d\n",data.impulse_buf_length);
data.impulse_buf = (float*)malloc(data.impulse_buf_length*sizeof(float));
assert(data.impulse_buf != NULL);
data.impulse_buf[0] = IMPULSE_AMP;
for(i=1; i<data.impulse_buf_length; i++)
data.impulse_buf[i] = 0;
data.impulse_sample_count = 0;
err = Pa_Initialize();
if( err != paNoError ) goto done;
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
if (inputParameters.device == paNoDevice) {
fprintf(stderr,"Error: No default input device.\n");
goto done;
}
inputParameters.channelCount = NUM_CHANNELS; /* stereo input */
inputParameters.sampleFormat = paInt16;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
if (outputParameters.device == paNoDevice) {
fprintf(stderr,"Error: No default output device.\n");
goto done;
}
outputParameters.channelCount = NUM_CHANNELS; /* stereo output */
outputParameters.sampleFormat = paInt16;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
/* Play some audio --------------------------------------------- */
err = Pa_OpenStream(
&stream,
&inputParameters,
&outputParameters,
SAMPLE_RATE,
N48,
paClipOff,
callback,
&data );
if( err != paNoError ) goto done;
err = Pa_StartStream( stream );
if( err != paNoError ) goto done;
while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
{
Pa_Sleep(100);
}
if( err < 0 ) goto done;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto done;
done:
Pa_Terminate();
if( err != paNoError )
{
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
err = 1; /* Always return 0 or 1, but no other return codes. */
}
fclose(data.fimp);
return err;
}

View File

@ -1,199 +0,0 @@
/*
pa_play.c
David Rowe
July 8 2012
Converts samples from a 16 bit short 8000 Hz rawfile to 480000Hz
sample rate and plays them using the default sound device. Used as
an intermediate step in Portaudio integration.
Modified from paex_record.c Portaudio example. Original author
author Phil Burk http://www.softsynth.com
*/
/*
* $Id: paex_record.c 1752 2011-09-08 03:21:55Z philburk $
*
* This program uses the PortAudio Portable Audio Library.
* For more information see: http://www.portaudio.com
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "portaudio.h"
#include "fdmdv.h"
#define SAMPLE_RATE 48000 /* 48 kHz sampling rate rec. as we
can trust accuracy of sound
card */
#define N8 160 /* processing buffer size at 8 kHz */
#define N48 (N8*FDMDV_OS) /* processing buffer size at 48 kHz */
#define MEM8 (FDMDV_OS_TAPS/FDMDV_OS)
#define NUM_CHANNELS 2 /* I think most sound cards prefer
stereo, we will convert to mono
as we sample */
/* state information passed to call back */
typedef struct {
FILE *fin;
float in8k[MEM8 + N8];
} paTestData;
/*
This routine will be called by the PortAudio engine when audio is
required. It may be called at interrupt level on some machines so
don't do anything that could mess up the system like calling
malloc() or free().
*/
static int playCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
FILE *fin = data->fin;
int i, nread;
int finished;
short *wptr = (short*)outputBuffer;
float *in8k = data->in8k;
float out48k[N48];
short out48k_short[N48];
short in8k_short[N8];
(void) outputBuffer; /* Prevent unused variable warnings. */
(void) timeInfo;
(void) statusFlags;
(void) userData;
/* note Portaudio docs recs. against making systems calls like
fwrite() in this callback but seems to work OK */
nread = fread(in8k_short, sizeof(short), N8, fin);
if (nread == N8)
finished = paContinue;
else
finished = paComplete;
for(i=0; i<N8; i++)
in8k[MEM8+i] = in8k_short[i];
/* upsample and update filter memory */
fdmdv_8_to_48(out48k, &in8k[MEM8], N8);
for(i=0; i<MEM8; i++)
in8k[i] = in8k[i+N8];
assert(outputBuffer != NULL);
/* write signal to both channels */
for(i=0; i<N48; i++)
out48k_short[i] = (short)out48k[i];
for(i=0; i<framesPerBuffer; i++,wptr+=2) {
wptr[0] = out48k_short[i];
wptr[1] = out48k_short[i];
}
return finished;
}
int main(int argc, char *argv[])
{
PaStreamParameters outputParameters;
PaStream* stream;
PaError err = paNoError;
paTestData data;
int i;
if (argc != 2) {
printf("usage: %s rawFile\n", argv[0]);
exit(0);
}
data.fin = fopen(argv[1], "rt");
if (data.fin == NULL) {
printf("Error opening input raw file %s\n", argv[1]);
exit(1);
}
for(i=0; i<MEM8; i++)
data.in8k[i] = 0.0;
err = Pa_Initialize();
if( err != paNoError ) goto done;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default input device */
if (outputParameters.device == paNoDevice) {
fprintf(stderr,"Error: No default output device.\n");
goto done;
}
outputParameters.channelCount = NUM_CHANNELS; /* stereo input */
outputParameters.sampleFormat = paInt16;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
/* Play some audio --------------------------------------------- */
err = Pa_OpenStream(
&stream,
NULL,
&outputParameters,
SAMPLE_RATE,
N48,
paClipOff,
playCallback,
&data );
if( err != paNoError ) goto done;
err = Pa_StartStream( stream );
if( err != paNoError ) goto done;
while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
{
Pa_Sleep(100);
}
if( err < 0 ) goto done;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto done;
fclose(data.fin);
done:
Pa_Terminate();
if( err != paNoError )
{
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
err = 1; /* Always return 0 or 1, but no other return codes. */
}
return err;
}

View File

@ -1,212 +0,0 @@
/*
pa_rec.c
David Rowe
July 6 2012
Records at 48000 Hz from default sound device, convertes to 8 kHz,
and saves to raw file. Used to get experience with Portaudio.
Modified from paex_record.c Portaudio example. Original author
author Phil Burk http://www.softsynth.com
To Build:
gcc paex_rec.c -o paex_rec -lm -lrt -lportaudio -pthread
*/
/*
* $Id: paex_record.c 1752 2011-09-08 03:21:55Z philburk $
*
* This program uses the PortAudio Portable Audio Library.
* For more information see: http://www.portaudio.com
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "portaudio.h"
#include "fdmdv.h"
#define SAMPLE_RATE 48000 /* 48 kHz sampling rate rec. as we
can trust accuracy of sound
card */
#define N8 160 /* processing buffer size at 8 kHz */
#define N48 (N8*FDMDV_OS) /* processing buffer size at 48 kHz */
#define NUM_CHANNELS 2 /* I think most sound cards prefer
stereo, we will convert to mono
as we sample */
/* state information passed to call back */
typedef struct {
FILE *fout;
int framesLeft;
float in48k[FDMDV_OS_TAPS + N48];
} paTestData;
/*
This routine will be called by the PortAudio engine when audio is
available. It may be called at interrupt level on some machines so
don't do anything that could mess up the system like calling
malloc() or free().
*/
static int recordCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
FILE *fout = data->fout;
int framesToCopy;
int i;
int finished;
short *rptr = (short*)inputBuffer;
float out8k[N8];
short out8k_short[N8];
(void) outputBuffer; /* Prevent unused variable warnings. */
(void) timeInfo;
(void) statusFlags;
(void) userData;
if (data->framesLeft < framesPerBuffer) {
framesToCopy = data->framesLeft;
finished = paComplete;
}
else {
framesToCopy = framesPerBuffer;
finished = paContinue;
}
data->framesLeft -= framesToCopy;
assert(inputBuffer != NULL);
/* just use left channel */
for(i=0; i<framesToCopy; i++,rptr+=2)
data->in48k[i+FDMDV_OS_TAPS] = *rptr;
/* downsample and update filter memory */
fdmdv_48_to_8(out8k, &data->in48k[FDMDV_OS_TAPS], N8);
for(i=0; i<FDMDV_OS_TAPS; i++)
data->in48k[i] = data->in48k[i+framesToCopy];
/* save 8k to disk */
for(i=0; i<N8; i++)
out8k_short[i] = (short)out8k[i];
/* note Portaudio docs recs. against making systems calls like
fwrite() in this callback but seems to work OK */
fwrite(out8k_short, sizeof(short), N8, fout);
return finished;
}
int main(int argc, char *argv[])
{
PaStreamParameters inputParameters;
PaStream* stream;
PaError err = paNoError;
paTestData data;
int i;
int numSecs;
if (argc != 3) {
printf("usage: %s rawFile time(s)\n", argv[0]);
exit(0);
}
data.fout = fopen(argv[1], "wt");
if (data.fout == NULL) {
printf("Error opening output raw file %s\n", argv[1]);
exit(1);
}
numSecs = atoi(argv[2]);
data.framesLeft = numSecs * SAMPLE_RATE;
for(i=0; i<FDMDV_OS_TAPS; i++)
data.in48k[i] = 0.0;
err = Pa_Initialize();
if( err != paNoError ) goto done;
printf( "PortAudio version number = %d\nPortAudio version text = '%s'\n",
Pa_GetVersion(), Pa_GetVersionText() );
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
if (inputParameters.device == paNoDevice) {
fprintf(stderr,"Error: No default input device.\n");
goto done;
}
inputParameters.channelCount = NUM_CHANNELS; /* stereo input */
inputParameters.sampleFormat = paInt16;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
/* Record some audio --------------------------------------------- */
err = Pa_OpenStream(
&stream,
&inputParameters,
NULL, /* &outputParameters, */
SAMPLE_RATE,
N48,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
recordCallback,
&data );
if( err != paNoError ) goto done;
err = Pa_StartStream( stream );
if( err != paNoError ) goto done;
while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
{
Pa_Sleep(100);
}
if( err < 0 ) goto done;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto done;
fclose(data.fout);
done:
Pa_Terminate();
if( err != paNoError )
{
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
err = 1; /* Always return 0 or 1, but no other return codes. */
}
return err;
}

View File

@ -1,270 +0,0 @@
/*
pa_recplay.c
David Rowe
July 8 2012
Echos audio from sound card input to sound card output. Samples at
48 kHz, converts to 8 kHz, converts back to 48kHz, and plays using
the default sound device. Used as an intermediate step in
Portaudio integration.
Modified from paex_record.c Portaudio example. Original author
author Phil Burk http://www.softsynth.com
*/
/*
* $Id: paex_record.c 1752 2011-09-08 03:21:55Z philburk $
*
* This program uses the PortAudio Portable Audio Library.
* For more information see: http://www.portaudio.com
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "portaudio.h"
#include "fdmdv.h"
#include "fifo.h"
#define SAMPLE_RATE 48000 /* 48 kHz sampling rate rec. as we
can trust accuracy of sound
card */
#define N8 160 /* processing buffer size at 8 kHz */
#define N48 (N8*FDMDV_OS) /* processing buffer size at 48 kHz */
#define MEM8 (FDMDV_OS_TAPS/FDMDV_OS)
#define NUM_CHANNELS 2 /* I think most sound cards prefer
stereo, we will convert to mono
as we sample */
#define MAX_FPB 2048 /* maximum value of framesPerBuffer */
/* state information passed to call back */
typedef struct {
float in48k[FDMDV_OS_TAPS + N48];
float in8k[MEM8 + N8];
struct FIFO *infifo;
struct FIFO *outfifo;
} paTestData;
/*
This routine will be called by the PortAudio engine when audio is
required. It may be called at interrupt level on some machines so
don't do anything that could mess up the system like calling
malloc() or free().
*/
static int callback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
int i;
short *rptr = (short*)inputBuffer;
short *wptr = (short*)outputBuffer;
float *in8k = data->in8k;
float *in48k = data->in48k;
float out8k[N8];
float out48k[N48];
short out48k_short[N48];
short in48k_short[N48];
short indata[MAX_FPB];
short outdata[MAX_FPB];
(void) timeInfo;
(void) statusFlags;
assert(inputBuffer != NULL);
assert(outputBuffer != NULL);
/*
framesPerBuffer is portaudio-speak for number of samples we
actually get from the record side and need to provide to the
play side. On Linux (at least) it was found that
framesPerBuffer may not always be what we ask for in the
framesPerBuffer field of Pa_OpenStream. For example a request
for 960 sample buffers lead to framesPerBuffer = 1024.
To perform the 48 to 8 kHz conversion we need an integer
multiple of FDMDV_OS samples to support the interpolation and
decimation. As we can't guarantee the size of framesPerBuffer
we do a little FIFO buffering.
*/
//printf("framesPerBuffer: %d N48 %d\n", framesPerBuffer, N48);
/* assemble a mono buffer (just use left channel) and write to FIFO */
assert(framesPerBuffer < MAX_FPB);
for(i=0; i<framesPerBuffer; i++,rptr+=2)
indata[i] = *rptr;
fifo_write(data->infifo, indata, framesPerBuffer);
/* while we have enough samples available ... */
//printf("infifo before: %d\n", fifo_n(data->infifo));
while (fifo_read(data->infifo, in48k_short, N48) == 0) {
/* convert to float */
for(i=0; i<N48; i++)
in48k[FDMDV_OS_TAPS + i] = in48k_short[i];
/* downsample and update filter memory */
fdmdv_48_to_8(out8k, &in48k[FDMDV_OS_TAPS], N8);
for(i=0; i<FDMDV_OS_TAPS; i++)
in48k[i] = in48k[i+N48];
/* play side, back up to 8k */
for(i=0; i<N8; i++)
in8k[MEM8+i] = out8k[i];
/* upsample and update filter memory */
fdmdv_8_to_48(out48k, &in8k[MEM8], N8);
for(i=0; i<MEM8; i++)
in8k[i] = in8k[i+N8];
/* write signal to both channels */
for(i=0; i<N48; i++)
out48k_short[i] = (short)out48k[i];
fifo_write(data->outfifo, out48k_short, N48);
}
//printf("infifo after: %d\n", fifo_n(data->infifo));
//printf("outfifo : %d\n", fifo_n(data->outfifo));
/* OK now set up output samples */
if (fifo_read(data->outfifo, outdata, framesPerBuffer) == 0) {
/* write signal to both channels */
for(i=0; i<framesPerBuffer; i++,wptr+=2) {
wptr[0] = outdata[i];
wptr[1] = outdata[i];
}
}
else {
//printf("no data\n");
/* zero output if no data available */
for(i=0; i<framesPerBuffer; i++,wptr+=2) {
wptr[0] = 0;
wptr[1] = 0;
}
}
return paContinue;
}
int main(int argc, char *argv[])
{
PaStreamParameters inputParameters, outputParameters;
PaStream* stream;
PaError err = paNoError;
paTestData data;
int i;
/* init callback data */
for(i=0; i<MEM8; i++)
data.in8k[i] = 0.0;
for(i=0; i<FDMDV_OS_TAPS; i++)
data.in48k[i] = 0.0;
data.infifo = fifo_create(2*N48);
data.outfifo = fifo_create(2*N48);
/* init port audio */
err = Pa_Initialize();
if( err != paNoError ) goto done;
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
if (inputParameters.device == paNoDevice) {
fprintf(stderr,"Error: No default input device.\n");
goto done;
}
inputParameters.channelCount = NUM_CHANNELS; /* stereo input */
inputParameters.sampleFormat = paInt16;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
if (outputParameters.device == paNoDevice) {
fprintf(stderr,"Error: No default output device.\n");
goto done;
}
outputParameters.channelCount = NUM_CHANNELS; /* stereo output */
outputParameters.sampleFormat = paInt16;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
/* Play some audio --------------------------------------------- */
err = Pa_OpenStream(
&stream,
&inputParameters,
&outputParameters,
SAMPLE_RATE,
512,
paClipOff,
callback,
&data );
if( err != paNoError ) goto done;
err = Pa_StartStream( stream );
if( err != paNoError ) goto done;
while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
{
Pa_Sleep(100);
}
if( err < 0 ) goto done;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto done;
done:
Pa_Terminate();
if( err != paNoError )
{
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
err = 1; /* Always return 0 or 1, but no other return codes. */
}
fifo_destroy(data.infifo);
fifo_destroy(data.outfifo);
return err;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More