Giter VIP home page Giter VIP logo

flparser's Introduction

FLParser

A parser for FL Studio project files in .NET.

FLParser is a utility for parsing and structuring project files in FL Studio (FLP files). It is used by the MONAD Demogroup for converting FLP files to a format useable by the demo replayer.

FLParser is based on andrewrk's node-flp, but contains many improvements to clean up code and add compatability for newer versions of FL Studio.

Please note: FLParser is currently in beta. Only the minimal things that we need are currently implemented, and some of them might break - if they do, or you find something new, please submit an issue or pull request.

install

In commandline:

$ cd my/project/directory
$ git clone https://github.com/monadgroup/flparser.git

In Visual Studio:

Solution > Add > Existing Project
    Find Monad.FLParser.csproj
Project References > Add Reference > Projects > Monad.FLParser

Nuget package coming soon!

use

Load a project with Project.Load:

Project project1 = Project.Load("path/to/project.flp"); // load from file

Stream someStream = ...;
Project project2 = Project.Load(someStream); // load from stream

BinaryReader someReader = ...;
Project project3 = Project.Load(someReader); // load from binaryreader

reference

classes

class Project

Represents an FLP file. Has the following properties: (all get; set;)

const int MaxInsertCount;   // max number of inserts (as of FL 12, equal to 105)
const int MaxTrackCount;    // max number of tracks (as of FL 12, equal to 199)
int MainVolume;             // volume of project
int MainPitch;              // pitch of project
int Ppq;                    // pulses per quarter-beat
double Tempo;               // tempo of project
string ProjectTitle;        // title of project
string Comment;             // comment of project
string Author;              // author of project
string Genre;               // genre of project

string VersionString;       // xx.xx.xx-formatted string of FL version
int Version;                // int format of version
List<Channel> Channels;     // list of channels in project
Track[] Tracks;             // set of tracks in project (length is equal to Project.MaxTrackCount)
List<Pattern> Patterns;     // list of patterns in project
Insert[] Inserts;           // set of inserts in project (length is equal to Project.MaxInsertCount)

class Channel

Represents an individual channel (instrument) in a project. Has the following properties: (all get; set;)

int Id;             // channel ID
string Name;        // channel name
uint Color;         // 0x00RRGGBB-formatted channel color
IChannelData Data;  // channel data, will either be GeneratorData or AutomationData

class GeneratorData : IChannelData

Represents channel data for a generator channel (sampler or plugin). Has the following properties: (all get; set;)

byte[] PluginSettings;      // settings saved by the plugin
string GeneratorName;       // plugin generator name
double Volume;              // generator volume
double Panning;             // generator panning
uint BaseNote;              // generator base note
int Insert;                 // insert to send audio to
int LayerParent;            // ???

Enums.ArpDirection ArpDir;  // direction of arp
int ArpRange;               // range of arp
int ArpChord;               // chord of arp (mapping unknown)
int ArpRepeat;              // number of times to repeat arp
double ArpTime;             // speed of arp
double ArpGate;             // arp note duration
bool ArpSlide;              // slide arp?

// for samplers:
string SampleFileName;      // path to sample
int SampleAmp;              // sample volume
bool SampleReversed;        // play sample reversed?
bool SampleReverseStereo;   // swap stereo channels?
bool SampleUseLoopPoints;   // ???

class AutomationData : IChannelData

Represents channel data for an automation channel. Has the following properties: (all get; set;)

Channel Channel;                // channel that this automation is controlling
int Parameter;                  // parameter to control
AutomationKeyframe[] Keyframes; // automation keyframes

class AutomationKeyframe

Represents an individual keyframe in an automation track. Has the following properties: (all get; set;)

int Position;       // keyframe position in pulses
double Value;       // keyframe value
float Tension;      // keyframe tension

class Track

Represents a track in a project playlist. Has the following properties: (all get; set;)

string Name;                // track name
uint Color;                 // 0x00RRGGBB-formatted track color
List<IPlaylistItem> Items;  // list of playlist items in track, will either be ChannelPlaylistItem or PatternPlaylistItem

class IPlaylistItem

Represents an item in a track. Has the following properties: (all get; set;)

int Position;       // position of the item in pulses
int Length;         // length of the item in pulses
int StartOffset;    // position to start in data
int EndOffset;      // position to end in data

class ChannelPlaylistItem : IPlaylistItem

Represents a sample or automation item in a track. Has the following additional properties: (all get; set;)

Channel Channel;    // channel to take sample or automation data from

class PatternPlaylistItem : IPlaylistItem

Represents a pattern in a track. Has the following additional properties: (all get; set;)

Pattern Pattern;    // pattern to take note data from

class Pattern

Represents a pattern in a project. Has the following properties: (all get; set;)

int Id;                                 // pattern ID
string Name;                            // pattern name
Dictionary<Channel, List<Note>> Notes;  // the notes that each channel plays in this pattern

class Note

Represents a note in a pattern. Has the following properties: (all get; set;)

int Position;       // note position in pulses
int Length;         // note length in pulses
byte Key;           // note key in MIDI format
ushort FinePitch;   // note pitch adjustment
ushort Release;     // note release time
byte Pan;           // note pan, 0 is left and 127 is right
byte Velocity;      // note velocity

class Insert

Represents an insert in a project. Has the following properties: (all get; set;)

const int MaxSlotCount;     // max number of effect slots (as of FL 12, equal to 10)
int Id;                     // insert ID
string Name;                // insert name
uint Color;                 // 0x00RRGGBB-formatted track color
ushort Icon;                // icon ID
Enums.InsertFlags Flags;    // insert flags
int Volume;                 // insert volume
int Pan;                    // insert pan
int StereoSep;              // stereo separation
int LowLevel;               // EQ lowpass level
int BandLevel;              // EQ bandpass level
int HighLevel;              // EQ highpass level
int LowFreq;                // EQ lowpass frequency
int BandFreq;               // EQ bandpass frequency
int HighFreq;               // EQ highpass frequency
int LowWidth;               // EQ lowpass width
int BandWidth;              // EQ bandpass width
int HighWidth;              // EQ highpass width
bool[] Routes;              // map of which inserts this insert routes to (length is equal to Project.MaxInsertCount)
InsertSlot[] Slots;         // set of slots in insert (length is equal to Insert.MaxSlotCount)

class InsertSlot

Represents an effect slot in an insert. Has the following propertie: (all get; set;)

int Volume;     // volume of slot
int State;      // slot state (0 = muted, 1 = enabled, 2 = solo)

enums

All enums are in the Enums static class.

enum Event

List of FLP event types, used for parsing. Consult the source code for a list of values.

enum InsertParam

List of insert parameters, used for parsing. Consult the source code for a list of values.

enum ArpDirection

Potential directions for generator channel's arpeggiator. Values are:

  • Off = 0 - no active arp
  • Up = 1 - arp notes go up
  • Down = 2 - arp notes go down
  • UpDownBounce = 3 - arp notes bounce up and down
  • UpDownSticky = 4 - arp notes stick up and down
  • Random - random arp notes

[Flags] enum InsertFlags

Flags for inserts to specify their states. Values are:

  • ReversePolarity = 1 - reverse polarity of the insert
  • SwapChannels = 1 << 1 - swap left and right channels
  • Unmute = 1 << 3 - insert is audible
  • DisableThreaded = 1 << 4 - threading is disabled on insert
  • DockedMiddle = 1 << 6 - insert is docked to middle
  • DockedRight = 1 << 7 - insert is docked to right
  • Separator = 1 << 10 - insert has separator on left
  • Lock = 1 << 11 - insert is locked
  • Solo = 1 << 12 - insert is solo'd (all other inserts will be muted)

license

Licensed under the GPL3 license. See the LICENSE file for more information.

flparser's People

Contributors

antazoey avatar cpdt avatar djh0ffman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flparser's Issues

Problems trying to understand the format

I'm curious, how you reversed engineer this, and I'm taking a look at a project file but the header parsing doesn't seem right to me.

The highlighted part in the image should be equivalent to the 4-byte long Int16 variable named type:

var type = reader.ReadInt16();
if (type != 0) throw new FlParseException($"Type {type} is not supported", reader.BaseStream.Position);

image

Seems like the type variable is not being parsed the way it should be, and would throw a wrong type error for this project file?

I'm a bit of a noob in reverse engineering, am I understanding correctly? Is this project file too new a version, corrupted or am I just mistaken?

FL 20.7+ Automation clips aren't parsed correctly

Well, I'm investigating this project, I'd like to automate a process to create projects but the thing is that I cannot figure out this problem.

I created an example project, which has the following automation clip:

image

The thing is as you can see, that we have a point over 37,0625 (37 + 1/16) (the Ppq is 96), so the position must be = 3558.

I serialized the project using JSON.NET and I looked for the 0,44999... value:

image

There are two matches, the next one:

image

Which has Position = 0, and also I'm looking for the 3558 value, but I can't find it...

So, what can I do about this? I'm looking for how to solve this but I think I won't have luck.

Thanks.

GPL Licensing Violation

Hello,

It has come to my attention that this project is licensed as MIT, when in-fact it cannot be licensed as such. This repository contains excellent work done researching this format further. However this project claims it is based off of node-flp. Node-flp is licensed as GPL as node-flp is based off of PyDAW, which is GPL. And to take it even further, PyDAW was based off of LMMS' work on the FLP import filter. Both LMMS and that filter are licensed as GPL. Basically what I'm trying to say is that this is GPL code all the way up until this repository. Any codebases that are using GPL code must abide by the GPL terms. Thus using GPL code to the extent that it has been in this project, has contaminated this codebase. This codebase should now be licensed as GPL. GPL also prohibits re-licensing, and that's what has been done here by having an MIT license.

This is just a heads-up for the maintainers of the project and for anyone else who plans on using this code. I wish I had payed closer attention, before using code from this repo in my project. Shame on me I guess.

But to the maintainers, thank you for your contributions. And I do not wish for there to be any hard feelings.

Channel names return blank on FL 12, FL 20.6, and 20.7 files

Hello there!

I am having a small issue with the parser and I'm wondering if it's an issue with my driving code, or the library itself.

When I run this:

Project proj = Project.Load("sample.flp", false);
Console.WriteLine("FL Version: "+proj.VersionString);
foreach (Channel chan in proj.Channels){
	Console.WriteLine(chan.Id+" | "+chan.Name+" | "+chan.Color);
}

The output returns as:

FL Version: 20.7.0.1714
0 |  | 16777215
1 |  | 16777215
2 |  | 16777215
3 |  | 8288104

Instead of:
image
With the exact same results occurring on a random FL 12 file.

Please help, and thank you greatly for your time.

Note release is being parsed as a uint16 instead of a byte

var release = reader.ReadUInt16();

In this line, release is being parsed as a uint16 instead of a byte, causing it to be incorrect. The byte after the note release is actually the note color channel inside of the pattern. I made a fix for this inside of my fork for .net standard but id rather not merge that with this to cause any other issues that may happen as I only tested this on 20.7+

FL 20.6 - AutomationData System.ArgumentOutOfRangeException

When trying to load a FL Studio 20.6 file with a bunch of automation data, the parser throws an exception:
Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index

When inspecting in debugger, it seems that paramDestionation is way out of the array size

new features please

function to save a project in version needed
to copy notes from channels in clipboard (if possible, im tryin, but nothing happend(maybe fl studio dont use win clipboard, im not sure ))

๐Ÿ“ In search for initial infos

Hey team ๐Ÿ‘‹ Thanks a lot for your work on this project.

I was just wondering where you got all this info for parsing a .flp file as imagine line doesn't seem to give much information about it. Did you find any docs related to it?

Thanks in advance for the response ๐Ÿ˜„

Compatability with FL Studio 20

FL Studio 20 was recently released, meaning there's a large chance that some parts of the parser are now broken. It would also be good to add support for some of the newer features (arrangements and time signatures primarily).

Playlist Parsing

This is more of a question than an issue. How would I go about parsing all the notes in the playlist of an flp?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.