Skip to content
This repository has been archived by the owner on Feb 19, 2023. It is now read-only.

Provider creation overview

Valera edited this page Jan 19, 2018 · 2 revisions

Common information

There is base API and wrapper for most common usage called soundProviderTask. First one provide more customisable and flexible way, second - easier to use in most situations.

Base API

Let me just show definion:

QueueHandle_t queue = NULL; // Read from here
QueueHandle_t controlQueue = NULL; // Read controlling data from here

// PROVIDER CONTROL INTERFACE START
virtual void provider_start() = 0; // Start filling (should be ok if started)
virtual void provider_pause() {}; // Optional methods for extra optimisation
virtual void provider_resume() {}; 
virtual void provider_stop() = 0; // Stop filling (should be ok if isn't started)

virtual void provider_restart() {provider_stop(); provider_start();} // This one calls if track repeats (default implementation should work, but it is better to write your own)
// PROVIDER CONTROL INTERFACE END

void postSample(SoundData sample);
void postControl(SoundProviderControl ctrl);

void queueReset();

virtual unsigned long int getFrequency() = 0; // Frequency in Hz, should be constant

Pretty easy, right?

So, you should implement:

  • void provider_start()
  • void provider_stop()
  • unsigned long int getFrequency()

Also, optional functions:

  • void provider_pause()
  • void provider_resume()
  • void provider_restart()

All of that functions should be as fast as possible and non-blocking, because all of them calls from timer's callback.

So, you should use it that way:

  1. Post samples using postSample(sample).
  2. When nothing to post, send end-of-queue using postControl(END).
  3. In case of error, post error using postControl(FAILURE).

Task wrapper for most common usage

In most cases base API is too complicated, so it is much better to use wrapper. It implements easier API. So a piece of code, again:

// TASK PROVIDER INTERFACE START
virtual void task_prestart() {};
virtual void task_poststart() {};
virtual void task_code() = 0;
virtual void task_prestop() {};
virtual void task_poststop() {};
// TASK PROVIDER INTERFACE END

// PROVIDER CONTROL INTERFACE START
void provider_start(); // Start filling (should be ok if started)
void provider_stop(); // Stop filling (should be ok if isn't started)
// PROVIDER CONTROL INTERFACE END

void taskProviderCode();
void stopFromTask();
TaskHandle_t taskHandle = NULL;

size_t stackSize = 2048;

It implements provider_start() and provider_stop(), so you still can redefine other methods.

Main part of code is placed in task_code(). Task starts in provider_start(). It doesn't need to stop itself at the end, but still must call postControl(). If you don't leave function or want emergency stop, call stopFromTask(). If you want to do something with your task by youself, its handle stored in taskHandle, but make shure that it isn't NULL.

Now custom code for start and stop is optional and should be implemented in task_*start() and task_*stop(). As you can understand, task_pre*() calls before starting/stopping, and task_post*() after.

If default stackSize is too small, you always can increace it.

Common

End-user

Developers and contributors

Clone this wiki locally