Giter VIP home page Giter VIP logo

pfseq's Introduction

Precision Timing Audio Sequencer Module

For audio tools like drum machines, samplers, metronomes, etc.

Overview

The requirements that led to this module:

  • playing clips with timing precison and accuracy that is good enough for recording a track for production
  • doing this for multiple simultaneous AudioTracks
  • able to change tempo while playing
  • able to change audio content while playing
  • able to define time position of audio clips relative to beats and bars, consistent with musical notation
  • content can be provided as looping or non-looping
  • runs in service (able to run in background)
  • error info sent to activity from service
  • module easily includable in an android app

Precision is achieved by:

  • streaming PCM audio data to AudioTrack instances and not allowing AudioTrack to underrun
  • keeping count of frames written to an AudioTrack
  • mapping frame-position to JVM nanotime with an AudioTimestamp
  • the time of a given item is calculated relative to the tempo start time and with adequate precision

Installation

Add the pfseq AAR module to your Android project and make it a dependency for the project's app module. You can get the AAR from this demo app's pfseq\build\outputs\aar directory. You may need to run "rebuild project" in Android Studio to generate this.

Usage

  1. Extend PFSeq and implement the abstract method getNotification(). It will need to return a Notification object unless the RUN_IN_FOREGROUND config value is set to false.
  2. Extend PFSeqActivity for any activity that will interact with your sequencer service. Abstract methods:
  • receiveMessage() - The sequencer service sends error messages to the activity. Do what you want with them here.
  • onConnect() - Called when the activity becomes bound. This is where you set up UI listeners that call public methods on your sequencer service (if bound).
  • getServiceClass() - Just return YourPFSeqBaseClass.class. It tells PFSeqActivity the name of your PFSeq base class.
  1. Call YourPFSeqBaseClass.setUpSequencer(config). Pass it a PFSeqConfig object. See PFSeqConfig class for how to override default config settings.
  2. Add at least one track to the sequencer, and add at least one "piano roll item" with an audio clip to the track.
  3. Call play() on the sequencer.

License

Copyright (c) 2019 People's Feelings
Licensed under GPL v2
https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html

Requirements

  • API level 24

Other features

  • Includes decoder to get raw PCM data from encoded files such as MP3s
  • Length of audio clips can be specified as absolute or relative to tempo
  • Velocity of clips can be set
  • all mathematical operations pertinent to timing accuracy are marked in the code with "adjust to taste" comments

pfseq's People

Contributors

foobar123asdf avatar peoplesfeelings avatar

Stargazers

 avatar  avatar  avatar Fernando Mora Ángel avatar José Miguel García Urrutia avatar  avatar Steve Myers avatar

Watchers

 avatar

pfseq's Issues

question

with double bpm = (i / 1000.0 * 1000) + 15 is the + 15 meant to be there?

also could this be extracted out of a service? like so it does not require a service?

initial playback latency

is there any way to decrease the initial playback latency without underrunning?

as at the moment I have

        put(SAMPLE_RATE, 44100);
        put(BUFFER_SIZE_BYTES, get(SAMPLE_RATE));
        put(CONTROL_THREAD_POLLING_MILLIS, 5);
        put(MIN_MILLIS_AHEAD_TO_WRITE, 400);
        put(MIN_WRITABLE_CONTENT_NANO, 5000);
        put(TIMESTAMP_POLLING_DELAY_MILLIS, 50);

in the config

and I don't know how to reduce initial playback latency without underrunning

and I am not as experienced with the internals of PFSeq to be able to make it into a real-time audio streamer without affecting the perfect timing of PFSeq

eg where any audio written will immediately be played

in particular, for use with a MIDI sequencer, where a NOTE can be played at any time, and is NOT limited to the constraints of a piano roll (eg it could be located at a position which does not perfectly align with a beat grid of 1/4 or 1/3 or whatever the user desires)

also the same issue would occur in a midi sequencer (eg drum pattern), where a user IS NOT guaranteed to press the play button 100% in sync with the metronome, but EXPECTS the audio to immediately play with the sync adjusted to match when ever the play button has been pressed

eg if the user presses play on a triplet, then the sync should be adjusted such that every 4 steps is on a triplet
eg

WHAT THE USER EXPECTS:
       beginning of bar                                                        end of bar
       |                                                                       |
       beginning of 1st beat               beginning of 2nd beat               |
       |                                   |                                   |
       -------------------------------------------------------------------------
       |  :  :  |  :  :  |  :  :  |  :  :  |  :  :  |  :  :  |  :  :  |  :  :  |
       |  :  :  |  :  :  |  :  :  |  : Pos |  :  :  |  :  :  |  :  :  |  :  :  |
       |  :  :  |  :  :  |  :  :  |  :  :  |  :  :  |  :  :  |  :  :  |  :  :  |
       -------------------------------------------------------------------------

THE ACTUAL GRID
       beginning of bar                                                        end of bar
       |                                                                       |
       beginning of 1st beat               beginning of 2nd beat               |
       |                                   |                                   |
       |     beginning of bar              |                                   |     end of bar
       |     |                             |                                   |     |
       |     beginning of 1st beat         |     beginning of 2nd beat         |     |
       |     |                             |     |                             |     |
       -------------------------------------------------------------------------------
       |  :  :  |  :  :  |  :  :  |  :  :  |  :  :  |  :  :  |  :  :  |  :  :  |  :  :
       |  : PLAY|  :  :  |  :  :  |  : Pos |  :  :  |  :  :  |  :  :  |  :  :  |  :  :
       |  :  :  |  :  :  |  :  :  |  :  :  |  :  :  |  :  :  |  :  :  |  :  :  |  :  :
       -------------------------------------------------------------------------------

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.