|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshsoundcolumn.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/levelset.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txsheet.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/toonzscene.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tproject.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/sceneproperties.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshsoundlevel.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tstream.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toutputproperties.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tsop.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tconvert.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Jeremy Bullock |
6767be |
#include <qaudioformat></qaudioformat>
|
|
Jeremy Bullock |
6767be |
#include <qaudiodeviceinfo></qaudiodeviceinfo>
|
|
Jeremy Bullock |
6767be |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
// ColumnLevel
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class ColumnLevel {
|
|
Shinya Kitaoka |
120a6e |
TXshSoundLevelP m_soundLevel;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/*!Offsets: in frames. Start offset is a positive number.*/
|
|
Shinya Kitaoka |
120a6e |
int m_startOffset;
|
|
Shinya Kitaoka |
120a6e |
/*!Offsets: in frames. End offset is a positive number(to subtract to..).*/
|
|
Shinya Kitaoka |
120a6e |
int m_endOffset;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Starting frame in the timeline
|
|
Shinya Kitaoka |
120a6e |
int m_startFrame;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! frameRate
|
|
Shinya Kitaoka |
120a6e |
double m_fps;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel(TXshSoundLevel *soundLevel = 0, int startFrame = -1,
|
|
Shinya Kitaoka |
120a6e |
int startOffset = -1, int endOffset = -1, double fps = -1);
|
|
Shinya Kitaoka |
120a6e |
~ColumnLevel();
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *clone() const;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Overridden from TXshLevel
|
|
Shinya Kitaoka |
120a6e |
TXshSoundLevel *getSoundLevel() const { return m_soundLevel.getPointer(); }
|
|
Shinya Kitaoka |
120a6e |
void setSoundLevel(TXshSoundLevelP level) { m_soundLevel = level; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void loadData(TIStream &is);
|
|
Shinya Kitaoka |
120a6e |
void saveData(TOStream &os);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void setStartOffset(int value);
|
|
Shinya Kitaoka |
120a6e |
int getStartOffset() const { return m_startOffset; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void setEndOffset(int value);
|
|
Shinya Kitaoka |
120a6e |
int getEndOffset() const { return m_endOffset; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void setOffsets(int startOffset, int endOffset);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Return the starting frame without offsets.
|
|
Shinya Kitaoka |
120a6e |
void setStartFrame(int frame) { m_startFrame = frame; }
|
|
Shinya Kitaoka |
120a6e |
int getStartFrame() const { return m_startFrame; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Return the ending frame without offsets.
|
|
Shinya Kitaoka |
120a6e |
int getEndFrame() const;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Return frame count without offset.
|
|
Shinya Kitaoka |
120a6e |
int getFrameCount() const;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Return frame count with offset.
|
|
Shinya Kitaoka |
120a6e |
int getVisibleFrameCount() const;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Return start frame with offset.
|
|
Shinya Kitaoka |
120a6e |
int getVisibleStartFrame() const;
|
|
Shinya Kitaoka |
120a6e |
//! Return last frame with offset.
|
|
Shinya Kitaoka |
120a6e |
int getVisibleEndFrame() const;
|
|
Shinya Kitaoka |
120a6e |
//! Updates m_startOfset and m_endOffset.
|
|
Shinya Kitaoka |
120a6e |
void updateFrameRate(double newFrameRate);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void setFrameRate(double fps) { m_fps = fps; }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel::ColumnLevel(TXshSoundLevel *soundLevel, int startFrame,
|
|
Shinya Kitaoka |
120a6e |
int startOffset, int endOffset, double fps)
|
|
Shinya Kitaoka |
120a6e |
: m_soundLevel(soundLevel)
|
|
Shinya Kitaoka |
120a6e |
, m_startOffset(startOffset)
|
|
Shinya Kitaoka |
120a6e |
, m_endOffset(endOffset)
|
|
Shinya Kitaoka |
120a6e |
, m_startFrame(startFrame)
|
|
Shinya Kitaoka |
120a6e |
, m_fps(fps) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel::~ColumnLevel() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *ColumnLevel::clone() const {
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *soundColumnLevel = new ColumnLevel();
|
|
Shinya Kitaoka |
120a6e |
soundColumnLevel->setSoundLevel(getSoundLevel());
|
|
Shinya Kitaoka |
120a6e |
soundColumnLevel->setStartFrame(m_startFrame);
|
|
Shinya Kitaoka |
120a6e |
soundColumnLevel->setStartOffset(m_startOffset);
|
|
Shinya Kitaoka |
120a6e |
soundColumnLevel->setEndOffset(m_endOffset);
|
|
Shinya Kitaoka |
120a6e |
soundColumnLevel->setFrameRate(m_fps);
|
|
Shinya Kitaoka |
120a6e |
return soundColumnLevel;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ColumnLevel::loadData(TIStream &is) {
|
|
Shinya Kitaoka |
120a6e |
std::string tagName;
|
|
Shinya Kitaoka |
120a6e |
is.openChild(tagName);
|
|
Shinya Kitaoka |
120a6e |
if (tagName == "SoundCells") {
|
|
Shinya Kitaoka |
120a6e |
TPersist *p = 0;
|
|
Shinya Kitaoka |
120a6e |
is >> m_startOffset >> m_endOffset >> m_startFrame >> p;
|
|
Shinya Kitaoka |
120a6e |
TXshSoundLevel *xshLevel = dynamic_cast<txshsoundlevel *="">(p);</txshsoundlevel>
|
|
Shinya Kitaoka |
120a6e |
if (xshLevel) m_soundLevel = xshLevel;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
is.closeChild();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ColumnLevel::saveData(TOStream &os) {
|
|
Shinya Kitaoka |
120a6e |
os.child("SoundCells") << getStartOffset() << getEndOffset()
|
|
Shinya Kitaoka |
120a6e |
<< getStartFrame() << m_soundLevel.getPointer();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ColumnLevel::setStartOffset(int value) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_soundLevel) return;
|
|
Shinya Kitaoka |
120a6e |
if (value < 0 || value > getFrameCount() - getEndOffset() - 1) return;
|
|
Shinya Kitaoka |
120a6e |
m_startOffset = value;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ColumnLevel::setEndOffset(int value) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_soundLevel) return;
|
|
Shinya Kitaoka |
120a6e |
if (value < 0 ||
|
|
Shinya Kitaoka |
120a6e |
getStartFrame() + getFrameCount() - value <
|
|
Shinya Kitaoka |
120a6e |
getStartFrame() + getStartOffset() + 1)
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
m_endOffset = value;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ColumnLevel::setOffsets(int startOffset, int endOffset) {
|
|
Shinya Kitaoka |
120a6e |
assert(startOffset > 0 && endOffset > 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (startOffset < 0 || startOffset > getFrameCount() - endOffset - 1) return;
|
|
Shinya Kitaoka |
120a6e |
m_startOffset = startOffset;
|
|
Shinya Kitaoka |
120a6e |
if (endOffset < 0 ||
|
|
Shinya Kitaoka |
120a6e |
getStartFrame() + getFrameCount() - endOffset <
|
|
Shinya Kitaoka |
120a6e |
getStartFrame() + getStartOffset() + 1)
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
m_endOffset = endOffset;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int ColumnLevel::getEndFrame() const {
|
|
Shinya Kitaoka |
120a6e |
if (!m_soundLevel) return -1;
|
|
Shinya Kitaoka |
120a6e |
return getStartFrame() + getFrameCount() - 1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int ColumnLevel::getFrameCount() const {
|
|
Shinya Kitaoka |
120a6e |
if (!m_soundLevel) return -1;
|
|
Shinya Kitaoka |
120a6e |
return m_soundLevel->getFrameCount();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int ColumnLevel::getVisibleFrameCount() const {
|
|
Shinya Kitaoka |
120a6e |
if (!m_soundLevel) return -1;
|
|
Shinya Kitaoka |
120a6e |
return getFrameCount() - getStartOffset() - getEndOffset();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int ColumnLevel::getVisibleStartFrame() const {
|
|
Shinya Kitaoka |
120a6e |
if (!m_soundLevel) return -1;
|
|
Shinya Kitaoka |
120a6e |
return getStartFrame() + getStartOffset();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int ColumnLevel::getVisibleEndFrame() const {
|
|
Shinya Kitaoka |
120a6e |
if (!m_soundLevel) return -1;
|
|
Shinya Kitaoka |
120a6e |
return getVisibleStartFrame() + getVisibleFrameCount() - 1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ColumnLevel::updateFrameRate(double newFrameRate) {
|
|
Shinya Kitaoka |
120a6e |
if (m_fps == newFrameRate) return;
|
|
Shinya Kitaoka |
120a6e |
double fact = (double)newFrameRate / m_fps;
|
|
Shinya Kitaoka |
120a6e |
m_startFrame = tround(m_startFrame * fact);
|
|
Shinya Kitaoka |
120a6e |
m_startOffset = tround(m_startOffset * fact);
|
|
Shinya Kitaoka |
120a6e |
m_endOffset = tround(m_endOffset * fact);
|
|
Shinya Kitaoka |
120a6e |
m_fps = newFrameRate;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool lessThan(const ColumnLevel *s1, const ColumnLevel *s2) {
|
|
Shinya Kitaoka |
120a6e |
return s1->getVisibleStartFrame() < s2->getVisibleStartFrame();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TXshSoundColumn::TXshSoundColumn()
|
|
Shinya Kitaoka |
120a6e |
: m_player(0)
|
|
Shinya Kitaoka |
120a6e |
, m_volume(0.4)
|
|
Shinya Kitaoka |
120a6e |
, m_currentPlaySoundTrack(0)
|
|
Shinya Kitaoka |
120a6e |
, m_isOldVersion(false) {
|
|
Shinya Kitaoka |
120a6e |
m_timer.setInterval(500);
|
|
Shinya Kitaoka |
120a6e |
m_timer.setSingleShot(true);
|
|
Shinya Kitaoka |
120a6e |
m_timer.stop();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimerOut()));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TXshSoundColumn::~TXshSoundColumn() {
|
|
Shinya Kitaoka |
120a6e |
clear();
|
|
Shinya Kitaoka |
120a6e |
if (m_timer.isActive()) {
|
|
Shinya Kitaoka |
120a6e |
m_timer.stop();
|
|
Shinya Kitaoka |
120a6e |
stop();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TXshColumn::ColumnType TXshSoundColumn::getColumnType() const {
|
|
Shinya Kitaoka |
120a6e |
return eSoundType;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TXshSoundColumn::canSetCell(const TXshCell &cell) const {
|
|
Shinya Kitaoka |
120a6e |
return cell.isEmpty() || cell.m_level->getSoundLevel() != 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TXshColumn *TXshSoundColumn::clone() const {
|
|
Shinya Kitaoka |
120a6e |
TXshSoundColumn *column = new TXshSoundColumn();
|
|
Shinya Kitaoka |
120a6e |
column->setVolume(m_volume);
|
|
Shinya Kitaoka |
120a6e |
column->setXsheet(getXsheet());
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_levels.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
column->insertColumnLevel(m_levels.at(i)->clone(), i);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return column;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::assignLevels(const TXshSoundColumn *src) {
|
|
Shinya Kitaoka |
120a6e |
// Svuoto la lista dei livelli
|
|
Shinya Kitaoka |
120a6e |
clear();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int r;
|
|
Shinya Kitaoka |
120a6e |
for (r = src->getFirstRow(); r <= src->getMaxFrame(); r++) {
|
|
Shinya Kitaoka |
120a6e |
int r0, r1;
|
|
Shinya Kitaoka |
120a6e |
if (!src->getLevelRange(r, r0, r1)) continue;
|
|
Shinya Kitaoka |
120a6e |
TXshCell cell = src->getCell(r);
|
|
Shinya Kitaoka |
120a6e |
if (cell.isEmpty()) continue;
|
|
Shinya Kitaoka |
120a6e |
TXshSoundLevel *soundLevel = cell.m_level->getSoundLevel();
|
|
Shinya Kitaoka |
120a6e |
assert(!!soundLevel);
|
|
Shinya Kitaoka |
120a6e |
int startOffset = cell.getFrameId().getNumber();
|
|
Shinya Kitaoka |
120a6e |
int startFrame = r - startOffset;
|
|
Shinya Kitaoka |
120a6e |
int endOffset = startFrame + soundLevel->getFrameCount() - r1 - 1;
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *l =
|
|
Shinya Kitaoka |
120a6e |
new ColumnLevel(soundLevel, startFrame, startOffset, endOffset);
|
|
Shinya Kitaoka |
120a6e |
insertColumnLevel(l);
|
|
Shinya Kitaoka |
120a6e |
r = r1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::loadData(TIStream &is) {
|
|
Shinya Kitaoka |
120a6e |
VersionNumber tnzVersion = is.getVersion();
|
|
Shinya Kitaoka |
120a6e |
if (tnzVersion < VersionNumber(1, 17)) {
|
|
Shinya Kitaoka |
120a6e |
TFilePath path;
|
|
Shinya Kitaoka |
120a6e |
is >> path;
|
|
Shinya Kitaoka |
120a6e |
m_isOldVersion = true;
|
|
Shinya Kitaoka |
120a6e |
int offset = 0;
|
|
Shinya Kitaoka |
120a6e |
is >> offset;
|
|
Shinya Kitaoka |
120a6e |
is >> m_volume;
|
|
Shinya Kitaoka |
120a6e |
if (!is.eos()) {
|
|
Shinya Kitaoka |
120a6e |
int status;
|
|
Shinya Kitaoka |
120a6e |
is >> status;
|
|
Shinya Kitaoka |
120a6e |
setStatusWord(status);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
TXshSoundLevelP level = new TXshSoundLevel(path.getWideName());
|
|
Shinya Kitaoka |
120a6e |
level->setPath(path);
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *l = new ColumnLevel(level.getPointer(), offset, 0, 0);
|
|
Shinya Kitaoka |
120a6e |
insertColumnLevel(l);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
is >> m_volume;
|
|
Shinya Kitaoka |
120a6e |
int levelCount = 0;
|
|
Shinya Kitaoka |
120a6e |
is >> levelCount;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < levelCount; i++) {
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *sl = new ColumnLevel();
|
|
Shinya Kitaoka |
120a6e |
sl->loadData(is);
|
|
Shinya Kitaoka |
120a6e |
insertColumnLevel(sl, i);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (!is.eos()) {
|
|
Shinya Kitaoka |
120a6e |
int status;
|
|
Shinya Kitaoka |
120a6e |
is >> status;
|
|
Shinya Kitaoka |
120a6e |
setStatusWord(status);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::saveData(TOStream &os) {
|
|
Shinya Kitaoka |
120a6e |
os << m_volume;
|
|
Shinya Kitaoka |
120a6e |
int levelsCount = m_levels.size();
|
|
Shinya Kitaoka |
120a6e |
os << levelsCount;
|
|
Shinya Kitaoka |
120a6e |
if (levelsCount == 0) return;
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < levelsCount; i++) m_levels.at(i)->saveData(os);
|
|
Shinya Kitaoka |
120a6e |
os << getStatusWord();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TXshSoundColumn::getRange(int &r0, int &r1) const {
|
|
Shinya Kitaoka |
120a6e |
r0 = getFirstRow();
|
|
Shinya Kitaoka |
120a6e |
r1 = getMaxFrame();
|
|
Shinya Kitaoka |
120a6e |
return r1 - r0 + 1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TXshSoundColumn::getRowCount() const {
|
|
Shinya Kitaoka |
120a6e |
return getMaxFrame() - getFirstRow();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TXshSoundColumn::getMaxFrame() const {
|
|
Shinya Kitaoka |
120a6e |
int levelsCount = m_levels.size();
|
|
Shinya Kitaoka |
120a6e |
if (levelsCount == 0) return -1;
|
|
Shinya Kitaoka |
120a6e |
return m_levels.at(levelsCount - 1)->getVisibleEndFrame();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TXshSoundColumn::getFirstRow() const {
|
|
Shinya Kitaoka |
120a6e |
if (m_levels.size() == 0) return -1;
|
|
Shinya Kitaoka |
120a6e |
return m_levels.at(0)->getVisibleStartFrame();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TXshCell &TXshSoundColumn::getCell(int row) const {
|
|
Shinya Kitaoka |
120a6e |
static TXshCell emptyCell;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *l = getColumnLevelByFrame(row);
|
|
Shinya Kitaoka |
120a6e |
if (row < 0 || row < getFirstRow() || row > getMaxFrame()) {
|
|
Shinya Kitaoka |
120a6e |
if (l) emptyCell.m_level = l->getSoundLevel();
|
|
Shinya Kitaoka |
120a6e |
return emptyCell;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!l) return emptyCell;
|
|
Shinya Kitaoka |
120a6e |
TXshSoundLevel *soundLevel = l->getSoundLevel();
|
|
Shinya Kitaoka |
120a6e |
TXshCell *cell = new TXshCell(soundLevel, TFrameId(row - l->getStartFrame()));
|
|
Shinya Kitaoka |
120a6e |
// La nuova cella aggiunge un reference al TXshSoundLevel; poiche' le celle
|
|
Shinya Kitaoka |
120a6e |
// delle
|
|
Shinya Kitaoka |
120a6e |
// TXshSoundColumn non sono strutture persistenti ma sono strutture dinamiche
|
|
Shinya Kitaoka |
120a6e |
// (vengono ricreate ogni volta) devo occuparmi di fare il release altrimenti
|
|
Shinya Kitaoka |
120a6e |
// il
|
|
Shinya Kitaoka |
120a6e |
// TXshSoundLevel non viene mai buttato.
|
|
Shinya Kitaoka |
120a6e |
soundLevel->release();
|
|
Shinya Kitaoka |
120a6e |
return *cell;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TXshSoundColumn::isCellEmpty(int row) const {
|
|
Shinya Kitaoka |
120a6e |
if (m_levels.empty()) return true;
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *l = getColumnLevelByFrame(row);
|
|
Shinya Kitaoka |
120a6e |
if (!l || !l->getSoundLevel()) return true;
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//--- debug only
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::checkColumn() const {
|
|
Toshihiro Shimizu |
890ddd |
#ifndef NDEBUG
|
|
Shinya Kitaoka |
120a6e |
int size = m_levels.size();
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < size; i++) {
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *level = m_levels.at(i);
|
|
Shinya Kitaoka |
120a6e |
assert(level);
|
|
Shinya Kitaoka |
120a6e |
assert(level->getSoundLevel());
|
|
Shinya Kitaoka |
120a6e |
int start1 = level->getVisibleStartFrame();
|
|
Shinya Kitaoka |
120a6e |
int end1 = level->getVisibleEndFrame();
|
|
Shinya Kitaoka |
120a6e |
assert(start1 <= end1);
|
|
Shinya Kitaoka |
120a6e |
if (i < size - 1) {
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *nextLevel = m_levels.at(i + 1);
|
|
Shinya Kitaoka |
120a6e |
assert(nextLevel);
|
|
Shinya Kitaoka |
120a6e |
assert(nextLevel->getSoundLevel());
|
|
Shinya Kitaoka |
120a6e |
int start2 = nextLevel->getVisibleStartFrame();
|
|
Shinya Kitaoka |
120a6e |
int end2 = nextLevel->getVisibleEndFrame();
|
|
Shinya Kitaoka |
120a6e |
assert(start2 <= end2);
|
|
Shinya Kitaoka |
120a6e |
assert(end1 < start2);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::getCells(int row, int rowCount, TXshCell cells[]) {
|
|
Shinya Kitaoka |
120a6e |
// le celle da settare sono [ra, rb]
|
|
Shinya Kitaoka |
120a6e |
int ra = row;
|
|
Shinya Kitaoka |
120a6e |
int rb = row + rowCount - 1;
|
|
Shinya Kitaoka |
120a6e |
assert(ra <= rb);
|
|
Shinya Kitaoka |
120a6e |
TXshCell *dstCell = cells;
|
|
Shinya Kitaoka |
120a6e |
int r;
|
|
Shinya Kitaoka |
120a6e |
for (r = ra; r <= rb; r++) *cells++ = getCell(r);
|
|
Shinya Kitaoka |
120a6e |
checkColumn();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::setCellInEmptyFrame(int row, const TXshCell &cell) {
|
|
Shinya Kitaoka |
120a6e |
if (cell.isEmpty()) return;
|
|
Shinya Kitaoka |
120a6e |
TXshSoundLevel *soundLevel = cell.getSoundLevel();
|
|
Shinya Kitaoka |
120a6e |
if (!soundLevel) return;
|
|
Shinya Kitaoka |
120a6e |
int startOffset = cell.getFrameId().getNumber();
|
|
Shinya Kitaoka |
120a6e |
int startFrame = row - startOffset;
|
|
Shinya Kitaoka |
120a6e |
int endOffset = startFrame + soundLevel->getFrameCount() - 1 - row;
|
|
Shinya Kitaoka |
120a6e |
insertColumnLevel(
|
|
Shinya Kitaoka |
120a6e |
new ColumnLevel(soundLevel, startFrame, startOffset, endOffset));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TXshSoundColumn::setCell(int row, const TXshCell &cell) {
|
|
Shinya Kitaoka |
120a6e |
return setCell(row, cell, false);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TXshSoundColumn::setCell(int row, const TXshCell &cell,
|
|
Shinya Kitaoka |
120a6e |
bool updateSequence) {
|
|
Shinya Kitaoka |
120a6e |
if (!canSetCell(cell)) return false;
|
|
Shinya Kitaoka |
120a6e |
assert(row >= 0);
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *lBefore = getColumnLevelByFrame(row - 1);
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *l = getColumnLevelByFrame(row);
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *lNext = getColumnLevelByFrame(row + 1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Se non devo fare un update della sequenzialita' e la cella e' uguale a
|
|
Shinya Kitaoka |
120a6e |
// quella gia' esistente ritorno.
|
|
Shinya Kitaoka |
120a6e |
if (!updateSequence && l && l->getSoundLevel() == cell.getSoundLevel() &&
|
|
Shinya Kitaoka |
120a6e |
row - l->getStartFrame() == cell.getFrameId().getNumber())
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool isBeforeLevelInSequence =
|
|
Shinya Kitaoka |
120a6e |
(lBefore && lBefore->getSoundLevel() == cell.getSoundLevel() &&
|
|
Shinya Kitaoka |
120a6e |
row - lBefore->getStartFrame() == cell.getFrameId().getNumber());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool isNextLevelInSequence =
|
|
Shinya Kitaoka |
120a6e |
(lNext && lNext->getSoundLevel() == cell.getSoundLevel() &&
|
|
Shinya Kitaoka |
120a6e |
row - lNext->getStartFrame() == cell.getFrameId().getNumber());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Modifico solo l'endOffset del BeforeLevel
|
|
Shinya Kitaoka |
120a6e |
if (isBeforeLevelInSequence) {
|
|
Shinya Kitaoka |
120a6e |
int oldEndOffset = lBefore->getEndOffset();
|
|
Shinya Kitaoka |
120a6e |
int endOffset = (lBefore->getVisibleEndFrame() != row) ? oldEndOffset - 1
|
|
Shinya Kitaoka |
120a6e |
: oldEndOffset;
|
|
Shinya Kitaoka |
120a6e |
if (isNextLevelInSequence) {
|
|
Shinya Kitaoka |
120a6e |
endOffset = lNext->getEndOffset();
|
|
Shinya Kitaoka |
120a6e |
// Se precedente e successivo sono diversi elimino il successivo (caso in
|
|
Shinya Kitaoka |
120a6e |
// cui inserisci un frame in successione su una cella vuota)
|
|
Shinya Kitaoka |
120a6e |
if (lNext != lBefore) removeColumnLevel(lNext);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (l && l != lBefore) {
|
|
Shinya Kitaoka |
120a6e |
if (l->getVisibleFrameCount() == 1)
|
|
Shinya Kitaoka |
120a6e |
removeColumnLevel(l);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
l->setStartOffset(l->getStartOffset() + 1);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
lBefore->setEndOffset(endOffset);
|
|
Shinya Kitaoka |
120a6e |
checkColumn();
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// Modifico solo lo startOffset del NextLevel
|
|
Shinya Kitaoka |
120a6e |
if (isNextLevelInSequence) {
|
|
Shinya Kitaoka |
120a6e |
int oldStartOffset = lNext->getStartOffset();
|
|
Shinya Kitaoka |
120a6e |
int startOffset = (lNext->getVisibleStartFrame() != row)
|
|
Shinya Kitaoka |
120a6e |
? oldStartOffset - 1
|
|
Shinya Kitaoka |
120a6e |
: oldStartOffset;
|
|
Shinya Kitaoka |
120a6e |
if (l && l != lNext) {
|
|
Shinya Kitaoka |
120a6e |
if (l->getVisibleFrameCount() == 1)
|
|
Shinya Kitaoka |
120a6e |
removeColumnLevel(l);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
l->setEndOffset(l->getEndOffset() + 1);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
lNext->setStartOffset(startOffset);
|
|
Shinya Kitaoka |
120a6e |
checkColumn();
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// I Frame non sono in successione quindi devo inserire la cella in frame un
|
|
Shinya Kitaoka |
120a6e |
// vuoto:
|
|
Shinya Kitaoka |
120a6e |
clearCells(row, 1);
|
|
Shinya Kitaoka |
120a6e |
setCellInEmptyFrame(row, cell);
|
|
Shinya Kitaoka |
120a6e |
checkColumn();
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TXshSoundColumn::setCells(int row, int rowCount, const TXshCell cells[]) {
|
|
Shinya Kitaoka |
120a6e |
assert(row >= 0);
|
|
Shinya Kitaoka |
120a6e |
// le celle da settare sono [ra, rb]
|
|
Shinya Kitaoka |
120a6e |
int ra = row;
|
|
Shinya Kitaoka |
120a6e |
int rb = row + rowCount - 1;
|
|
Shinya Kitaoka |
120a6e |
assert(ra <= rb);
|
|
Shinya Kitaoka |
120a6e |
bool ret = false;
|
|
Shinya Kitaoka |
120a6e |
int r;
|
|
Shinya Kitaoka |
120a6e |
for (r = ra; r <= rb; r++) {
|
|
Shinya Kitaoka |
120a6e |
bool isOneCellSet = setCell(r, cells[r - ra]);
|
|
Shinya Kitaoka |
120a6e |
if (isOneCellSet) ret = isOneCellSet;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::insertEmptyCells(int row, int rowCount) {
|
|
Shinya Kitaoka |
120a6e |
if (m_levels.isEmpty())
|
|
Shinya Kitaoka |
120a6e |
return; // se la colonna e' vuota non devo inserire celle
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int ra = row;
|
|
Shinya Kitaoka |
120a6e |
int rb = row + rowCount - 1;
|
|
Shinya Kitaoka |
120a6e |
assert(ra <= rb);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Se il livello nella riga ra inizia prima devo "spezzarlo"
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *l = getColumnLevelByFrame(ra);
|
|
Shinya Kitaoka |
120a6e |
if (l && l->getVisibleStartFrame() < ra) {
|
|
Shinya Kitaoka |
120a6e |
int oldOffset = l->getEndOffset();
|
|
Shinya Kitaoka |
120a6e |
l->setEndOffset(oldOffset + l->getVisibleEndFrame() - ra + 1);
|
|
Shinya Kitaoka |
120a6e |
insertColumnLevel(new ColumnLevel(l->getSoundLevel(), l->getStartFrame(),
|
|
Shinya Kitaoka |
120a6e |
row - l->getStartFrame(), oldOffset));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Sposto il first frame di tutti i livelli successivi ad ra.
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = m_levels.count() - 1; i >= 0; i--) {
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *cl = m_levels.at(i);
|
|
Shinya Kitaoka |
120a6e |
if (cl->getVisibleStartFrame() < ra) continue;
|
|
Shinya Kitaoka |
120a6e |
cl->setStartFrame(cl->getStartFrame() + rowCount);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
checkColumn();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::removeCells(int row, int rowCount, bool shift) {
|
|
Shinya Kitaoka |
120a6e |
// le celle da cancellare sono [ra, rb]
|
|
Shinya Kitaoka |
120a6e |
int ra = row;
|
|
Shinya Kitaoka |
120a6e |
int rb = row + rowCount - 1;
|
|
Shinya Kitaoka |
120a6e |
assert(ra <= rb);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = m_levels.size() - 1; i >= 0; i--) {
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *l = m_levels.at(i);
|
|
Shinya Kitaoka |
120a6e |
if (!l) continue; // Non dovrebbe accadere!
|
|
Shinya Kitaoka |
120a6e |
int visibleStartFrame = l->getVisibleStartFrame();
|
|
Shinya Kitaoka |
120a6e |
int visibleEndFrame = l->getVisibleEndFrame();
|
|
Shinya Kitaoka |
120a6e |
// Fuori dal range da tagliare.
|
|
Shinya Kitaoka |
120a6e |
if (visibleStartFrame > rb || visibleEndFrame < ra) continue;
|
|
Shinya Kitaoka |
120a6e |
int newEndOffset = l->getEndFrame() - ra + 1;
|
|
Shinya Kitaoka |
120a6e |
int newStartOffset = rb - l->getStartFrame() + 1;
|
|
Shinya Kitaoka |
120a6e |
// Il livello contiene il range da cancellare: devo "spezzare" il livello in
|
|
Shinya Kitaoka |
120a6e |
// due.
|
|
Shinya Kitaoka |
120a6e |
if (visibleStartFrame < ra && visibleEndFrame > rb) {
|
|
Shinya Kitaoka |
120a6e |
int oldEndOffset = l->getEndOffset();
|
|
Shinya Kitaoka |
120a6e |
l->setEndOffset(newEndOffset);
|
|
Shinya Kitaoka |
120a6e |
insertColumnLevel(new ColumnLevel(l->getSoundLevel(), l->getStartFrame(),
|
|
Shinya Kitaoka |
120a6e |
newStartOffset, oldEndOffset));
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (visibleStartFrame < ra) l->setEndOffset(newEndOffset);
|
|
Shinya Kitaoka |
120a6e |
if (visibleEndFrame > rb) l->setStartOffset(newStartOffset);
|
|
Shinya Kitaoka |
120a6e |
// Il livello e' contenuto nel range da cancellare: lo rimuovo.
|
|
Shinya Kitaoka |
120a6e |
if (visibleStartFrame >= ra && visibleEndFrame <= rb) removeColumnLevel(l);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (shift) {
|
|
Shinya Kitaoka |
120a6e |
for (i = m_levels.size() - 1; i >= 0; i--) {
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *l = m_levels.at(i);
|
|
Shinya Kitaoka |
120a6e |
if (!l) continue; // Non dovrebbe accadere!
|
|
Shinya Kitaoka |
120a6e |
int visibleStartFrame = l->getVisibleStartFrame();
|
|
Shinya Kitaoka |
120a6e |
int visibleEndFrame = l->getVisibleEndFrame();
|
|
Shinya Kitaoka |
120a6e |
if (visibleStartFrame > ra)
|
|
Shinya Kitaoka |
120a6e |
l->setStartFrame(l->getStartFrame() - rowCount);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Devo controllare se il livello precedente il taglio e quello successivo
|
|
Shinya Kitaoka |
120a6e |
// sono in sequenza
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *beforeL = getColumnLevelByFrame(ra - 1);
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *nextL = getColumnLevelByFrame(ra);
|
|
Shinya Kitaoka |
120a6e |
if (beforeL && nextL &&
|
|
Shinya Kitaoka |
120a6e |
beforeL->getSoundLevel() == nextL->getSoundLevel() &&
|
|
Shinya Kitaoka |
120a6e |
beforeL->getStartFrame() == nextL->getStartFrame()) {
|
|
Shinya Kitaoka |
120a6e |
beforeL->setEndOffset(nextL->getEndOffset());
|
|
Shinya Kitaoka |
120a6e |
removeColumnLevel(nextL);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
checkColumn();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::clearCells(int row, int rowCount) {
|
|
Shinya Kitaoka |
120a6e |
if (rowCount <= 0) return;
|
|
Shinya Kitaoka |
120a6e |
if (m_levels.isEmpty())
|
|
Shinya Kitaoka |
120a6e |
return; // se la colonna e' vuota non devo "sbiancare" celle
|
|
Shinya Kitaoka |
120a6e |
removeCells(row, rowCount, false);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::removeCells(int row, int rowCount) {
|
|
Shinya Kitaoka |
120a6e |
removeCells(row, rowCount, true);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::updateCells(int row, int rowCount) {
|
|
Shinya Kitaoka |
120a6e |
int r;
|
|
Shinya Kitaoka |
120a6e |
for (r = row; r < row + rowCount; r++) {
|
|
Shinya Kitaoka |
120a6e |
TXshCell cell = getCell(r);
|
|
Shinya Kitaoka |
120a6e |
setCell(row, cell, true);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TXshSoundColumn::modifyCellRange(int row, int delta,
|
|
Shinya Kitaoka |
120a6e |
bool modifyStartValue) {
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *l = getColumnLevelByFrame(row);
|
|
Shinya Kitaoka |
120a6e |
if (!l) return -1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int startVisibleFrame = l->getVisibleStartFrame();
|
|
Shinya Kitaoka |
120a6e |
int endVisibleFrame = l->getVisibleEndFrame();
|
|
Shinya Kitaoka |
120a6e |
// Non dovrebbe mai accadere, metto un controllo di sicurezza.
|
|
Shinya Kitaoka |
120a6e |
if (startVisibleFrame != row && endVisibleFrame != row) return -1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int r0 = delta > 0 ? row : row + delta;
|
|
Shinya Kitaoka |
120a6e |
int r1 = delta > 0 ? row + delta : row;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int r;
|
|
Shinya Kitaoka |
120a6e |
for (r = r0; r <= r1; r++) {
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *oldL = getColumnLevelByFrame(r);
|
|
Shinya Kitaoka |
120a6e |
if (!oldL || oldL == l) continue;
|
|
Shinya Kitaoka |
120a6e |
int visibleStartFrame = oldL->getVisibleStartFrame();
|
|
Shinya Kitaoka |
120a6e |
int visibleEndFrame = oldL->getVisibleEndFrame();
|
|
Shinya Kitaoka |
120a6e |
if (visibleStartFrame >= r0 && visibleEndFrame <= r1)
|
|
Shinya Kitaoka |
120a6e |
removeColumnLevel(oldL);
|
|
Shinya Kitaoka |
120a6e |
if (visibleStartFrame <= r0)
|
|
Shinya Kitaoka |
120a6e |
oldL->setEndOffset(oldL->getEndOffset() + visibleEndFrame - r0 + 1);
|
|
Shinya Kitaoka |
120a6e |
if (visibleEndFrame >= r1)
|
|
Shinya Kitaoka |
120a6e |
oldL->setStartOffset(oldL->getStartOffset() + r1 - visibleStartFrame + 1);
|
|
Shinya Kitaoka |
120a6e |
r = visibleEndFrame;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (modifyStartValue) {
|
|
Shinya Kitaoka |
120a6e |
// Evito che vada oltre il limite infieriore
|
|
Shinya Kitaoka |
120a6e |
if (endVisibleFrame < startVisibleFrame + delta)
|
|
Shinya Kitaoka |
120a6e |
delta = endVisibleFrame - startVisibleFrame;
|
|
Shinya Kitaoka |
120a6e |
int newStartOffset = l->getStartOffset() + delta;
|
|
Shinya Kitaoka |
120a6e |
// Evito che vada oltre il limite superiore
|
|
Shinya Kitaoka |
120a6e |
if (newStartOffset < 0) newStartOffset = 0;
|
|
Shinya Kitaoka |
120a6e |
l->setStartOffset(newStartOffset);
|
|
Shinya Kitaoka |
120a6e |
checkColumn();
|
|
Shinya Kitaoka |
120a6e |
getXsheet()->updateFrameCount();
|
|
Shinya Kitaoka |
120a6e |
return l->getVisibleStartFrame();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Evito che vada oltre il limite superiore
|
|
Shinya Kitaoka |
120a6e |
if (startVisibleFrame > endVisibleFrame + delta)
|
|
Shinya Kitaoka |
120a6e |
delta = startVisibleFrame - endVisibleFrame;
|
|
Shinya Kitaoka |
120a6e |
// Evito che vada oltre il limite inferiore
|
|
Shinya Kitaoka |
120a6e |
int newEndOffset = l->getEndOffset() - delta;
|
|
Shinya Kitaoka |
120a6e |
if (newEndOffset < 0) newEndOffset = 0;
|
|
Shinya Kitaoka |
120a6e |
l->setEndOffset(newEndOffset);
|
|
Shinya Kitaoka |
120a6e |
checkColumn();
|
|
Shinya Kitaoka |
120a6e |
getXsheet()->updateFrameCount();
|
|
Shinya Kitaoka |
120a6e |
return l->getVisibleEndFrame();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TXshSoundColumn::getLevelRange(int row, int &r0, int &r1) const {
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *l = getColumnLevelByFrame(row);
|
|
Shinya Kitaoka |
120a6e |
if (!l) {
|
|
Shinya Kitaoka |
120a6e |
r0 = r1 = row;
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
r0 = l->getVisibleStartFrame();
|
|
Shinya Kitaoka |
120a6e |
r1 = l->getVisibleEndFrame();
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TXshSoundColumn::getLevelRangeWithoutOffset(int row, int &r0,
|
|
Shinya Kitaoka |
120a6e |
int &r1) const {
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *l = getColumnLevelByFrame(row);
|
|
Shinya Kitaoka |
120a6e |
if (!l) {
|
|
Shinya Kitaoka |
120a6e |
r0 = r1 = row;
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
r0 = l->getStartFrame();
|
|
Shinya Kitaoka |
120a6e |
r1 = l->getEndFrame();
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::setXsheet(TXsheet *xsheet) {
|
|
Shinya Kitaoka |
120a6e |
TXshColumn::setXsheet(xsheet);
|
|
Shinya Kitaoka |
120a6e |
ToonzScene *scene = xsheet->getScene();
|
|
Shinya Kitaoka |
120a6e |
if (!scene || m_levels.empty()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_isOldVersion) {
|
|
Shinya Kitaoka |
120a6e |
assert(m_levels.size() == 1);
|
|
Shinya Kitaoka |
120a6e |
scene->getLevelSet()->insertLevel(m_levels.at(0)->getSoundLevel());
|
|
Shinya Kitaoka |
120a6e |
m_isOldVersion = false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TOutputProperties *properties = scene->getProperties()->getOutputProperties();
|
|
Shinya Kitaoka |
120a6e |
setFrameRate(properties->getFrameRate());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::setFrameRate(double fps) {
|
|
Shinya Kitaoka |
120a6e |
if (m_levels.empty()) return;
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_levels.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *column = m_levels.at(i);
|
|
Shinya Kitaoka |
120a6e |
TXshSoundLevel *soundLevel = column->getSoundLevel();
|
|
Shinya Kitaoka |
120a6e |
if (soundLevel->getFrameRate() != fps) soundLevel->setFrameRate(fps);
|
|
Shinya Kitaoka |
120a6e |
column->setFrameRate(fps);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::updateFrameRate(double fps) {
|
|
Shinya Kitaoka |
120a6e |
if (m_levels.empty()) return;
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_levels.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *column = m_levels.at(i);
|
|
Shinya Kitaoka |
120a6e |
TXshSoundLevel *soundLevel = column->getSoundLevel();
|
|
Shinya Kitaoka |
120a6e |
double oldFps = soundLevel->getFrameRate();
|
|
Shinya Kitaoka |
120a6e |
if (oldFps != fps) soundLevel->setFrameRate(fps);
|
|
Shinya Kitaoka |
120a6e |
column->updateFrameRate(fps);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::setVolume(double value) {
|
|
Shinya Kitaoka |
120a6e |
m_volume = tcrop<double>(value, 0.0, 1.0);</double>
|
|
Shinya Kitaoka |
120a6e |
if (m_player && m_player->isPlaying())
|
|
|
a9c425 |
#ifndef _WIN32
|
|
Shinya Kitaoka |
120a6e |
m_player->setVolume(m_volume);
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
stop();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double TXshSoundColumn::getVolume() const { return m_volume; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::play(TSoundTrackP soundtrack, int s0, int s1, bool loop) {
|
|
Shinya Kitaoka |
120a6e |
if (!TSoundOutputDevice::installed()) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!m_player) m_player = new TSoundOutputDevice();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_player) {
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
|
a9c425 |
#ifndef _WIN32
|
|
Jeremy Bullock |
6767be |
m_player->prepareVolume(m_volume);
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP mixedTrack = soundtrack;
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP mixedTrack = TSoundTrack::create(
|
|
Shinya Kitaoka |
120a6e |
soundtrack->getFormat(), soundtrack->getSampleCount());
|
|
Shinya Kitaoka |
120a6e |
mixedTrack = TSop::mix(mixedTrack, soundtrack, 1.0, m_volume);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
m_player->play(mixedTrack, s0, s1, loop);
|
|
Shinya Kitaoka |
120a6e |
m_currentPlaySoundTrack = mixedTrack;
|
|
|
a9c425 |
#ifdef _WIN32
|
|
Shinya Kitaoka |
120a6e |
m_timer.start();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
} catch (TSoundDeviceException &) {
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::play(ColumnLevel *columnLevel, int currentFrame) {
|
|
Shinya Kitaoka |
120a6e |
assert(columnLevel);
|
|
Shinya Kitaoka |
120a6e |
TXshSoundLevel *soundLevel = columnLevel->getSoundLevel();
|
|
Shinya Kitaoka |
120a6e |
int offset = 0;
|
|
Shinya Kitaoka |
120a6e |
int startFrame = currentFrame - columnLevel->getStartFrame();
|
|
Shinya Kitaoka |
120a6e |
int endFrame = soundLevel->getFrameCount() - columnLevel->getEndOffset();
|
|
Shinya Kitaoka |
120a6e |
int spf = soundLevel->getSamplePerFrame();
|
|
Shinya Kitaoka |
120a6e |
int s0 = startFrame * spf;
|
|
Shinya Kitaoka |
120a6e |
int s1 = endFrame * spf;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!soundLevel->getSoundTrack()) return;
|
|
Shinya Kitaoka |
120a6e |
play(soundLevel->getSoundTrack(), s0, s1, false);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::play(int currentFrame) {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP soundTrack = getOverallSoundTrack(currentFrame);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!soundTrack) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int spf = m_levels.at(0)->getSoundLevel()->getSamplePerFrame();
|
|
Shinya Kitaoka |
120a6e |
int startFrame = (currentFrame - getFirstRow());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int s0 = startFrame * spf;
|
|
Shinya Kitaoka |
120a6e |
int s1 = getMaxFrame() * spf;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
play(soundTrack, s0, s1, false);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::stop() {
|
|
Shinya Kitaoka |
120a6e |
if (m_player) {
|
|
Shinya Kitaoka |
120a6e |
m_player->stop();
|
|
Shinya Kitaoka |
120a6e |
m_player->close();
|
|
Shinya Kitaoka |
120a6e |
m_player = 0;
|
|
Shinya Kitaoka |
120a6e |
m_currentPlaySoundTrack = TSoundTrackP();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TXshSoundColumn::isPlaying() const {
|
|
Shinya Kitaoka |
120a6e |
return m_player && m_player->isPlaying();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::insertColumnLevel(ColumnLevel *columnLevel, int index) {
|
|
Shinya Kitaoka |
120a6e |
if (index == -1) index = m_levels.size();
|
|
Shinya Kitaoka |
120a6e |
m_levels.insert(index, columnLevel);
|
|
Shinya Kitaoka |
120a6e |
qSort(m_levels.begin(), m_levels.end(), lessThan);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::removeColumnLevel(ColumnLevel *columnLevel) {
|
|
Shinya Kitaoka |
120a6e |
if (!columnLevel) return;
|
|
Shinya Kitaoka |
120a6e |
int index = m_levels.indexOf(columnLevel);
|
|
Shinya Kitaoka |
120a6e |
if (index == -1) return;
|
|
Shinya Kitaoka |
120a6e |
m_levels.removeAt(index);
|
|
Shinya Kitaoka |
120a6e |
delete columnLevel;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *TXshSoundColumn::getColumnLevelByFrame(int frame) const {
|
|
Shinya Kitaoka |
120a6e |
int levelCount = m_levels.size();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < levelCount; i++) {
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *l = m_levels.at(i);
|
|
Shinya Kitaoka |
120a6e |
TXshSoundLevel *soundLevel = l->getSoundLevel();
|
|
Shinya Kitaoka |
120a6e |
int startFrame = l->getStartFrame() + l->getStartOffset();
|
|
Shinya Kitaoka |
120a6e |
int frameCount =
|
|
Shinya Kitaoka |
120a6e |
soundLevel->getFrameCount() - l->getStartOffset() - l->getEndOffset();
|
|
Shinya Kitaoka |
120a6e |
if (startFrame <= frame && startFrame + frameCount > frame) return l;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *TXshSoundColumn::getColumnLevel(int index) {
|
|
Shinya Kitaoka |
120a6e |
if (index < 0 || index >= m_levels.count()) return 0;
|
|
Shinya Kitaoka |
120a6e |
return m_levels.at(index);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TXshSoundColumn::getColumnLevelIndex(ColumnLevel *columnLevel) const {
|
|
Shinya Kitaoka |
120a6e |
return m_levels.indexOf(columnLevel);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::clear() {
|
|
Shinya Kitaoka |
120a6e |
int sequenceCount = m_levels.size();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < sequenceCount; i++) {
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *s = m_levels[i];
|
|
Shinya Kitaoka |
120a6e |
delete s;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_levels.clear();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::onTimerOut() {
|
|
|
a9c425 |
#ifdef _WIN32
|
|
Shinya Kitaoka |
120a6e |
if (m_player && m_player->isAllQueuedItemsPlayed()) stop();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TXshSoundColumn::scrub(int fromFrame, int toFrame) {
|
|
Shinya Kitaoka |
120a6e |
if (!isCamstandVisible()) return;
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP soundTrack = getOverallSoundTrack(fromFrame, toFrame + 1);
|
|
Shinya Kitaoka |
120a6e |
if (!soundTrack) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
play(soundTrack, 0, soundTrack->getSampleCount(), false);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TXshSoundColumn::getOverallSoundTrack(int fromFrame, int toFrame,
|
|
Shinya Kitaoka |
120a6e |
double fps,
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackFormat format) {
|
|
Shinya Kitaoka |
120a6e |
int levelsCount = m_levels.size();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (levelsCount == 0) return 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (fps == -1) fps = m_levels[0]->getSoundLevel()->getFrameRate();
|
|
Shinya Kitaoka |
120a6e |
if (fromFrame == -1) fromFrame = getFirstRow();
|
|
Shinya Kitaoka |
120a6e |
if (toFrame == -1) toFrame = getMaxFrame();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (format.m_sampleRate == 0) {
|
|
Shinya Kitaoka |
120a6e |
// Found the best format inside the soundsequences
|
|
Shinya Kitaoka |
120a6e |
int sampleRate = 0;
|
|
Shinya Kitaoka |
120a6e |
int bitsPerSample = 8;
|
|
Shinya Kitaoka |
120a6e |
int channels = 1;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < levelsCount; i++) {
|
|
Shinya Kitaoka |
120a6e |
TXshSoundLevel *soundLevel = m_levels.at(i)->getSoundLevel();
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP soundTrack = soundLevel->getSoundTrack();
|
|
Shinya Kitaoka |
120a6e |
if (soundTrack.getPointer() == 0) continue;
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackFormat f = soundTrack->getFormat();
|
|
Shinya Kitaoka |
120a6e |
if ((int)f.m_sampleRate > sampleRate) {
|
|
Shinya Kitaoka |
120a6e |
format.m_sampleRate = f.m_sampleRate;
|
|
Shinya Kitaoka |
120a6e |
sampleRate = f.m_sampleRate;
|
|
Shinya Kitaoka |
120a6e |
format.m_channelCount = f.m_channelCount;
|
|
Shinya Kitaoka |
120a6e |
channels = f.m_channelCount;
|
|
Shinya Kitaoka |
120a6e |
format.m_signedSample = f.m_signedSample;
|
|
Shinya Kitaoka |
120a6e |
format.m_bitPerSample = f.m_bitPerSample;
|
|
Shinya Kitaoka |
120a6e |
bitsPerSample = f.m_bitPerSample;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (f.m_channelCount > channels) {
|
|
Shinya Kitaoka |
120a6e |
format.m_channelCount = f.m_channelCount;
|
|
Shinya Kitaoka |
120a6e |
channels = f.m_channelCount;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (f.m_bitPerSample > bitsPerSample) {
|
|
Shinya Kitaoka |
120a6e |
format.m_bitPerSample = f.m_bitPerSample;
|
|
Shinya Kitaoka |
120a6e |
bitsPerSample = f.m_bitPerSample;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// If there is no soundSequence I use a default format
|
|
Shinya Kitaoka |
120a6e |
if (levelsCount == 0 || format.m_sampleRate == 0) {
|
|
Shinya Kitaoka |
120a6e |
format.m_sampleRate = 44100;
|
|
Shinya Kitaoka |
120a6e |
format.m_bitPerSample = 16;
|
|
Shinya Kitaoka |
120a6e |
format.m_channelCount = 1;
|
|
Shinya Kitaoka |
120a6e |
format.m_signedSample = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Jeremy Bullock |
6767be |
// We prefer to have 22050 as a maximum sampleRate (to avoid crashes or
|
|
Jeremy Bullock |
6767be |
// another issues)
|
|
|
a9c425 |
#ifdef _WIN32
|
|
Shinya Kitaoka |
120a6e |
if (format.m_sampleRate >= 44100) format.m_sampleRate = 22050;
|
|
Jeremy Bullock |
6767be |
#else
|
|
Jeremy Bullock |
6767be |
QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
|
|
Jeremy Bullock |
6767be |
QList<int> ssrs = info.supportedSampleRates();</int>
|
|
Jeremy Bullock |
6767be |
if (!ssrs.contains(format.m_sampleRate)) format.m_sampleRate = 44100;
|
|
Jeremy Bullock |
6767be |
QAudioFormat qFormat;
|
|
Jeremy Bullock |
6767be |
qFormat.setSampleRate(format.m_sampleRate);
|
|
Jeremy Bullock |
6767be |
qFormat.setSampleType(format.m_signedSample ? QAudioFormat::SignedInt
|
|
Jeremy Bullock |
6767be |
: QAudioFormat::UnSignedInt);
|
|
Jeremy Bullock |
6767be |
qFormat.setSampleSize(format.m_bitPerSample);
|
|
Jeremy Bullock |
6767be |
qFormat.setCodec("audio/pcm");
|
|
Jeremy Bullock |
6767be |
qFormat.setChannelCount(format.m_channelCount);
|
|
Jeremy Bullock |
6767be |
qFormat.setByteOrder(QAudioFormat::LittleEndian);
|
|
Jeremy Bullock |
6767be |
if (!info.isFormatSupported((qFormat))) {
|
|
Jeremy Bullock |
6767be |
qFormat = info.nearestFormat(qFormat);
|
|
Jeremy Bullock |
6767be |
format.m_bitPerSample = qFormat.sampleSize();
|
|
Jeremy Bullock |
6767be |
format.m_channelCount = qFormat.channelCount();
|
|
Jeremy Bullock |
6767be |
format.m_sampleRate = qFormat.sampleRate();
|
|
Jeremy Bullock |
6767be |
if (qFormat.sampleType() == QAudioFormat::SignedInt)
|
|
Jeremy Bullock |
6767be |
format.m_signedSample = true;
|
|
Jeremy Bullock |
6767be |
else
|
|
Jeremy Bullock |
6767be |
format.m_signedSample = false;
|
|
Jeremy Bullock |
6767be |
}
|
|
Jeremy Bullock |
6767be |
#endif
|
|
Shinya Kitaoka |
120a6e |
// Create the soundTrack
|
|
Shinya Kitaoka |
120a6e |
double samplePerFrame = format.m_sampleRate / fps;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// In seconds
|
|
Shinya Kitaoka |
120a6e |
double duration = double(toFrame - fromFrame) / fps;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Seconds to Sample (it is more accurate than using sampleCount
|
|
Shinya Kitaoka |
120a6e |
double dsamp = duration * format.m_sampleRate;
|
|
Shinya Kitaoka |
120a6e |
TINT32 lsamp = (TINT32)dsamp;
|
|
Shinya Kitaoka |
120a6e |
if ((double)lsamp < dsamp - TConsts::epsilon) lsamp++;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP overallSoundTrack;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
overallSoundTrack = TSoundTrack::create(format, lsamp);
|
|
Shinya Kitaoka |
120a6e |
} catch (TSoundDeviceException &) {
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Blank the whole track
|
|
Shinya Kitaoka |
120a6e |
overallSoundTrack->blank(0, lsamp);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (levelsCount == 0) return overallSoundTrack;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < levelsCount; i++) {
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *l = m_levels.at(i);
|
|
Shinya Kitaoka |
120a6e |
TXshSoundLevel *soundLevel = l->getSoundLevel();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Check if the soundtrack is inside the frame Range.
|
|
Shinya Kitaoka |
120a6e |
int levelStartFrame = l->getStartFrame() + l->getStartOffset();
|
|
Shinya Kitaoka |
120a6e |
int levelEndFrame = levelStartFrame + soundLevel->getFrameCount() -
|
|
Shinya Kitaoka |
120a6e |
l->getStartOffset() - l->getEndOffset();
|
|
Shinya Kitaoka |
120a6e |
// If the soundSequence is completely before fromFrame I will skip it
|
|
Shinya Kitaoka |
120a6e |
if ((levelStartFrame < fromFrame && levelEndFrame < fromFrame)) continue;
|
|
Shinya Kitaoka |
120a6e |
// If the soundSequence is after toFrame I don't check the others (that
|
|
Shinya Kitaoka |
120a6e |
// comes later..)
|
|
Shinya Kitaoka |
120a6e |
if ((levelStartFrame > toFrame && levelEndFrame > toFrame)) break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Extract the right soundTrack (using the offsets)
|
|
Shinya Kitaoka |
120a6e |
// (pay attention to convert it before)
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP s = soundLevel->getSoundTrack();
|
|
Shinya Kitaoka |
120a6e |
if (!s) continue;
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP soundTrack = TSop::convert(s, format);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int s0delta = 0;
|
|
Shinya Kitaoka |
120a6e |
if (fromFrame > levelStartFrame) s0delta = fromFrame - levelStartFrame;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int s0 = (l->getStartOffset() + s0delta) * samplePerFrame;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int s1delta = 0;
|
|
Shinya Kitaoka |
120a6e |
if (toFrame < levelEndFrame) s1delta = levelEndFrame - toFrame;
|
|
Shinya Kitaoka |
120a6e |
int s1 = (soundLevel->getFrameCount() - l->getEndOffset() - s1delta) *
|
|
Shinya Kitaoka |
120a6e |
samplePerFrame;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (s1 > 0 && s1 >= s0) {
|
|
Shinya Kitaoka |
120a6e |
soundTrack = soundTrack->extract(s0, s1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Copy the sound track
|
|
Shinya Kitaoka |
120a6e |
overallSoundTrack->copy(
|
|
Shinya Kitaoka |
120a6e |
soundTrack,
|
|
Shinya Kitaoka |
120a6e |
int((levelStartFrame - fromFrame) *
|
|
Shinya Kitaoka |
120a6e |
samplePerFrame)); // The int cast is IMPORTANT, since
|
|
Shinya Kitaoka |
120a6e |
} // there are 2 overloads (int & double)
|
|
Shinya Kitaoka |
120a6e |
} // with DIFFERENT SCALES. We mean the
|
|
Shinya Kitaoka |
120a6e |
// SAMPLES-BASED one.
|
|
Shinya Kitaoka |
120a6e |
return overallSoundTrack;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TXshSoundColumn::mixingTogether(
|
|
Shinya Kitaoka |
120a6e |
const std::vector<txshsoundcolumn *=""> &vect, int fromFrame, int toFrame,</txshsoundcolumn>
|
|
Shinya Kitaoka |
120a6e |
double fps) {
|
|
Shinya Kitaoka |
120a6e |
int offset = 0xffff;
|
|
Shinya Kitaoka |
120a6e |
long sampleCount = 0;
|
|
Shinya Kitaoka |
120a6e |
std::vector<tsoundtrackp> tracks;</tsoundtrackp>
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP mix;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int size = vect.size(), i = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ColumnLevel *l = vect[0]->getColumnLevel(0);
|
|
Shinya Kitaoka |
120a6e |
if (!l) // May happen if the sound level is not
|
|
Shinya Kitaoka |
120a6e |
return mix; // correctly loaded from disk
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TXshSoundLevel *soundLevel = l->getSoundLevel();
|
|
Shinya Kitaoka |
120a6e |
assert(soundLevel);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (fps == -1) fps = soundLevel->getFrameRate();
|
|
Shinya Kitaoka |
120a6e |
if (fromFrame == -1) fromFrame = 0;
|
|
Shinya Kitaoka |
120a6e |
if (toFrame == -1) toFrame = getXsheet()->getFrameCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!soundLevel->getSoundTrack()) return mix;
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackFormat format = soundLevel->getSoundTrack()->getFormat();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TXshSoundColumn *c = 0;
|
|
Shinya Kitaoka |
120a6e |
int j;
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < size; ++j) {
|
|
Shinya Kitaoka |
120a6e |
TXshSoundColumn *oldC = c;
|
|
Shinya Kitaoka |
120a6e |
c = vect[j];
|
|
Shinya Kitaoka |
120a6e |
if (j == 0) {
|
|
Shinya Kitaoka |
120a6e |
mix = c->getOverallSoundTrack(fromFrame, toFrame, fps, format);
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP mixedTrack =
|
|
Shinya Kitaoka |
120a6e |
TSoundTrack::create(mix->getFormat(), mix->getSampleCount());
|
|
Shinya Kitaoka |
120a6e |
mix = TSop::mix(mixedTrack, mix, 1.0, c->getVolume());
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
assert(oldC);
|
|
Shinya Kitaoka |
120a6e |
if (c->getVolume() == 0 || c->isEmpty()) {
|
|
Shinya Kitaoka |
120a6e |
c = oldC;
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
mix =
|
|
Shinya Kitaoka |
120a6e |
TSop::mix(mix, c->getOverallSoundTrack(fromFrame, toFrame, fps, format),
|
|
Shinya Kitaoka |
120a6e |
1.0, c->getVolume());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Per ora perche mov vuole solo 16 bit
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackFormat fmt = mix->getFormat();
|
|
Shinya Kitaoka |
120a6e |
if (fmt.m_bitPerSample != 16) fmt.m_bitPerSample = 16;
|
|
Shinya Kitaoka |
120a6e |
mix = TSop::convert(mix, fmt);
|
|
Shinya Kitaoka |
120a6e |
return mix;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PERSIST_IDENTIFIER(TXshSoundColumn, "soundColumn")
|