Blame synfig-studio/src/gui/audiocontainer.cpp

Carlos Lopez a09598
/* === S Y N F I G ========================================================= */
Carlos Lopez a09598
/*!	\file audiocontainer.cpp
Carlos Lopez a09598
**	\brief Audio Container implementation File
Carlos Lopez a09598
**
Carlos Lopez a09598
**	$Id$
Carlos Lopez a09598
**
Carlos Lopez a09598
**	\legal
Carlos Lopez a09598
**	Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
Carlos Lopez a09598
**
Carlos Lopez a09598
**	This package is free software; you can redistribute it and/or
Carlos Lopez a09598
**	modify it under the terms of the GNU General Public License as
Carlos Lopez a09598
**	published by the Free Software Foundation; either version 2 of
Carlos Lopez a09598
**	the License, or (at your option) any later version.
Carlos Lopez a09598
**
Carlos Lopez a09598
**	This package is distributed in the hope that it will be useful,
Carlos Lopez a09598
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
Carlos Lopez a09598
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Carlos Lopez a09598
**	General Public License for more details.
Carlos Lopez a09598
**	\endlegal
Carlos Lopez a09598
*/
Carlos Lopez a09598
/* ========================================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
/* === H E A D E R S ======================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
#ifdef USING_PCH
Carlos Lopez a09598
#	include "pch.h"
Carlos Lopez a09598
#else
Carlos Lopez a09598
#ifdef HAVE_CONFIG_H
Carlos Lopez a09598
#	include <config.h></config.h>
Carlos Lopez a09598
#endif
Carlos Lopez a09598
Carlos Lopez a09598
#include <algorithm></algorithm>
[d.j.a.y] Jerome Blanchi f8d04e
#include <sigc++ sigc++.h=""></sigc++>
Carlos Lopez a09598
Carlos Lopez a09598
#include <etl stringf=""></etl>
Carlos Lopez a09598
#include <etl clock=""></etl>
Carlos Lopez a09598
//#include <etl thread=""></etl>
Carlos Lopez a09598
#include <glibmm thread.h=""></glibmm>
Carlos Lopez a09598
Carlos Lopez a09598
#include <synfig general.h=""></synfig>
Carlos Lopez a09598
Carlos Lopez a09598
#include <glibmm main.h=""></glibmm>
Carlos Lopez a09598
Carlos Lopez a09598
#include "audiocontainer.h"
Carlos Lopez a09598
Carlos Lopez a09598
#include <cstdio></cstdio>
Carlos Lopez a09598
#include <sys stat.h=""></sys>
Carlos Lopez a09598
#include <errno.h></errno.h>
Carlos Lopez a09598
Carlos Lopez a09598
#include <set></set>
Carlos Lopez a09598
#include <vector></vector>
Carlos Lopez a09598
abdbf2
#include <gui localization.h=""></gui>
Carlos Lopez a09598
Carlos Lopez a09598
#endif
Carlos Lopez a09598
Carlos Lopez a09598
/* === U S I N G =========================================================== */
Carlos Lopez a09598
Carlos Lopez a09598
using namespace std;
Carlos Lopez a09598
using namespace etl;
Carlos Lopez a09598
using namespace synfig;
Carlos Lopez a09598
Carlos Lopez a09598
/* === M A C R O S ========================================================= */
Carlos Lopez a09598
#ifdef __WIN32
Carlos Lopez a09598
#else //linux...
Carlos Lopez a09598
#define AUDIO_OUTPUT	FSOUND_OUTPUT_OSS
Carlos Lopez a09598
#endif
Carlos Lopez a09598
Carlos Lopez a09598
/* === G L O B A L S ======================================================= */
Carlos Lopez a4bd06
//const double delay_factor = 3;
Carlos Lopez a4bd06
//Warning: Unused variable delay_factor
Carlos Lopez a09598
/* === P R O C E D U R E S ================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
/* === M E T H O D S ======================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
/* === E N T R Y P O I N T ================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
//Help constructing stuff
Carlos Lopez a09598
struct FSOUND_SAMPLE;
Carlos Lopez a09598
using studio::AudioContainer;
Carlos Lopez a09598
Carlos Lopez a09598
bool build_profile(FSOUND_SAMPLE */*sample*/, double &/*samplerate*/, std::vector<char> &/*samples*/)</char>
d363e8
	{ return false; } // not implemented
Carlos Lopez a09598
Carlos Lopez a09598
d363e8
struct scrubinfo {};
Carlos Lopez a09598
Carlos Lopez a09598
//----- AudioProfile Implementation -----------
Carlos Lopez a09598
void studio::AudioProfile::clear()
Carlos Lopez a09598
{
Carlos Lopez a09598
	samplerate = 0;
Carlos Lopez a09598
	samples.clear();
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
handle<audiocontainer>	studio::AudioProfile::get_parent() const</audiocontainer>
Carlos Lopez a09598
{
Carlos Lopez a09598
	return parent;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void studio::AudioProfile::set_parent(etl::handle<audiocontainer> i)</audiocontainer>
Carlos Lopez a09598
{
Carlos Lopez a09598
	parent = i;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
double studio::AudioProfile::get_offset() const
Carlos Lopez a09598
{
Carlos Lopez a09598
	if(parent)
Carlos Lopez a09598
		return parent->get_offset();
Carlos Lopez a09598
	return 0;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
//---------- AudioContainer definitions ---------------------
Carlos Lopez a09598
Carlos Lopez a09598
struct studio::AudioContainer::AudioImp
Carlos Lopez a09598
{
Carlos Lopez a09598
	//Sample load time information
Carlos Lopez a09598
	FSOUND_SAMPLE *		sample;
Carlos Lopez a09598
	int					channel;
Carlos Lopez a09598
	int					sfreq;
Carlos Lopez a09598
	int					length;
Carlos Lopez a09598
Carlos Lopez a09598
	//Time information
Carlos Lopez a09598
	double				offset; //time offset for playing...
Carlos Lopez a09598
Carlos Lopez a09598
	//We don't need it now that we've adopted the play(t) time schedule...
Carlos Lopez a09598
	//current time... and playing info....
Carlos Lopez a09598
	//float				seekpost;
Carlos Lopez a09598
	//bool				useseekval;
Carlos Lopez a09598
Carlos Lopez a09598
	//Make sure to sever our delayed start if we are stopped prematurely
Carlos Lopez a09598
	sigc::connection	delaycon;
Carlos Lopez a09598
Carlos Lopez a09598
	//Action information
Carlos Lopez a09598
	bool				playing;
Carlos Lopez a09598
	double				curscrubpos;
Carlos Lopez a09598
	etl::clock			timer;	//for getting the time diff between scrub input points
Carlos Lopez a09598
Carlos Lopez a09598
	//Scrubbing information...
Carlos Lopez a09598
	//the current position of the sound will be sufficient for normal stuff...
Carlos Lopez a09598
	scrubinfo			*scrptr;
Carlos Lopez a09598
Carlos Lopez a09598
	bool is_scrubbing() const {return scrptr != 0;}
d363e8
	void set_scrubbing(bool /*s*/) { scrptr = 0; }
Carlos Lopez a09598
Carlos Lopez a09598
	//helper to make sure we are actually playing (and to get a new channel...)
d363e8
	bool init_play() { return false; }
Carlos Lopez a09598
Carlos Lopez a09598
public: //structors
6320b8
	AudioImp():
6320b8
		sample(0),
6320b8
		channel(0),
6320b8
		sfreq(0),
6320b8
		length(0),
6320b8
		offset(0),
6320b8
		playing(false),
6320b8
		curscrubpos(),
6320b8
		scrptr(0)
d363e8
	{ } //reuse the channel...
Carlos Lopez a09598
Carlos Lopez a09598
	~AudioImp()
d363e8
		{ clear(); }
Carlos Lopez a09598
Carlos Lopez a09598
public: //helper/accessor funcs
Carlos Lopez a09598
	bool start_playing_now() //callback for timer...
d363e8
		{ return false; } //so the timer doesn't repeat itself
Carlos Lopez a09598
	bool isRunning()
d363e8
		{ return false; }
Carlos Lopez a09598
	bool isPaused()
d363e8
		{ return false; }
Carlos Lopez a09598
Carlos Lopez a09598
public: //forward interface
Carlos Lopez a09598
Carlos Lopez a09598
	//Accessors for the offset - in seconds
d363e8
	const double &get_offset() const
d363e8
		{return offset;}
Carlos Lopez a09598
	void set_offset(const double &d)
d363e8
		{ offset = d; }
Carlos Lopez a09598
Carlos Lopez a09598
	//Will override the parameter timevalue if the sound is running, and not if it's not...
Carlos Lopez a09598
	bool get_current_time(double &/*out*/)
d363e8
		{ return isRunning(); }
Carlos Lopez a09598
Carlos Lopez a09598
	//Big implementation functions...
Carlos Lopez a09598
	bool load(const std::string &filename, const std::string &filedirectory);
Carlos Lopez a09598
	void clear();
Carlos Lopez a09598
Carlos Lopez a09598
	//playing functions
Carlos Lopez a09598
	void play(double t);
Carlos Lopez a09598
	void stop();
Carlos Lopez a09598
Carlos Lopez a09598
	//scrubbing functions
Carlos Lopez a09598
	void start_scrubbing(double t);
Carlos Lopez a09598
	void scrub(double t);
Carlos Lopez a09598
	void stop_scrubbing();
Carlos Lopez a09598
Carlos Lopez a09598
	double scrub_time()
d363e8
		{ return curscrubpos; }
Carlos Lopez a09598
};
Carlos Lopez a09598
Carlos Lopez a09598
//--------------- Audio Container definitions --------------------------
6320b8
studio::AudioContainer::AudioContainer():
6320b8
	imp(NULL),
6320b8
	profilevalid()
6320b8
{ }
Carlos Lopez a09598
Carlos Lopez a09598
studio::AudioContainer::~AudioContainer()
Carlos Lopez a09598
{
Carlos Lopez a09598
	if(imp) delete (imp);
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
bool studio::AudioContainer::load(const std::string &filename,const std::string &filedirectory)
Carlos Lopez a09598
{
Carlos Lopez a09598
	if(!imp)
Carlos Lopez a09598
	{
Carlos Lopez a09598
		imp = new AudioImp;
Carlos Lopez a09598
	}
Carlos Lopez a09598
Carlos Lopez a09598
	profilevalid = false;
Carlos Lopez a09598
	return imp->load(filename,filedirectory);
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
handle<studio::audioprofile> studio::AudioContainer::get_profile(float /*samplerate*/)</studio::audioprofile>
d363e8
	{ return handle<studio::audioprofile>(); }</studio::audioprofile>
Carlos Lopez a09598
Carlos Lopez a09598
void studio::AudioContainer::clear()
Carlos Lopez a09598
{
d363e8
	if (imp) { delete imp; imp = 0; }
Carlos Lopez a09598
	profilevalid = false;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void studio::AudioContainer::play(double t)
d363e8
	{ if(imp) imp->play(t); }
Carlos Lopez a09598
Carlos Lopez a09598
void studio::AudioContainer::stop()
d363e8
	{ if(imp) imp->stop(); }
Carlos Lopez a09598
Carlos Lopez a09598
bool studio::AudioContainer::get_current_time(double &out)
Carlos Lopez a09598
{
Carlos Lopez a09598
	if(imp) return imp->get_current_time(out);
Carlos Lopez a09598
	else return false;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void AudioContainer::set_offset(const double &s)
d363e8
	{ if(imp) imp->set_offset(s); }
Carlos Lopez a09598
Carlos Lopez a09598
double AudioContainer::get_offset() const
Carlos Lopez a09598
{
Carlos Lopez a09598
	static double zero = 0;
d363e8
	return imp ? imp->get_offset() : zero;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
bool AudioContainer::is_playing() const
d363e8
	{ return imp && imp->playing; }
Carlos Lopez a09598
Carlos Lopez a09598
bool AudioContainer::is_scrubbing() const
d363e8
	{ return imp && imp->is_scrubbing(); }
Carlos Lopez a09598
Carlos Lopez a09598
void AudioContainer::start_scrubbing(double t)
d363e8
	{ if (imp) imp->start_scrubbing(t); }
Carlos Lopez a09598
Carlos Lopez a09598
void AudioContainer::stop_scrubbing()
d363e8
	{ if(imp) imp->stop_scrubbing(); }
Carlos Lopez a09598
Carlos Lopez a09598
void AudioContainer::scrub(double t)
d363e8
	{ if(imp) imp->scrub(t); }
Carlos Lopez a09598
Carlos Lopez a09598
double AudioContainer::scrub_time() const
d363e8
	{ return imp ? imp->scrub_time() : 0; }
Carlos Lopez a09598
Carlos Lopez a09598
bool AudioContainer::isRunning() const
d363e8
	{ return imp && imp->isRunning(); }
Carlos Lopez a09598
Carlos Lopez a09598
bool AudioContainer::isPaused() const
d363e8
	{ return imp && imp->isPaused(); }
Carlos Lopez a09598
Carlos Lopez a09598
//----------- Audio imp information -------------------
Carlos Lopez a09598
Carlos Lopez a09598
bool studio::AudioContainer::AudioImp::load(const std::string &/*filename*/,
Carlos Lopez a09598
											const std::string &/*filedirectory*/)
Carlos Lopez a09598
{
Carlos Lopez a09598
	clear();
Carlos Lopez a09598
	return false;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void studio::AudioContainer::AudioImp::play(double /*t*/)
d363e8
	{ }
Carlos Lopez a09598
Carlos Lopez a09598
void studio::AudioContainer::AudioImp::stop()
Carlos Lopez a09598
{
Carlos Lopez a09598
	delaycon.disconnect();
Carlos Lopez a09598
	playing = false;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void studio::AudioContainer::AudioImp::clear()
Carlos Lopez a09598
{
Carlos Lopez a09598
	channel = 0;
Carlos Lopez a09598
	sample = 0;
Carlos Lopez a09598
	playing = false;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void studio::AudioContainer::AudioImp::start_scrubbing(double /*t*/)
Carlos Lopez a09598
{
d363e8
	if (playing) stop();
Carlos Lopez a09598
	set_scrubbing(true);
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void studio::AudioContainer::AudioImp::stop_scrubbing()
Carlos Lopez a09598
{
d363e8
	if (is_scrubbing()) set_scrubbing(false);
Carlos Lopez a09598
	curscrubpos = 0;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void studio::AudioContainer::AudioImp::scrub(double /*t*/)
d363e8
	{ }