Shop OBEX P1 Docs P2 Docs Learn Events
FlexProp: a complete programming system for P2 (and P1) - Page 46 — Parallax Forums

FlexProp: a complete programming system for P2 (and P1)



  • pik33pik33 Posts: 2,357

    I tested the latest commit. The short example from post #1349 still fails (= the Basic program cannot read from a file if the C code has #include <stdio.h> in it)

    However if I use dim mp3 as class using "mp3b.c" instead of DECLARE FUNCTION mp3init LIB "mp3b.c" () AS integer then the Basic program can read from the file.

  • @pik33 said:
    I tested the latest commit. The short example from post #1349 still fails (= the Basic program cannot read from a file if the C code has #include <stdio.h> in it)

    However if I use dim mp3 as class using "mp3b.c" instead of DECLARE FUNCTION mp3init LIB "mp3b.c" () AS integer then the Basic program can read from the file.

    Yes, there's a conflict between C's stdio library and the BASIC I/O functions which causes problems if they're declared in the same object (for example the top level object), even if they're not used. I'm not sure how to fix that. For now putting the C code in a different object is one work-around. Doing all the file I/O in C would be another.

  • pik33pik33 Posts: 2,357
    edited 2023-05-11 21:04

    As I already have a player that do all file managing in Basic, the first attempt will be making a class. And I don't know if the C decoder needs the stdio at all in this case. I need only init and decode frame.
    I encountered the error when I manage to compile the decoder with a simple Basic main file and a stripped decode function (so the compiler didn't fail on lack of registers), and the function returned -6 (can't find a frame) so I started debugging and discovered it cannot read the file.

  • pik33pik33 Posts: 2,357
    edited 2023-05-12 16:10

    The decoder doesn't need stdio. After removing the unneeded #include, both versions, class and lib, seems to work and return something that looks like decoded data... so I will now try and attach the audio driver to check if it is really a decoded audio.

    Edit: MP3 is playing in the real time now :) from a P2 on my desk

    A lot of work is needed before it will go to the Prop2Play. The decoder is capricious: it needs to be feed exactly, corrected frames, and then timings are tight (but it still can get bytes from file and play using 1 cog)

  • Wuerfel_21Wuerfel_21 Posts: 4,628
    edited 2023-05-12 17:32

    The FAT driver works best when your reads align to sector boundaries (i.e. always read multiples of 512). If you don't, the driver needs to memcpy around between it's internal buffers and the buffer you read into (I optimized memcpy in the library already, before you ask). Additionally, reading larger blocks is also vastly more efficient. I also think(tm) "nice" block sizes like 1k,8k,32k, etc are at a slight(?) advantage due to FAT cluster alignment.

  • pik33pik33 Posts: 2,357
    edited 2023-05-12 17:58

    Yes, of course, but the simplest mp3 test can do without it. In the prop2play all things will be properly buffered. I have a problem with the decoder itself: try to play Oxygene, part 4. I cannot describe this but one of its instruments sounds weird while other sound good.

    A long way to do. (1) opening, buffering and seeking mp3 files (2) make the decoder work in other cog than the player itself (3) make the decoder C code clean: now I simply put all C files into one big mess and it started to work, but this needs cleaning, ordering, restoring license notes etc, (4) debugging the decoder so it will no more making strange sound and (5) at last, write the proper API for the audio driver as I managed to forget how to use it.

  • I've published a new binary release of flexprop, 6.1.4, with a lot of bug fixes inspired by the USB and MP3 projects. The focus is very much on bug fixes, the only new feature is that .fpide files now can have -I directives (which was intended originally anyway, so this is kind of a bug fix as well).

  • I have a really dumb question.
    You all have been doing a number of things that are to quote develope this GUI. I am simply wanting to do C++ type programming and use the
    "libraries" that were "available" under P1.
    I also want to write my own libraries in P2 like P1.
    Is there a simple library list?
    Someone sent me a link for libraries but I could not easily impliment them.
    Sorry some of this is beyond me for quick implimentation.
    This is where you are loosing people. We need some more simplistic instruction of how to work the problem.
    Sorry, no offense to anyone.
    I would like to translate some of my C++ P1 code easily to P2.
    Unfortunately the Prop tool for P2 does not support C++ for the prop.
    Unfortunately you guys move so fast that some of us cannot keep up.
    Please slow down and think of the novices who are trying to move forward.
    Thank you very much.
    Some of us need to understand what what a binary is . I have looked it up and cannot get a good undersatanding what it is.
    Sorry to say this but I think it would help greatly for the others who are beginners. I would really like to as to quote one of the geniuses " not to push any bodies buttons", "
    I really like to have so much power in my hands." That was a couple of years ago. He know who he is. I thank him as I have been attempting programming since the old IBM 1130 and 360 years, fortran and Basic.

    If Parallax wants to advance microcontroller coding and as we all want to help, we need to remind ourselvelvs that it is not just about us but about everyone.
    Please can we create a formum to start from the beginning like the old P1 documentation that took you from blinking a light to working with capacitors for the discharge time.
    We will not make money but we will have the legacy of being mentors to the younger.
    Wow what a concept.

  • pik33pik33 Posts: 2,357
    edited 2023-05-15 06:23

    There was an OBEX... they said they will return it. That was the "library list". Now, they are all available on Github. Much less convenient at least for a beginner.
    Flexprop is an independent compiler: Parallax develops Spin/PASM only Propeller Tool/Pnut.
    I don't know what compiler you have used for your P1 C++: Flexprop is C with some C++ extension added. Flexprop however can compile P1 code (Spin1) for a P2 unless you use P1's hardware features that are not present in a P2.
    A binary is simply a binary. The file with the machine code that you upload to a Propeller and it starts to execute instructions from it.

  • @pilot0315,

    Yes, I like the learn site that walked me through the simple projects for the P1. Andy did a great job of putting together a number of libraries for the P1. I used these libraries to help me learn more about the P1 and develop my own libraries.

    Sadly, this does not exist for the P2 nor is there a WX board for the P2 or a robot as well. For an educational product I don't think the P2 is right for the job.

    I have since converted all my libraries from the P1 to the P2 with very little changes in most cases. Some changes are based on the new compiler environment and how the P2 works.

    Eric has moved some of the library tools over to the P2, but I found some of them simple did not work. Since very few people program in C many of the libraries have not been fully tested. Eric's job to create a multifaceted compiler is amazing in itself. He does not have the resources to buy every trinket that Parallax made nor the time to test each and every one of them.

    I am enjoying my journey into the P2 environment even if it is only me myself and I.


  • @pilot0315 : I can appreciate your desire to have a forum for P2 beginners and some better documentation for beginners, but you'd probably have much more luck starting a new topic for that. It will reach a broader group of people then, including more people who might be in a better position to help. This particular discussion is about the FlexProp compiler. just as the engineers who build planes are not always the best flying instructors, compiler writers are not necessarily the best people to teach programming,

    That said, if there's some particular program you'd like to try to get working under FlexProp, please post it and perhaps we can offer suggestions

  • evanhevanh Posts: 15,290

    "binary" and "executable" are interchangeable in this context.

  • pilot0315pilot0315 Posts: 836
    edited 2023-05-15 18:47

    Thank you for the response. I got pretty good with the P1, working with it for 10 years. P2 was for me progressing but I had a long hiatus and for the last few months have been trying to get back.
    Some one put me to his libraries but I need a step by step of how to integrate them. Simple IDE worked well libraries and I as well wrote an extended tutorial on making libraries that got a good response after the forums showed me what was missing. I have been wanting to import those programs into P2 C. Need something simple that is like full duplex serial if possible in flexprop.
    Flexprop does not seem to hard to use. Unfortunately the prop tool does not work with C for the P2, and since the P2 can work in C on other compilers, can they fix that?
    I will take your suggestion and start a thread on translating from P1 to P2 on a more comprehensive level. I will keep the struggle on.
    Also is there an explanation list of what the libraries do in flexprop, as some of the acronyms are hard to understand.

  • pik33pik33 Posts: 2,357

    I have problems with the mp3 decoder.

    The original Adafruit MP3 decoder compiled for a Linux PC works as expected
    The P2 version does not.

    Symptoms: while so called "long blocks" seem to be decoded correctly, the "short blocks" are not.

    This can be seen in the attached input.mp3/output.bin. There is clipping somewhere and the percussive instrument's sound at about 5th seconds of the file was decompressed way too long.
    I experimented with the code, silencing the short blocks and this experiment confirmed that they are the problem: there was silence in the output where there are incorrect decoded fragments.

    To check if this is not a problem that I introduced with my experiments, I checked this using the file from the post #6 of this topic:

    What I changed is: instead of open the host, I used the SD card and I added fclose at the end as without this fclose the resulting output is 0 bytes long. The rest of the code remains unchanged.

    I attached the code with my input and output file in the "standalone" directory.

    The contains the (correct) output of the Adafruit MP3 decoder from a Linux machine using the same input.mp3.

  • roglohrogloh Posts: 5,241
    edited 2023-05-16 09:09

    @pik33 If you can now find a given block that differs and can feed the input for that block into both decoders, one running on a PC and the other on a P2 and dump it out being decoded with printf to some file etc with any luck you might be able to directly home in on where the calculation differs (using a simple file diff) and then locate the offending computation/clipping operation. Of course this is probably easier said than done - I've not even looked at the source.

  • pik33pik33 Posts: 2,357

    Yes, I can. The next thing I can do is to prepare a very short mp3 out of 3..5 frames, including a short block in it, and insert a lot of debug logging into the C files. I have now the environment prepared to do this: I have both versions of the decoder on a Linux virtual machine and I know where the bad blocks are in the music file. Maybe later today, I have another &^%*ing project (not a microcontroller related :( ) to do at the university.

  • pik33pik33 Posts: 2,357

    It seems adding 1 to CLZ restored the sanity.

  • @pik33 Does that mean you actually found gcc's CLZ() on Linux returns different values to the P2 with __builtin_clz() with flexspin? Or something else?

  • pik33pik33 Posts: 2,357
    edited 2023-05-17 14:18

    No, I didn't checked this yet, but after adding this #1, the decoder now works as expected. The problem was overflows when the guard bit value computed by CLZ was too low.
    The problem may be CLZ itself but it can also be something in the short block processing path thats computes different in P2 than in Intel.

  • RaymanRayman Posts: 14,066

    I didn't know about CLZ (count leading zeroes)... I wonder if it is implemented using the PASM2 ENCOD instruction...

  • ersmithersmith Posts: 5,958
    edited 2023-05-17 22:20

    @pik33 said:
    It seems adding 1 to CLZ restored the sanity.

    Only as a side effect of changing the number of guard bits, and hence avoiding a loop that inside it had an expression like *xPrev++ >>= es; which flexspin was compiling incorrectly :(. That's fixed in github now. Thanks for bringing this to my attention!

    CLZ itself is fine; it disagrees with the x86 on what CLZ(0) should be (x86 gives 31, P2 gives 32) but other platforms share the P2 behavior and the decoder works on them.

    @Rayman said:
    I didn't know about CLZ (count leading zeroes)... I wonder if it is implemented using the PASM2 ENCOD instruction...

    Yes, that's what it translates into on P2.

  • pik33pik33 Posts: 2,357

    Yes, 6.1.5 compiled the decoder that works good without adding 1 to CLZ or (what I also tried) fixing the amount of guard bits.

  • evanhevanh Posts: 15,290

    Ha, I've only ever known it as priority encode. I didn't read the sources and I though maybe CLZ meant clear the Z flag.

  • I've released version 6.1.5, which fixes some bugs that cropped up in testing of the new USB driver and MP3 decoder. It is available both from github and from my Patreon page (see the links in my signature).

  • pik33pik33 Posts: 2,357

    A feature request - "No terminal" option :) so the program loads and runs but opens no additional terminal window.

  • pik33pik33 Posts: 2,357
    edited 2023-05-31 21:14

    I made a mistake and wrote, in Basic


    instead of


    where c is integer. This compiled and worked giving a (not a proper) result. I think a compilation error should occur here as I don't know what can be a result of substracting an integer from a string. While I tried to

    print (line$-5) (this also compiled)

    it prints something, almost always garbage.

    You can also add an integer to the string. The result is more predictable, giving the original string with several more (but not 5 more when I added 5) characters.

    That should be an error while compiling, or php behavior (string+int=string+str$(int) )

  • @ersmith said:
    I'm saving up for a P2D2 board and other hardware to test with FlexGUI.

    Isn't that something Parallax can provide free of charge for your efforts?

  • pedwardpedward Posts: 1,642
    edited 2023-05-31 19:40

    The flexprop install instructions for Linux state "build from source". Would you be interested in me contributing an RPM spec to build RPMs? Also, do you have a CI pipeline setup for this?

    I could help with writing a Jenkins file to build RPMs, also we could potentially add some testing.

    Flatpak might also be a good way to go for Linux support. I haven't built any flatpak bundles yet, so that would be new.

    EDIT: Looking more deeply into this, Github offers "Github Actions" for public repos to perform CI and builds, etc. They offer Ubuntu, Windows, and MacOSX VMs for building.

    Obviously it would be a challenge to build RPMs using Ubuntu, but it could be possible to build Flatpak bundles on Unbutu, solving that.

    Another option would be to setup Jenkins integration with a GH token and have more control over the build env.

    I have my own Jenkins server that I use with my private repo on GH, it could be possible to configure it in pull-only mode instead of webhook mode, then have it discover branches, etc and do builds. This would offer more flexibility because I use Docker containers for the environment, therefore jobs could be defined for a variety of different Linux environments and versions more easily.

    I could pre-stage docker containers that have the necessary dependencies, to avoid downloading them every CI run. Then it would be /relatively/ lightweight to do builds.

    It took maybe 1min with single-threaded make to build flexprop yesterday, if I do something like make -j 40 then it should be pretty fast, assuming there are no problematic dependencies.

  • We have github actions for building and testing the compiler tools (currently only win32 artifacts are generated)

  • pik33pik33 Posts: 2,357

    Another glitch. I don't know, bug, or feature :) If feature, needs explaining in doc.

    This test code:

    sub a()
    for i=1 to 20
    print i
    next i
    end sub
    sub b()
    let i=i+1
    end sub

    produces this result:

    ( Entering terminal mode.  Press Ctrl-] or Ctrl-Z to exit. )                    

    FlexBasic accepts undeclared variables in 'for' loops, and also it allows to use 'let' to declare and assign a variable, but I expected the "i" in for loop is local to sub a. It seems however it is global.

    Adding dim i in one or both of subs restores the proper behavior, so it is to remember, always declare your variables or strange things can happen :) .

Sign In or Register to comment.