Skip to content

Instantly share code, notes, and snippets.

@teburd
Created October 1, 2011 17:21
Show Gist options
  • Save teburd/1256353 to your computer and use it in GitHub Desktop.
Save teburd/1256353 to your computer and use it in GitHub Desktop.
%% @author Tom Burdick <[email protected]>
%% @copyright 2011 Tom Burdick
%% @doc Sine wave generating trace handler. Useful for fun and testing.
%% @end
-module(plot_trace_sine).
-behaviour(plot_trace_handler).
-export([init/1, units/1, rate/1, length/1, samples/3, terminate/2]).
-record(state, {units, rate, frequency, amplitude, offset, phase, length}).
%% ----------------------------------------------------------------------------
%% plot_trace_handler callbacks
%% ----------------------------------------------------------------------------
init(Options) ->
random:seed(now()),
{units, Units} = option(units, Options, <<"U">>),
{rate, Rate} = option(rate, Options, 50.0 + random:uniform()*100.0),
QRate = 0.25*Rate,
{frequency, Frequency} = option(frequency, Options, QRate + random:uniform()*QRate),
{amplitude, Amplitude} = option(amplitude, Options, 50.0 + random:uniform()*100.0),
{phase, Phase} = option(phase, Options, 0.0),
{length, Length} = option(length, Options, 1000000),
{ok, #state{rate=Rate, units=Units, amplitude=Amplitude,
frequency=Frequency, phase=Phase, length=Length}}.
units(State) ->
{State#state.units, State}.
rate(State) ->
{State#state.rate, State}.
length(State) ->
{State#state.length, State}.
samples(Begin, End, State) when is_integer(Begin), is_integer(End), Begin < End, End < State#state.length ->
Samples = sine(Begin, Begin+End, State#state.frequency,
State#state.amplitude, 0.0, State#state.rate),
{Samples, State}.
terminate(_Reason, _State) ->
ok.
%% ----------------------------------------------------------------------------
%% private api
%% ----------------------------------------------------------------------------
%% @doc Find an option in a list with a default return.
option(Key, List, Default) ->
case lists:keyfind(Key, 1, List) of
false ->
{Key, Default};
{Key, Value} ->
{Key, Value}
end.
%% @doc Generate a set of points representing a sine wave
%% given some parameters (position, points to generate, freqency, amplitude,
%% offset, sample rate, points per pixel).
%% @end
sine(X, N=0, Frequency, Amplitude, Offset, SampleRate)
when is_integer(X), is_integer(N), is_float(Frequency),
is_float(Amplitude), is_float(Offset), is_float(SampleRate)->
[];
sine(X, N, Frequency, Amplitude, Offset, SampleRate)
when is_integer(X), is_integer(N), is_float(Frequency),
is_float(Amplitude), is_float(Offset), is_float(SampleRate) ->
Y0 = math:sin(2*math:pi()*X*(Frequency/SampleRate)),
Y1 = Amplitude*Y0,
Y2 = round(Y1),
Y3 = Y2 + Offset,
[Y3 | sine(X+1, N-1, Frequency, Amplitude, Offset, SampleRate)].
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment