blob: 6294bc26030698f014d0439abae744baf37ad540 [file] [log] [blame]
// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Various generator classes that generate sound samples for playback. Most
// derive off of FrameGenerator, and generate full frames (one sample for each
// channel) of sound.
//
// SineWaveGenerator -- Generates a single test tone for a given frequency.
// ASharpMinorGenerator -- Generates tones for the A# Harmonic Minor Scale.
// Why choose A# Harmonic Minor? Cause I can. (and because double-sharps
// are cool :) )
#ifndef INCLUDE_TONE_GENERATORS_H_
#define INCLUDE_TONE_GENERATORS_H_
#include <set>
#include <vector>
#include "include/common.h"
#include "include/sample_format.h"
class ToneGenerator {
public:
virtual ~ToneGenerator() {}
// Fills data with up to |buf_size| bytes with of audio frames. Only
// complete frames are written into data (ie., the number of samples written
// is a multiple of the number of channels), and |buf_size| is adjusted to
// reflect the number of bytes written into data.
//
// The |format|, and |num_channels| parameters affet the size of a frame, and
// the type of sample written. The |active_channels| parameter is used to
// select which channels have samples written into them. If a channel is
// not listed in |active_channels|, then it is filled with silence. This is
// to allow generating tones on specific channels.
//
// The |active_channels| set is 0 indexed. If you have 2 channels, and you
// want to play on all of them, make sure |active_channels| contains 0, and
// 1.
virtual size_t GetFrames(SampleFormat format,
int num_channels,
const std::set<int> &active_channels,
void *data,
size_t buf_size) = 0;
// Returns whether or not the FrameGenerator is able to produce more frames.
// This is used to signal when one should stop calling GetFrames().
virtual bool HasMoreFrames() const = 0;
};
class SineWaveGenerator : public ToneGenerator {
public:
explicit SineWaveGenerator(int sample_rate,
double length_sec = -1.0,
int volume_gain = 50);
// Generates a sampled sine wave, where the sine wave period is determined
// by |frequency| and the sine wave sampling rate is determined by
// |sample_rate| (in HZ).
double Next();
void Reset(double frequency);
virtual size_t GetFrames(SampleFormat format,
int num_channels,
const std::set<int> &active_channels,
void *data,
size_t buf_size);
virtual bool HasMoreFrames() const;
private:
double cur_x_;
int cur_frame_;
int total_frame_;
int sample_rate_;
double frequency_;
int volume_gain_;
};
class MultiToneGenerator : public ToneGenerator {
public:
MultiToneGenerator(int sample_rate, double length_sec);
virtual ~MultiToneGenerator();
void SetVolumes(double start_vol, double end_vol);
virtual void Reset(const std::vector<double> &frequencies,
bool reset_timer = false);
virtual void Reset(const double *frequencies, int num_tones,
bool reset_timer = false);
virtual void Reset(double frequency, bool reset_timer = false);
virtual size_t GetFrames(SampleFormat format,
int num_channels,
const std::set<int> &active_channels,
void *data,
size_t buf_size);
virtual bool HasMoreFrames() const;
private:
std::vector<SineWaveGenerator> tone_wave_;
double GetFadeMagnitude() const;
int frames_generated_;
int frames_wanted_;
int fade_frames_;
std::vector<double> frequencies_;
int sample_rate_;
double cur_vol_;
double start_vol_;
double inc_vol_;
pthread_mutex_t param_mutex;
};
class ASharpMinorGenerator : public ToneGenerator {
public:
ASharpMinorGenerator(int sample_rate, double tone_length_sec);
virtual ~ASharpMinorGenerator();
void SetVolumes(double start_vol, double end_vol);
virtual void Reset();
virtual size_t GetFrames(SampleFormat format,
int num_channels,
const std::set<int> &active_channels,
void *data,
size_t buf_size);
virtual bool HasMoreFrames() const;
private:
static const int kNumNotes = 16;
static const double kNoteFrequencies[kNumNotes];
MultiToneGenerator tone_generator_;
int cur_note_;
};
#endif // INCLUDE_TONE_GENERATORS_H_