From 03d7886528a6670244f9cdf7608dea3c46de129d Mon Sep 17 00:00:00 2001 From: Rich E Date: Fri, 18 Jan 2008 20:27:28 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r9151, which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/reakin/sdiflists/; revision=9152 --- GnuGPL.txt | 340 ++++++++++++++++++++++ README | 61 ++++ loris.STYP | 107 +++++++ makefile | 52 ++++ sdiflists-help.pd | 96 +++++++ sdiflists.c | 748 +++++++++++++++++++++++++++++++++++++++++++++++++ sdiftostring.h | 13 + test/meowLoris.sdif | Bin 0 -> 402120 bytes test/orgue.sdif | Bin 0 -> 1016 bytes test/pianoSpear.sdif | Bin 0 -> 136928 bytes test/richiepooSMS.sdif | Bin 0 -> 253136 bytes 11 files changed, 1417 insertions(+) create mode 100644 GnuGPL.txt create mode 100644 README create mode 100644 loris.STYP create mode 100644 makefile create mode 100644 sdiflists-help.pd create mode 100644 sdiflists.c create mode 100644 sdiftostring.h create mode 100644 test/meowLoris.sdif create mode 100644 test/orgue.sdif create mode 100644 test/pianoSpear.sdif create mode 100644 test/richiepooSMS.sdif diff --git a/GnuGPL.txt b/GnuGPL.txt new file mode 100644 index 0000000..d60c31a --- /dev/null +++ b/GnuGPL.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +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 give any other recipients of the Program a copy of this License +along with the Program. + +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 Program or any portion +of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +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 Program, 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 Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) 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; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, 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 executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or 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 counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program 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. + + 5. 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 Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. 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 Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program 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 Program. + +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. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program 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. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 Program +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 Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, 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 + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), 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 Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/README b/README new file mode 100644 index 0000000..a12fe42 --- /dev/null +++ b/README @@ -0,0 +1,61 @@ +~~~~~~~~~~~~~~~~~ [sdiflists] v0.1 - ~~~~~~~~~~~~~~~~~~~~~ +date: Jan 17, 2008 +author: Richie Eakin +email: reakinator@gmail.com +homepage: www.teafordragons.com/rte + +PURPOSE: +This is an external for the computer music application Pure Data. +Its purpose is to allow the use of SDIF analysis data within pd. +SDIF is a file format for data exchange between programs, you +can find more info about it at http://www.ircam.fr/sdif or +http://archive.cnmat.berkeley.edu/SDIF/ . I specifically use it +for resynthesizing sinusoidal tracks in pd... look for Trax on my +webpage to get all the components for that. + +INSTALL: +You first need to download and install Ircam's SDIF library. There are +many different versions to be found on the net, I am using the latest +Sourceforge version found at http://sourceforge.net/projects/sdif. Last +time I tried, I could not get it to compile on windows, so if you want this +on that platform you have to get it to compile and adjust the makefile. + +in this directory do + (for linux) + make pd_linux +or (for mac) + make pd_darwin + +HOW TO USE: +[sdiflists] will only handle one stream per sdif file; if you do not declare +which stream you want you will get the first in the file by default. All +matrices within that frame will be available for output. The number of +outlets is declared as an argument to the externals, e.g. [sdiflists 6] +would make 6 outlets that output analysis data, one for each column. +So if you have 2 matrices of 4 columns each, you will get all of the first +matrix and the first 2 columns of the second. There is also an outlet +for time and for info such as 1NVT tables and other useful things. +For syntax detais, see sdiflists-help.pd. + +BUGS or SUGGESTIONS: +There are a couple known bugs (you may notice warnings of the +wrong frametype in the terminal, haven't figured out why yet) and +a couple work-arounds in the code. But please let me know what +you find when using this external, if you can fix it then great. As I +mentioned above, so far I only use this external for sinusoidal +synthesis so I do not know if frametypes other than 1TRC or +1STF will cause problems. I have tried to check, but.. you know. + +TODO: +- make an external for writing sdif files.. hopefully people have +suggestions for doing this because it is a little trickier than +outputting lists like [sdiflists] + +THANKYOUS: +Thanks to Tom Erbe for all the programming tips throughout my +stay at UCSD. Thanks to Miller Puckette for helping me figure +out the odds and ends of Pd. Thanks to Shlomo Dubnov for +introducing me to and sharing knowledge about Sound Descr- +tors. Finally thanks to those on the SDIF and Pd mailing lists +for helping cure me of ignorance. Sorry though, still a long way +to go! \ No newline at end of file diff --git a/loris.STYP b/loris.STYP new file mode 100644 index 0000000..22bee49 --- /dev/null +++ b/loris.STYP @@ -0,0 +1,107 @@ + +SDIF + +1NVT +{ + GenerationDate Thu_22_Jun_2006; + GenerationUser Richie_Eakin; + Generator modified_from_SdifTypes.STYP; + SourceFile SdifTypes.STYP + Application Loris_Sound_Modeling_Package + Author Kelly_Fitz +} + +1TYP +{ +1MTD 1NVT { NVTText } +1MTD 1TYP { TYPText } +1MTD 1IDS { IDSText } +1FTD 1NVT { 1NVT NameValueTable; } +1FTD 1TYP { 1TYP TypeDefinitions; } +1FTD 1IDS { 1IDS StreamInfo; } + +1MTD 1GAI { Gain } +1FTD 1GAI { 1GAI Gain; } +1MTD IWIN { WindowIdentifier, WindowSize } +1MTD 1WIN { Samples } +1FTD 1WIN { IWIN WindowInfo; 1WIN Window; } +1MTD 1CHA { Channel1, Channel2 } + +1MTD 1FQ0 { Frequency, Confidence, Score, RealAmplitude } +1FTD 1FQ0 { 1FQ0 FundamentalFrequencyEstimate; } + +1MTD 1PIC { Frequency, Amplitude, Phase, Confidence } +1MTD 1TRC { Index, Frequency, Amplitude, Phase } +1MTD 1HRM { Index, Frequency, Amplitude, Phase } +1FTD 1PIC { 1PIC PickedPeaks; } +1FTD 1TRC { 1TRC SinusoidalTracks; } +1FTD 1HRM { 1HRM HarmonicPartials; } +1MTD 1HRE { MeanDeltaFrequency, Harmonicity, WeightedHarmonicity } +1FTD 1HRE { 1HRE HarmonicityEstimate; } + +1MTD IENV { HighestBinFrequency, ScaleType, BreakFrequency } +1MTD 1ENV { Env } +1FTD 1ENV { IENV SpectralEnvelopeInfo; 1ENV SpectralEnvelope; 1GAI Gain; } +1MTD ITFC { SamplingRate, Order } +1MTD 1CEC { CepstralCoefficients } +1FTD 1CEC { 1CEC CepstralCoefs; } +1MTD 1ARA { AutoRegressiveCoefficients } +1MTD 1ARK { ReflectionCoefficients } +1MTD 1ARR { AutoCorrelationCoefficients } +1FTD 1ARA { 1GAI Gain; 1ARA ARACoefs; } +1FTD 1ARK { 1GAI Gain; 1ARK ARKCoefs; } +1FTD 1ARR { 1ARR ARRCoefs; } + +1MTD 1FOF { Frequency, Amplitude, BandWidth, Tex, DebAtt, Atten, Phase } +1MTD 2RES { Frequency, Amplitude, DecayRate, Phase } +1MTD 1RES { Frequency, Amplitude, BandWidth, Saliance, Correction } +1MTD 1DIS { Distribution, Amplitude } +1FTD 1NOI { 1DIS NoiseDistribution; } +1FTD 1FOB { 1FQ0 FundamentalFrequencyEstimate; 1FOF Formants; 1CHA Channels; } +1FTD 1REB { 1RES Filters; 1CHA Channels; } + +1MTD ISTF { DFTPeriod, WindowDuration, FFTSize } +1MTD 1STF { Real, Imaginary } +1FTD ISTF { ISTF FourierTransformInfo; } +1FTD 1STF { ISTF FourierTransformInfo; 1STF FourierTransform; 1WIN Window; } + +1MTD INRG { Scale, NormalisationFactor } +1MTD 1NRG { Energy } +1FTD 1NRG { INRG ScaleAndFactor; 1NRG Energy; IWIN WindowInfo; 1WIN Window; } +1MTD 1BND { LowerFrequencyLimit, UpperFrequencyLimit } +1FTD 1BND { 1BND Bands; } + +1MTD ITDS { SamplingRate } +1MTD 1TDS { Sample } + +1MTD 1PEM { Identifier, Parameter1, Parameter2, Parameter3 } +1MTD ITMR { Index, Frequency, Amplitude, Phase } +1MTD ITMI { Index } +1MTD 1BEG { Id } +1MTD 1END { Id } +1MTD 1SEG { Confidence } +1FTD 1SEG { 1SEG Segmentation; } +1MTD 1LAB { Chars } +1FTD 1MRK { 1BEG SegmentStart; 1END SegmentEnd; 1SEG Segmentation; 1LAB Label; 1PEM PeriodMarker; ITMR TransientMarkerRepresentation; ITMI TransientMarkerIdentifier; } + +1MTD 1VUN { VoicingCoefficient } +1MTD 1VUF { CuttingFrequency } +1FTD 1VUV { 1VUN VoicedUnvoicedNorm; 1VUF VoicedUnvoicedFreq; } + +1MTD 1MID { Status, Data1, Data2 } +1MTD 1SYX { Data } +1FTD 1MID { 1MID MIDIEvent; 1SYX MIDISystemExclusive; } + +1MTD EMPM { Value, Index } +1MTD EMJR { Record } +1FTD EFPM { EMPM Tableau; EMJR EndRecording; } + +1MTD RBEP { Index, frequency, amplitude, phase, noise, timeOffset } +1FTD RBEP { RBEP Reassigned_Bandwidth_Enhanced_Partials; } +1MTD RBEL { Index, label } +1FTD RBEL { RBEL Reassigned_Bandwidth_Enhanced_Labels; } +1MTD RBET { marker_times } +1MTD RBEN { marker_names } +1FTD RBEM { RBET marker_times; RBEN marker_names; } +} + diff --git a/makefile b/makefile new file mode 100644 index 0000000..c0638cd --- /dev/null +++ b/makefile @@ -0,0 +1,52 @@ +# ----------Pd-Sdif makefile, using the makefile-------------- +# ---------from example Pd externals-------------------------- +# *** Make sure the pd header files and sdif library can +# *** be found by including the right directory +# - this external will probably work on windows if you can +# get the SDIF IRCAM library installed, but I couldn't +# use the pd/doc/6.extern/makefile and link with -lsdif + +current: + echo make pd_linux + +clean: ; rm -f *.pd_linux *.o + + +# ----------------------- LINUX i386 ----------------------- + +pd_linux: sdiflists.pd_linux + + + +.SUFFIXES: .pd_linux + +LINUXCFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer \ + -Wall -W -Wshadow -Wstrict-prototypes -Werror \ + -Wno-unused -Wno-parentheses -Wno-switch + +LINUXINCLUDE = -I /usr/local/include + + +.c.pd_linux: + cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c + ld -lsdif -export_dynamic -shared -o $*.pd_linux $*.o -lc -lm + strip --strip-unneeded $*.pd_linux + rm $*.o + + +# ----------------------- Mac OSX ----------------------- + +pd_darwin: sdiflists.pd_darwin + +.SUFFIXES: .pd_darwin + +DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \ + -Wno-unused -Wno-parentheses -Wno-switch + +DARWIN_INCLUDE = -I /usr/local/include + +.c.pd_darwin: + cc $(DARWINCFLAGS) $(DARWIN_INCLUDE) -o $*.o -c $*.c + cc -bundle -undefined suppress -lsdif -flat_namespace -o $*.pd_darwin $*.o + rm -f $*.o + diff --git a/sdiflists-help.pd b/sdiflists-help.pd new file mode 100644 index 0000000..7e326e2 --- /dev/null +++ b/sdiflists-help.pd @@ -0,0 +1,96 @@ +#N canvas 33 413 1015 502 10; +#X floatatom 389 469 8 0 0 0 - - -; +#X floatatom 486 314 5 0 0 0 - - -; +#X obj 450 443 list trim; +#X msg 486 161 info; +#X msg 486 195 types loris.STYP; +#X obj 332 420 sdiflists 4; +#X obj 487 291 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 +-1 -1; +#X msg 486 351 time \$1; +#X floatatom 487 334 5 0 0 0 - - -; +#N canvas 0 0 450 300 printcols 0; +#X obj 38 46 inlet; +#X obj 38 120 spigot; +#X obj 38 142 print COLUMN-1; +#X obj 98 96 inlet; +#X obj 98 170 spigot; +#X obj 168 46 inlet; +#X obj 168 120 spigot; +#X obj 228 96 inlet; +#X obj 228 170 spigot; +#X obj 98 192 print COLUMN-2; +#X obj 168 142 print COLUMN-3; +#X obj 228 192 print COLUMN-4; +#X obj 324 42 inlet; +#X connect 0 0 1 0; +#X connect 1 0 2 0; +#X connect 3 0 4 0; +#X connect 4 0 9 0; +#X connect 5 0 6 0; +#X connect 6 0 10 0; +#X connect 7 0 8 0; +#X connect 8 0 11 0; +#X connect 12 0 1 1; +#X connect 12 0 4 1; +#X connect 12 0 6 1; +#X connect 12 0 8 1; +#X restore 296 467 pd printcols; +#X obj 375 449 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 +1; +#X msg 486 255 about; +#X text 609 191 Specify a custom types definition file; +#X text 647 206 (ex. Loris's RBEP format); +#X text 524 156 sends info out the rightmost outlet in list tuples +; +#X text 524 168 Info also sends out 1NVT and 1IDS data; +#X obj 450 467 print INFO_OUTLET; +#X msg 486 113 open 2 test/richiepooSMS.sdif; +#X msg 486 375 timerange 0.009; +#X text 488 396 default timerange = 0.01; +#X text 532 255 nothing really important here; +#X obj 19 27 cnv 15 204 45 empty empty [sdiflists] 20 22 0 14 -62784 +-241291 0; +#X text 226 30 v.01; +#X text 226 50 Author: Richie Eakin; +#X text 16 99 this external uses the SDIF IRCAM library to read sdif +files and output the matrices in the form of one lists per column. +Only one stream can be read per external \, use more if you need to. +The number of columns of all the combines matrices should be specified +at creation time. The SDIF specification is very open \, but you have +to use frame and matrix types that are declared in the standard library +(found at www.ircam.fr/sdif) or with the inclusion of you own *.STYP +file. I have included one that defines Loris' RBEP filetype \, along +with the rest of the standard definitions.; +#X msg 486 54 open test/pianoSpear.sdif; +#X text 485 77 If you don't want the first stream in the file \, specify +the number of the stream you want BEFORE the filename.; +#X text 485 31 open a .sdif file first.; +#X msg 486 138 open test/orgue.sdif; +#X text 635 137 (this file has a 1NVT table); +#X msg 486 229 open 1 test/meowLoris.sdif; +#X text 677 232 RBEP is in stream 1; +#X text 518 287 bang outputs the next frame in time; +#X text 533 312 float outputs a specific frame; +#X text 546 349 use timestamp instead of frame number; +#X text 601 375 specify the time range (use with time message); +#X connect 1 0 5 0; +#X connect 2 0 16 0; +#X connect 3 0 5 0; +#X connect 4 0 5 0; +#X connect 5 0 9 0; +#X connect 5 1 9 1; +#X connect 5 2 9 2; +#X connect 5 3 9 3; +#X connect 5 4 0 0; +#X connect 5 5 2 0; +#X connect 6 0 5 0; +#X connect 7 0 5 0; +#X connect 8 0 7 0; +#X connect 10 0 9 4; +#X connect 11 0 5 0; +#X connect 17 0 5 0; +#X connect 18 0 5 0; +#X connect 25 0 5 0; +#X connect 28 0 5 0; +#X connect 30 0 5 0; diff --git a/sdiflists.c b/sdiflists.c new file mode 100644 index 0000000..cb71356 --- /dev/null +++ b/sdiflists.c @@ -0,0 +1,748 @@ + +/*------------------------------sdiflists-----------------------------/ + --------------------------------------------------------------------- + An external object for Pure Data that reads SDIF files, with the help + of IRCAM's SDIF library. + -written by Richie Eakin.. See the readme for more documentation. + reakinator@gmail.com +*/ + +#define IFRAMES 1000 +#define MAX_STREAMS 1000 +#define DATE "17/1/08" +#define DEBUG 0 +#define DEBUG_MEM 0 + +#include "m_pd.h" +#include "sdiftostring.h" +#include +#include +#include +#include +#include + +static t_class *sdiflists_class; + +//a structure of outlets, decided by an init parameter. +//taken from Pd's trigger object in x_connective.c +typedef struct colout +{ + t_symbol u_type; //outlet type from STYP (todo)? + t_outlet *out; + t_atom *outvec; +} t_colout; + +// file markers, info for frame positions and times to allow seeking +typedef struct pos +{ + SdifFloat8 timetag; // seconds + SdiffPosT filepos; // memory locations +} t_pos; + +typedef struct sdiflists +{ + t_object x_ob; + SdifFileT *file ; //file data is malloced by SDIF library and everything goes in here + SdifStringT *string ; //ascii queries + t_symbol *filename; + t_colout *data; + int n_outs; + int max_vec; // enough memory is allocated for the biggest list that will be sent out + int nframes; //number of frames found during indexing + t_canvas *canvas; //used for locating path directory + t_atom *infolist; // storage for right most outlet (always info - NVT or stats) + t_outlet *infoout; + t_outlet *timeout; + float seconds; + float timeRange; + t_pos *markers; // locations and times of frames + long index; // current frame + int use_timetags; // boolean for deciding between timetag and index seeking + unsigned int streamid; // a unique identifier for streams within a file +} t_sdiflists; + +/*-------------------open files, STYP first if given, then SDIF-----------------*/ +static void sdiflists_open(t_sdiflists *x, t_symbol *s, int argcount, t_atom *argvec) +{ + int i,j; + unsigned int StreamSpecified = 0; + + for (i = 0; i < argcount; i++) + { + if (argvec[i].a_type == A_FLOAT) + {//TODO: check if this was given after file, cuz that would be useless + x->streamid = (int) argvec[i].a_w.w_float; + StreamSpecified = 1; + post("stream specified:#%d", x->streamid); + } + + if (argvec[i].a_type == A_SYMBOL) + { + char *sym = argvec[i].a_w.w_symbol->s_name; + if(!strcmp( sym + strlen(sym)-5 , ".sdif" ) || + !strcmp( sym + strlen(sym)-5 , ".SDIF" )) + { + t_colout *u; + if(x->markers[0].timetag != -1) + { + post("closing file... "); + SdifFClose(x->file); + for(j=0; j < x->nframes; j++) x->markers[j].timetag = x->markers[j].filepos = 0; + for(j=0, u = x->data; j < x->n_outs; u++, j++) freebytes( u->outvec, x->max_vec * sizeof(t_atom)); + + x->markers[0].timetag = -1; + x->index = -1; + x->nframes = IFRAMES; +#if DEBUG + post("sdiflists::open: closed previous file"); +#endif + }// end if x->file exists + unsigned int rows = 0; + unsigned int cols = 0; + + t_int eof, m, updatepos; + t_int firstframe = 1; + t_int timepos = 0; + size_t bytesread = 0; + SdiffPosT currpos; + float currtime = 0; + + /*method for opening file in canvas directory. + Based on zexy's [msgfile], which is based on + Pd's [textfile]*/ + char filnam[MAXPDSTRING], namebuf[MAXPDSTRING]; + char buf[MAXPDSTRING], *bufptr, *readbuf; + int fd; // used to check if file exists + char *dirname; + + dirname = canvas_getdir(x->canvas)->s_name; + t_binbuf *bbuf = binbuf_new(); + + fd = open_via_path(dirname, sym,"", buf, &bufptr, MAXPDSTRING, 0); + if(fd < 0) + { + error("sdiflists-open: %s cannot be found", sym); + return; + } + namebuf[0] = 0; + if (*buf) strcat(namebuf, buf), strcat(namebuf, "/"); + + strcat(namebuf, bufptr); + // open and get length + sys_bashfilename(namebuf, filnam); + //this is hopefully a readable file + +#if DEBUG + post("(open_via_path) dirname: %s, filename->s_name: %s, buf: %s, bufptr: %s", dirname, sym, buf, bufptr); + post("AFTER bashfilename: namebuf: %s, filnam: %s ", namebuf, filnam); +#endif + + x->filename = gensym( namebuf ); + + /* Check if the file is a good SDIF file, skip function if not */ + if (SdifCheckFileFormat (x->filename->s_name)) + { + post("sdiflists: reading %s", x->filename->s_name); + x->file = SdifFOpen ( x->filename->s_name, eReadFile); + bytesread += SdifFReadGeneralHeader (x->file); + bytesread += SdifFReadAllASCIIChunks (x->file); + eof = SdifFCurrSignature(x->file) == eEmptySignature; + int err; + while (!eof) //frame loop + { + /*The frame positions must be indexed before the + frameheader is read, then check if it is a + selected frame. If not, skip the frame and + overwrite the marker.*/ + err = SdifFGetPos(x->file, &currpos); + if(err==-1) error("error SdifFGetPos"); + + + /* Read frame header. Current signature has already been read + by SdifFReadAllASCIIChunks or the last loop.) */ + bytesread += SdifFReadFrameHeader (x->file); + + if(!StreamSpecified) + { + x->streamid = SdifSelectGetFirstInt(x->file->Selection->stream, SdifFCurrID (x->file)); + StreamSpecified = 1; + post("first stream used: #%d", x->streamid); + } + + //PROBLEM: (maybe not...check)the last frame in the file is always acceptable... fix by using sel spec + while (!SdifFCurrFrameIsSelected (x->file) || SdifFCurrID (x->file) != x->streamid ) + { + // post("frame skipped"); + SdifFSkipFrameData (x->file); + if ((eof = SdifFGetSignature(x->file, &bytesread) == eEof)) break; + SdifFGetPos(x->file, &currpos); + bytesread += SdifFReadFrameHeader(x->file); + } + + if(eof) //have to check again...since it might have skipped to the end + break; + + //check if this is a new time so successive frames don't overwrite filepos + currtime = SdifFCurrTime (x->file); + if( !timepos || x->markers[timepos-1].timetag != currtime ) + { + x->markers[timepos].filepos = currpos; + x->markers[timepos].timetag = currtime; + timepos++; + if( timepos >= x->nframes ) + { + x->markers = (t_pos *)resizebytes( x->markers, x->nframes * sizeof(t_pos), + (x->nframes + IFRAMES) * sizeof(t_pos) ); + x->nframes = x->nframes + IFRAMES; + } + } + /*matrices loop */ + for ( m = 0; (unsigned int)m < SdifFCurrNbMatrix (x->file); m++) + { + bytesread += SdifFReadMatrixHeader (x->file); + + if( SdifFCurrNbRow (x->file) > rows) + { + rows = SdifFCurrNbRow (x->file); //get matrix stats + cols = SdifFCurrNbCol (x->file);//should stay the same + } + //skip the actual matrices + bytesread += SdifFSkipMatrixData (x->file); + }// end for matrices + eof = SdifFGetSignature (x->file, &bytesread) == eEof; + + }// end while no eof + x->seconds = currtime; + x->nframes= timepos; //last timepos was the eof +#if DEBUG + post(" rows: %d , cols: %d , frames: %d , seconds: %f", rows, cols, x->nframes, x->seconds); + post("sdiflists: %s opened. ", x->filename->s_name); +#endif + x->max_vec = rows; //needed to free memory + + //the following lines are a bug work-around... if the eof is reached, you cannot seek + //until the fle is closed, opened, and re-initialized... i posted about this on the sdif list. + SdifFClose (x->file); + x->file = SdifFOpen ( x->filename->s_name, eReadFile); + SdifFReadGeneralHeader (x->file); + SdifFReadAllASCIIChunks (x->file); + eof = SdifFCurrSignature(x->file) == eEmptySignature; + + //make room for the row lists + for ( i=0, u = x->data; i < x->n_outs; u++, i++) + u->outvec = (t_atom *)getbytes( x->max_vec * sizeof(t_atom)); + + } /* end if filetype check */ + } + } //end if Symbol + }//end for arguments +} + +/*--------------------seek to position and output data---------------------*/ +/*SDIF selection spec is infile::[#stream][:frame][/matrix][.column][_row][@time]*/ +/*in any order (accept :: is always first), allowing spaces*/ +static void sdiflists_seek(t_sdiflists *x, t_floatarg gotoindex) +{ + //check if file has been opened, -1 means first timetag was never set + if(x->markers[0].timetag == -1) + { + post("sdiflists: open a file before seeking"); + return; + } + x->index = (long)gotoindex; + //check if index exists + if( x->index >= x->nframes || gotoindex < 0) + { + +#if DEBUG + post("no index there."); +#endif + return; + } + +#if DEBUG_MEM + post ("index = %d , file pos = %d", x->index, x->markers[x->index].filepos); +#endif + + t_colout *u; + int i, selectedrow, selectedcol; + unsigned int m; + int nbrows =0; + int nbcols =0; + int xout = 0; + int eof = 0; + int col, row; + float value = 0; + size_t bytesread; + int listsize[x->n_outs]; + float timetag; + + //seek to index + SdifFSetPos( x->file , &x->markers[x->index].filepos); + + //loop through + while(!eof) + { + SdifFReadFrameHeader(x->file); + timetag = SdifFCurrTime (x->file); + //break once the current time has changed + if( x->markers[x->index].timetag != timetag) break; + + outlet_float(x->timeout, timetag); + + /*Get the Data. If no selection is given when the file is opened, + all rows/columns/matrices/frames will be obtained. */ + if(SdifFCurrFrameIsSelected(x->file)) + { + +#if DEBUG + //fsig turns up 0 unless I close file and reopen in in the open function.. + SdifSignature fsig = SdifFCurrFrameSignature (x->file); + SdifUInt4 streamid = SdifFCurrID (x->file); + post("\n frame header- Signature: '%s', timetag: %f, streamid: %d, nmatrices: %d", + SdifSignatureToString(fsig),x->markers[x->index].timetag, streamid,SdifFCurrNbMatrix (x->file)); +#endif + + //each frame can contain multiple matrices, so go through all of them + for( m= 0; m < SdifFCurrNbMatrix (x->file) ; m++) + { + bytesread = SdifFReadMatrixHeader(x->file); + //matrices not selected will be skipped, but they still need to be added to the bytesread tally + if (SdifFCurrMatrixIsSelected (x->file)) + { + //get how many rows total, then check which ones are selected + nbrows = SdifFCurrNbRow (x->file); + nbcols = SdifFCurrNbCol (x->file); +#if DEBUG + //same problem with matrix signature as frame signature + SdifDataTypeET type = SdifFCurrDataType(x->file); + post("matrix header: Signature: '%s', nbrows: %d, nbcols %d, type %04x", + SdifSignatureToString(SdifFCurrSignature(x->file)), nbrows, nbcols, type); +#endif + + //go through every row and build vectors according to which column the row i sin + for (selectedrow = 0, row = 0; row < nbrows; row++) + { + if(SdifFRowIsSelected (x->file, row)) + { + bytesread += SdifFReadOneRow (x->file); + //put each member in the correct vector by accessing each one according to the current column + //plus any previous columns from other matrices/frames + for ( selectedcol= 0, col = 1, u = x->data + xout + selectedcol; + col <= nbcols && xout + selectedcol < x->n_outs; col++, u++) + { + + if(SdifFColumnIsSelected (x->file, col)) + { + value = SdifFCurrOneRowCol (x->file, col); + SETFLOAT(u->outvec + selectedrow, value); + selectedcol++; + }//end if col is selected + } //end for cols + selectedrow++; + }//end if row is selected + }//end for rows + //set how big each vector is that was just filled + for(i = 0; i < SdifFNumColumnsSelected (x->file); i++) + { + listsize[xout + i] = SdifFNumRowsSelected (x->file); + } + //update number of columns + xout += SdifFNumColumnsSelected (x->file); + }//end if matrix is selected + else bytesread += SdifFSkipMatrixData(x->file); + + SdifFReadPadding(x->file, SdifFPaddingCalculate(x->file->Stream, bytesread)); + }//end for matrices in frame + }// end if current frame is selected and not eof + else SdifFSkipFrameData(x->file); + + eof = SdifFGetSignature (x->file, &bytesread) == eEof; + } //end while not eof + + /* !! Once eof has been found, I have to close the file and reopen for the + frame signatures to be found. someone please tell me why this is.. */ + if(eof) + { + SdifFClose (x->file); + x->file = SdifFOpen ( x->filename->s_name, eReadFile); + SdifFReadGeneralHeader (x->file); + SdifFReadAllASCIIChunks (x->file); + eof = SdifFCurrSignature(x->file) == eEmptySignature; + + } +#if DEBUG + if (SdifFLastError (x->file)) + { + error(" in sdiflists_seek() "); + } +#endif + // send out columns of rows, preserving right to left order +for (i = x->n_outs, u = x->data + i; u--, i--;) + outlet_list(u->out, gensym("list"),listsize[i], u->outvec); +} + +static void sdiflists_timeRange(t_sdiflists *x, t_floatarg t) +{ + x->timeRange = t; +} +static void sdiflists_time(t_sdiflists *x, t_floatarg time) +{ + int i; + float timeDiff; + for( i = 0; i < x->nframes; i++) + { + + timeDiff = fabs( x->markers[i].timetag - time ); + if(timeDiff < x->timeRange ) + { + sdiflists_seek(x, i); + break; + } + } +} + +static void sdiflists_bang(t_sdiflists *x) +{ + sdiflists_seek(x, (float)++x->index); +} + + +/*--------------------------------------------------------*/ +/* query posts frame, matrix, and all ascii info */ +static void sdiflists_info(t_sdiflists *x) +{ + + /* What I want to Post: + - information about external + - filename + - 1NVT + - streams in file, frame/matrix types + - selection + - column info + - framecount and timerange + */ + + post("\n_-=-_ sdiflists -info _-=-_"); + + if(x->markers[0].timetag == -1) + { + post("sdiflists: open a file before getting info"); + return; + } + post("filename: %s", x->filename->s_name); + + + //size_t bytesread = 0; + //int eof; + + + SdifFClose (x->file); + x->file = SdifFOpen ( x->filename->s_name, eReadFile); + SdifFReadGeneralHeader (x->file); + SdifFReadAllASCIIChunks (x->file); + + + + //----send all Names Values Tables out right most list outlet---- + if (SdifNameValuesLIsNotEmpty(x->file->NameValues)) + { + x->string = SdifStringNew(); + SdifListInitLoop(x->file->NameValues->NVTList); + while (SdifListIsNext(x->file->NameValues->NVTList)) + { + x->file->NameValues->CurrNVT = (SdifNameValueTableT *) + SdifListGetNext(x->file->NameValues->NVTList); + + SdifUInt4 iNV; + SdifHashNT *pNV; + SdifHashTableT *HTable; + HTable = x->file->NameValues->CurrNVT->NVHT; + + for(iNV=0; iNVHashSize; iNV++) + for (pNV = HTable->Table[iNV]; pNV; pNV = pNV->Next) + { + SdifNameValueT *NameValue = (SdifNameValueT *) pNV->Data; + SETSYMBOL(x->infolist , gensym(NameValue->Name)); + SETSYMBOL(x->infolist + 1 , gensym(NameValue->Value)); + outlet_list(x->infoout, gensym("list"), 2 , x->infolist); + }//end for pNV + } //end list while NVT + SdifStringFree(x->string); + }// end if NVT is not empty + + //---------------------- post 1IDS --------------------------- + if ( (SdifExistUserMatrixType(x->file->MatrixTypesTable)) + || (SdifExistUserFrameType(x->file->FrameTypesTable)) ) + { + x->string = SdifStringNew(); + if ((x->file->TypeDefPass == eNotPass) || (x->file->TypeDefPass == eReadPass)) + { + SdifFAllMatrixTypeToSdifString(x->file, x->string); + SETSYMBOL ( x->infolist , gensym( SdifSignatureToString(e1TYP)) ); + SETSYMBOL ( x->infolist + 1 , gensym(x->string->str) ); + outlet_list(x->infoout, gensym("list"), 2 , x->infolist); + + post("---- %s ----",SdifSignatureToString(e1TYP)); + + SdifFAllFrameTypeToSdifString(x->file, x->string); //this compiles + } + SdifStringFree(x->string); + } + + if (SdifStreamIDTableGetNbData (x->file->StreamIDsTable) > 0) + { + x->string = SdifStringNew(); + if ((x->file->StreamIDPass == eNotPass) || (x->file->StreamIDPass == eReadPass)) + { + SdifFAllStreamIDToSdifString(x->file, x->string); //this also undeclared in sdif.h. x->string? + SETSYMBOL ( x->infolist , gensym(SdifSignatureToString(e1IDS)) ); + SETSYMBOL ( x->infolist + 1 , gensym(x->string->str) ); + outlet_list(x->infoout, gensym("list"), 2 , x->infolist); + + } + SdifStringFree(x->string); + } + + //------ output Stream ID's and corresponding Frame types -------- + size_t bytesread = 0; + int eof = 0; + int nStream = 0; + int streamIDlist[MAX_STREAMS]; + int j, newStream; + for(j = 0; j < MAX_STREAMS; j++) + streamIDlist[j] = -1; + while(!eof) + { + bytesread += SdifFReadFrameHeader (x->file); + SdifUInt4 streamid = SdifFCurrID (x->file); + SdifSignature fsig = SdifFCurrFrameSignature (x->file); + newStream = 1; + for(j = 0; j < MAX_STREAMS; j++) + { + if(streamIDlist[j] == (signed) streamid) + newStream = 0; + } + if(newStream) + { + streamIDlist[nStream++] = streamid; + SETSYMBOL(x->infolist , gensym("stream")); + SETFLOAT(x->infolist + 1, streamid ); + outlet_list(x->infoout, gensym("list"), 2 , x->infolist); + + SETSYMBOL(x->infolist , gensym("frametype")); + SETSYMBOL (x->infolist + 1, gensym(SdifSignatureToString(fsig)) ); + outlet_list(x->infoout, gensym("list"), 2 , x->infolist); + } + + bytesread += SdifFSkipFrameData (x->file); + eof = (SdifFGetSignature(x->file, &bytesread)== eEof); + + } + + //also send other useful info out rightmost list outlet + SETSYMBOL(x->infolist , gensym("frames")); + SETFLOAT (x->infolist + 1, (float) x->nframes); + outlet_list(x->infoout, gensym("list"), 2 , x->infolist); + + SETSYMBOL(x->infolist , gensym("seconds")); + SETFLOAT (x->infolist + 1, x->seconds ); + outlet_list(x->infoout, gensym("list"), 2 , x->infolist); + + SETSYMBOL(x->infolist , gensym("maxlist")); + SETFLOAT (x->infolist + 1, x->max_vec ); + outlet_list(x->infoout, gensym("list"), 2 , x->infolist); + + +} + +/*--------------------------------------------------------*/ +/* about for author info */ +static void sdiflists_about(t_sdiflists *x) +{ + post("~~~ [sdiflists] v0.1 ~~~"); + post("by Richie Eakin, reakinator@gmail.com"); + post("source last edited: %s", DATE); + post("SDIF Ircam library version %s \n", SDIF_VERSION_STRING ); +} + +static void sdiflists_error(t_sdiflists *x, t_floatarg bool) +{ + if(bool == 0) + { + SdifDisableErrorOutput (); + post("error output disabled."); + } + + if(bool == 1) + { + SdifEnableErrorOutput (); + post("error output enabled."); + } +} + +static void sdiflists_types(t_sdiflists *x, t_symbol *types) +{ + + if(x->markers[0].filepos != -1 ) + { + t_colout *u; + int j; + SdifFClose(x->file); + for(j=0; j < x->nframes; j++) + x->markers[j].timetag = x->markers[j].filepos = 0; + + x->markers[0].timetag = -1; + + for ( j=0, u = x->data; j < x->n_outs; u++, j++) + freebytes( u->outvec, x->max_vec * sizeof(t_atom)); + +#if DEBUG + post("sdiflists::types: closed previous file"); +#endif + x->nframes = IFRAMES; + } + //prepend the full path onto the filename + char fullfilename[MAXPDSTRING], namebuf[MAXPDSTRING]; + char buf[MAXPDSTRING], *bufptr, *dirname; + int fd = 0; + + dirname=canvas_getdir(x->canvas)->s_name; + t_binbuf *bbuf = binbuf_new(); + fd = open_via_path(dirname, types->s_name,"", buf, &bufptr, MAXPDSTRING, 0); + if(fd > 0) + { + namebuf[0] = 0; + if (*buf) + strcat(namebuf, buf), strcat(namebuf, "/"); + strcat(namebuf, bufptr); + sys_bashfilename(namebuf, fullfilename); + + SdifGenKill (); // have to close it to read a new .STYP + SdifGenInitCond (types->s_name); + + post("sdiflists: types-declaration file: %s", types->s_name); + } + else post ("sdiflists: types file %s could not be opened", types->s_name); +} + + + +/*--------------------constructors and destructors---------------------*/ +/* optional creation arguments are typechecked for number of columns, + STYP types-definition file, and initial SDIF file. The STYP should be + first so that the SDIF file is defined correctly.*/ + +/*TODO: -c x or -m y to decide between columns or matrices output*/ +static void *sdiflists_new(t_symbol *s, int argcount, t_atom *argvec) +{ + +#if DEBUG + post("~~~ sdiflists: Debug Mode ~~~"); + +#endif + + + t_sdiflists *x = (t_sdiflists *)pd_new(sdiflists_class); + + x->canvas = canvas_getcurrent(); + t_colout *u; + + int i, j; + int gotcols = 0; + + x->n_outs = 0; + x->nframes = IFRAMES; + x->timeRange = 0.01; + x->index = -1; // will be incremented to 0 if banged, reset if seeked + + + + SdifGenInitCond (""); /*initialize standard .STYP types file if uninitialized */ + + for (i = 0; i < argcount; i++) + { + + if (argvec[i].a_type == A_FLOAT) + { + gotcols= 1; + x->n_outs = (int) argvec[i].a_w.w_float; + x->data = (t_colout *)getbytes(x->n_outs * sizeof(*x->data)); + + + /*number of outlets is defined here; one for each column specified or + one for each matrix (if x->n_outs is zero) */ + for ( j=0, u = x->data; j < x->n_outs; u++, j++) + { + u->out = outlet_new (&x->x_ob, &s_list); + } + } + if (argvec[i].a_type == A_SYMBOL) + { + t_atom at; + SETSYMBOL(&at , argvec[i].a_w.w_symbol ); + char *sym = argvec[i].a_w.w_symbol->s_name; + + if( (!strcmp( sym + strlen(sym)-5 , ".sdif" ) || + !strcmp( sym + strlen(sym)-5 , ".SDIF" )) && gotcols ) + { + sdiflists_open(x, 0, 1, &at); + } + if(!strcmp( sym + strlen(sym)-5 , ".styp" ) || + !strcmp( sym + strlen(sym)-5 , ".STYP" )) + { + sdiflists_types(x, argvec[i].a_w.w_symbol); + } + + }//end if symbol argument + + + + }//end for creation arguments + + x->timeout =outlet_new(&x->x_ob, &s_float); + x->infoout = outlet_new(&x->x_ob, gensym("list")); + x->markers = (t_pos *)getbytes( x->nframes * sizeof(t_pos)); + x->infolist = (t_atom *)getbytes( 2 * sizeof(t_atom)); + x->markers[0].timetag = -1; //if this isn't -1, a file is open + return (void *)x; +} + +/*cleanup function - leave SDIF library in case there are other files using it */ +static void sdiflists_free(t_sdiflists *x) +{ + t_colout *u; + int i; + SdifFClose (x->file); + + for ( i=0, u = x->data; i < x->n_outs; u++, i++) + freebytes( u->outvec, x->max_vec * sizeof(t_atom)); + + freebytes(x->data, x->n_outs * sizeof(*x->data)); + freebytes(x->markers, x->nframes * sizeof(t_pos)); + freebytes(x->infolist, 2 * sizeof(t_atom)); +} + +/*SETUP: a float inlet and variable creation arguments. */ +void sdiflists_setup(void) +{ + sdiflists_class = class_new(gensym("sdiflists"), (t_newmethod)sdiflists_new, (t_method)sdiflists_free,sizeof(t_sdiflists), 0, A_GIMME, 0); + //open - filename/streams input(to do: multiple streams) + class_addmethod(sdiflists_class, (t_method)sdiflists_open, gensym("open"), A_GIMME , 0); + //seek - float is used as index or (TODO) time + class_addfloat(sdiflists_class, (t_method)sdiflists_seek); + // bang - sends out next frame + class_addbang(sdiflists_class, sdiflists_bang); + //info - print statistics and useful information stored in file + class_addmethod(sdiflists_class, (t_method)sdiflists_info, gensym("info"), 0); + //error - disable/re-enable error messages from sdif library + class_addmethod(sdiflists_class, (t_method)sdiflists_error, gensym("error"), A_DEFFLOAT); + //get -- get info and send out right most outlet + class_addmethod(sdiflists_class, (t_method)sdiflists_about, gensym("about"), 0); + //types - change the STYP file from default ( SdifTypes.STYP) + class_addmethod(sdiflists_class, (t_method)sdiflists_types, gensym("types"), A_DEFSYM, 0); + //time - specify desired frame by time intead of frame number + class_addmethod(sdiflists_class, (t_method)sdiflists_time, gensym("time"), A_DEFFLOAT, 0); + //timerange - the timestamp selected is within this amount of the time specification + class_addmethod(sdiflists_class, (t_method)sdiflists_timeRange, gensym("timerange"), A_DEFFLOAT, 0); +} diff --git a/sdiftostring.h b/sdiftostring.h new file mode 100644 index 0000000..5b2ae59 --- /dev/null +++ b/sdiftostring.h @@ -0,0 +1,13 @@ +/* SdifFPut.c functions that were not declared in sdif.h*/ + +#include +int SdifFNameValueLCurrNVTtoSdifString (SdifFileT *SdifF, SdifStringT *SdifString); +int SdifFAllStreamIDToSdifString (SdifFileT *SdifF, SdifStringT *SdifSTring); + +/* + Append one frame type to SdifString +*/ +int SdifFOneFrameTypeToSdifString(SdifFrameTypeT *FrameType, SdifStringT *SdifString); + + +int SdifFOneMatrixTypeToSdifString(SdifMatrixTypeT *MatrixType, SdifStringT *SdifString); diff --git a/test/meowLoris.sdif b/test/meowLoris.sdif new file mode 100644 index 0000000..6de8ce9 Binary files /dev/null and b/test/meowLoris.sdif differ diff --git a/test/orgue.sdif b/test/orgue.sdif new file mode 100644 index 0000000..768c1d0 Binary files /dev/null and b/test/orgue.sdif differ diff --git a/test/pianoSpear.sdif b/test/pianoSpear.sdif new file mode 100644 index 0000000..6d3b1fc Binary files /dev/null and b/test/pianoSpear.sdif differ diff --git a/test/richiepooSMS.sdif b/test/richiepooSMS.sdif new file mode 100644 index 0000000..5f45dbc Binary files /dev/null and b/test/richiepooSMS.sdif differ -- cgit v1.2.1