summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Schweer <ws.seh.de>2006-07-29 11:43:41 +0000
committerWerner Schweer <ws.seh.de>2006-07-29 11:43:41 +0000
commitac2fa3ea8db683dca17cc39bc94fc8f7122b4d65 (patch)
tree6f591ef7559441933b81250489459d6921c2a907
parentd6797341cbfbd1abefefe4759fef64f5bc281172 (diff)
fixed audio "crackling"
-rw-r--r--muse/CMakeLists.txt4
-rw-r--r--muse/ChangeLog3
-rw-r--r--muse/al/pos.cpp9
-rw-r--r--muse/muse/audio.cpp5
-rw-r--r--muse/muse/audioprefetch.cpp5
-rw-r--r--muse/muse/audiotrack.cpp4
-rw-r--r--muse/muse/midiseq.cpp3
-rw-r--r--muse/muse/plugin.cpp2
-rw-r--r--muse/muse/thread.cpp2
-rw-r--r--muse/muse/wave.cpp103
-rw-r--r--muse/muse/wave.h10
-rw-r--r--muse/muse/waveedit/waveview.cpp2
-rw-r--r--muse/muse/waveevent.cpp2
-rw-r--r--muse/muse/wavetrack.cpp23
14 files changed, 120 insertions, 57 deletions
diff --git a/muse/CMakeLists.txt b/muse/CMakeLists.txt
index 2a254007..3a6f42b5 100644
--- a/muse/CMakeLists.txt
+++ b/muse/CMakeLists.txt
@@ -21,8 +21,8 @@
project(muse)
CMAKE_MINIMUM_REQUIRED(VERSION 2.4.1)
-# set(CMAKE_BUILD_TYPE Debug)
-set(CMAKE_BUILD_TYPE Release)
+set(CMAKE_BUILD_TYPE Debug)
+# set(CMAKE_BUILD_TYPE Release)
set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
diff --git a/muse/ChangeLog b/muse/ChangeLog
index fec0424f..3523283d 100644
--- a/muse/ChangeLog
+++ b/muse/ChangeLog
@@ -1,3 +1,6 @@
+29.7 (ws)
+ * fixed drawing of waveform in wave track. Concurrent wave file
+ accesses from gui and rt task produced distortions ("crackling").
25.7 (ng) DeicsOnze
* add panic button
28.6. (ws)
diff --git a/muse/al/pos.cpp b/muse/al/pos.cpp
index 7c6e6c8e..eb3629c2 100644
--- a/muse/al/pos.cpp
+++ b/muse/al/pos.cpp
@@ -422,8 +422,10 @@ void PosLen::setLenTick(unsigned len)
{
_lenTick = len;
sn = -1;
-// if (type() == FRAMES)
+ if (type() == FRAMES)
_lenFrame = tempomap.tick2frame(len, &sn);
+ else
+ _lenTick = len;
}
//---------------------------------------------------------
@@ -432,10 +434,11 @@ void PosLen::setLenTick(unsigned len)
void PosLen::setLenFrame(unsigned len)
{
- _lenFrame = len;
sn = -1;
-// if (type() == TICKS)
+ if (type() == TICKS)
_lenTick = tempomap.frame2tick(len, &sn);
+ else
+ _lenFrame = len;
}
//---------------------------------------------------------
diff --git a/muse/muse/audio.cpp b/muse/muse/audio.cpp
index 42cd3255..f27cf6fd 100644
--- a/muse/muse/audio.cpp
+++ b/muse/muse/audio.cpp
@@ -307,7 +307,7 @@ void Audio::process(unsigned frames)
++watchAudio; // make a simple watchdog happy
if (msg) {
-// printf("msg\n");
+// printf("---msg\n");
processMsg(msg);
int sn = msg->serialNo;
msg = 0; // dont process again
@@ -363,7 +363,6 @@ void Audio::process(unsigned frames)
(*i)->silence(frames);
return;
}
-
unsigned framePos = _pos.frame();
if (state == PLAY) {
@@ -552,7 +551,7 @@ void Audio::process(unsigned frames)
void Audio::processMsg(AudioMsg* msg)
{
// if (_running)
-// printf("audio process %d\n", msg->id);
+ printf("audio process %d\n", msg->id);
switch(msg->id) {
case AUDIO_ROUTEADD:
diff --git a/muse/muse/audioprefetch.cpp b/muse/muse/audioprefetch.cpp
index f9853f6a..7f6711f7 100644
--- a/muse/muse/audioprefetch.cpp
+++ b/muse/muse/audioprefetch.cpp
@@ -111,9 +111,9 @@ void AudioPrefetch::processMsg1(const void* m)
void AudioPrefetch::msgTick()
{
- PrefetchMsg msg;
- msg.id = PREFETCH_TICK;
if (fifo.count() < FIFO_BUFFER/3) {
+ PrefetchMsg msg;
+ msg.id = PREFETCH_TICK;
while (sendMsg1(&msg, sizeof(msg))) {
printf("AudioPrefetch::msgTick(): send failed!\n");
}
@@ -174,7 +174,6 @@ void AudioPrefetch::prefetch(bool seekFlag)
WaveTrack* track = *it;
if (!seekFlag && ((audio->isRecording() && track->recordFlag()) || !audio->isPlaying()))
continue;
- // int ch = track->channels();
track->fetchData(writePos, segmentSize, widx);
}
writePos += segmentSize;
diff --git a/muse/muse/audiotrack.cpp b/muse/muse/audiotrack.cpp
index 0d99a746..02cd857a 100644
--- a/muse/muse/audiotrack.cpp
+++ b/muse/muse/audiotrack.cpp
@@ -503,8 +503,8 @@ bool AudioTrack::multiplyCopy(int dstChannels, float** dstBuffer, int ctrl)
if (_mute || bufferEmpty || _volume == 0.0)
return false;
int srcChannels = channels();
- double vol[2];
- double _pan = ctrlVal(AC_PAN).f;
+ float vol[2];
+ float _pan = ctrlVal(AC_PAN).f;
vol[0] = _volume * (1.0 - _pan);
vol[1] = _volume * (1.0 + _pan);
diff --git a/muse/muse/midiseq.cpp b/muse/muse/midiseq.cpp
index d1bcc114..0895096b 100644
--- a/muse/muse/midiseq.cpp
+++ b/muse/muse/midiseq.cpp
@@ -60,6 +60,7 @@ static void readMsg(void* p, void*)
void MidiSeq::processMsg(const ThreadMsg* m)
{
+
AudioMsg* msg = (AudioMsg*)m;
switch (msg->id) {
case MS_PROCESS:
@@ -397,12 +398,12 @@ void MidiSeq::updatePollFd()
if (!isRunning())
return;
clearPollFd();
+
if (timer) {
int timerFd = timer->getFd();
if (timerFd != -1)
addPollFd(timerFd, POLLIN, midiTick, this, 0);
}
-
addPollFd(toThreadFdr, POLLIN, ::readMsg, this, 0);
struct pollfd* pfd;
diff --git a/muse/muse/plugin.cpp b/muse/muse/plugin.cpp
index c5d6362a..aeee6cc5 100644
--- a/muse/muse/plugin.cpp
+++ b/muse/muse/plugin.cpp
@@ -231,7 +231,7 @@ Plugin* PluginList::find(const QString& file, const QString& name)
if ((file == (*i)->lib()) && (name == (*i)->label()))
return *i;
}
- printf("Plugin <%s> not found\n", name.toLatin1().data());
+ printf("MusE: Plugin <%s> not found\n", name.toAscii().data());
return 0;
}
diff --git a/muse/muse/thread.cpp b/muse/muse/thread.cpp
index c77d8ab9..ea8de818 100644
--- a/muse/muse/thread.cpp
+++ b/muse/muse/thread.cpp
@@ -231,6 +231,8 @@ void Thread::loop()
while (_running) {
if (debugMode) // DEBUG
_pollWait = 10; // ms
+ else
+ _pollWait = -1;
int n = poll(pfd, npfd, _pollWait);
if (n < 0) {
diff --git a/muse/muse/wave.cpp b/muse/muse/wave.cpp
index 9b6fc1d2..9b40c967 100644
--- a/muse/muse/wave.cpp
+++ b/muse/muse/wave.cpp
@@ -253,7 +253,8 @@ SndFile::SndFile(const QString& name)
{
refCount = 0;
_finfo.setFile(name);
- sf = 0;
+ sfRT = 0;
+ sfUI = 0;
csize = 0;
cache = 0;
openFlag = false;
@@ -284,8 +285,11 @@ bool SndFile::openRead()
return false;
}
QString p = _finfo.absoluteFilePath();
- sf = sf_open(p.toLatin1().data(), SFM_READ, &sfinfo);
- if (sf == 0)
+ sfinfo.format = 0;
+ sfUI = sf_open(p.toAscii().data(), SFM_READ, &sfinfo);
+ sfinfo.format = 0;
+ sfRT = sf_open(p.toAscii().data(), SFM_READ, &sfinfo);
+ if (sfUI == 0 || sfRT == 0)
return true;
writeFlag = false;
openFlag = true;
@@ -335,7 +339,7 @@ void SndFile::readCache(const QString& path, bool showProgress)
for (unsigned ch = 0; ch < channels(); ++ch)
cache[ch] = new SampleV[csize];
- FILE* cfile = fopen(path.toLatin1().data(), "r");
+ FILE* cfile = fopen(path.toAscii().data(), "r");
if (cfile) {
for (unsigned ch = 0; ch < channels(); ++ch)
fread(cache[ch], csize * sizeof(SampleV), 1, cfile);
@@ -368,7 +372,7 @@ void SndFile::readCache(const QString& path, bool showProgress)
// TODO
}
}
- seek(i * cacheMag, 0);
+ seek(i * cacheMag);
read(channels(), fp, cacheMag);
for (unsigned ch = 0; ch < channels(); ++ch) {
float rms = 0.0;
@@ -426,18 +430,44 @@ void SndFile::read(SampleV* s, int mag, unsigned pos)
s[ch].peak = 0;
s[ch].rms = 0;
}
- if (pos > samples()) {
-// printf("%p pos %d > samples %d\n", this, pos, samples());
+ if (pos > samples())
return;
- }
if (mag < cacheMag) {
float data[channels()][mag];
float* fp[channels()];
for (unsigned i = 0; i < channels(); ++i)
fp[i] = &data[i][0];
- seek(pos, 0);
- read(channels(), fp, mag);
+ sf_seek(sfUI, pos, SEEK_SET);
+ {
+ int srcChannels = channels();
+ int dstChannels = sfinfo.channels;
+ size_t n = mag;
+ float** dst = fp;
+ float buffer[n * dstChannels];
+ size_t rn = sf_readf_float(sfUI, buffer, n);
+ float* src = buffer;
+
+ if (srcChannels == dstChannels) {
+ for (size_t i = 0; i < rn; ++i) {
+ for (int ch = 0; ch < srcChannels; ++ch)
+ *(dst[ch]+i) = *src++;
+ }
+ }
+ else if ((srcChannels == 1) && (dstChannels == 2)) {
+ // stereo to mono
+ for (size_t i = 0; i < rn; ++i)
+ *(dst[0] + i) = src[i + i] + src[i + i + 1];
+ }
+ else if ((srcChannels == 2) && (dstChannels == 1)) {
+ // mono to stereo
+ for (size_t i = 0; i < rn; ++i) {
+ float data = *src++;
+ *(dst[0]+i) = data;
+ *(dst[1]+i) = data;
+ }
+ }
+ }
for (unsigned ch = 0; ch < channels(); ++ch) {
s[ch].peak = 0;
@@ -459,7 +489,7 @@ void SndFile::read(SampleV* s, int mag, unsigned pos)
int rest = csize - (pos/cacheMag);
int end = mag;
if (rest < mag)
- end = rest;
+ end = rest;
for (unsigned ch = 0; ch < channels(); ++ch) {
int rms = 0;
@@ -485,15 +515,16 @@ bool SndFile::openWrite()
return false;
}
QString p = _finfo.filePath();
- sf = sf_open(p.toLatin1().data(), SFM_RDWR, &sfinfo);
- if (sf) {
+ sfRT = sf_open(p.toLatin1().data(), SFM_RDWR, &sfinfo);
+ sfUI = 0;
+ if (sfRT) {
openFlag = true;
writeFlag = true;
QString cacheName = _finfo.absolutePath() +
QString("/") + _finfo.baseName() + QString(".wca");
readCache(cacheName, true);
}
- return sf == 0;
+ return sfRT == 0;
}
//---------------------------------------------------------
@@ -506,7 +537,9 @@ void SndFile::close()
printf("SndFile:: alread closed\n");
return;
}
- sf_close(sf);
+ sf_close(sfRT);
+ if (sfUI)
+ sf_close(sfUI);
openFlag = false;
}
@@ -521,9 +554,9 @@ void SndFile::remove()
QString cacheName = _finfo.absolutePath() + QString("/") + _finfo.baseName() + QString(".wca");
// QFile::remove(_finfo.filePath());
// QFile::remove(cacheName);
+ // DEBUG:
QFile::rename(_finfo.filePath(), _finfo.filePath() + ".del");
QFile::rename(cacheName, cacheName + ".del");
-
}
//---------------------------------------------------------
@@ -532,10 +565,7 @@ void SndFile::remove()
unsigned SndFile::samples() const
{
- sf_count_t curPos = sf_seek(sf, 0, SEEK_CUR);
- int frames = sf_seek(sf, 0, SEEK_END);
- sf_seek(sf, curPos, SEEK_SET);
- return frames;
+ return sfinfo.frames;
}
//---------------------------------------------------------
@@ -547,16 +577,28 @@ unsigned SndFile::channels() const
return sfinfo.channels;
}
+//---------------------------------------------------------
+// samplerate
+//---------------------------------------------------------
+
unsigned SndFile::samplerate() const
{
return sfinfo.samplerate;
}
+//---------------------------------------------------------
+// format
+//---------------------------------------------------------
+
unsigned SndFile::format() const
{
return sfinfo.format;
}
+//---------------------------------------------------------
+// setFormat
+//---------------------------------------------------------
+
void SndFile::setFormat(int fmt, int ch, int rate)
{
sfinfo.samplerate = rate;
@@ -573,7 +615,9 @@ void SndFile::setFormat(int fmt, int ch, int rate)
size_t SndFile::read(int srcChannels, float** dst, size_t n)
{
float buffer[n * sfinfo.channels];
- size_t rn = sf_readf_float(sf, buffer, n);
+ size_t rn = sf_readf_float(sfRT, buffer, n);
+// sf_seek(sfRT, n, SEEK_CUR); //libsndfile does not update position??
+
float* src = buffer;
int dstChannels = sfinfo.channels;
@@ -637,16 +681,16 @@ size_t SndFile::write(int srcChannels, float** src, size_t n)
srcChannels, dstChannels);
return 0;
}
- return sf_writef_float(sf, buffer, n) ;
+ return sf_writef_float(sfRT, buffer, n) ;
}
//---------------------------------------------------------
// seek
//---------------------------------------------------------
-off_t SndFile::seek(off_t frames, int whence)
+off_t SndFile::seek(off_t frames)
{
- return sf_seek(sf, frames, whence);
+ return sf_seek(sfRT, frames, SEEK_SET);
}
//---------------------------------------------------------
@@ -657,7 +701,7 @@ QString SndFile::strerror() const
{
char buffer[128];
buffer[0] = 0;
- sf_error_str(sf, buffer, 128);
+ sf_error_str(sfRT, buffer, 128);
return QString(buffer);
}
@@ -705,6 +749,7 @@ SndFile* SndFile::getWave(const QString& inName, bool writeFlag)
//---------------------------------------------------------
// applyUndoFile
//---------------------------------------------------------
+
void SndFile::applyUndoFile(const QString& original, const QString& tmpfile, unsigned startframe, unsigned endframe)
{
// This one is called on both undo and redo of a wavfile
@@ -750,7 +795,7 @@ void SndFile::applyUndoFile(const QString& original, const QString& tmpfile, uns
for (unsigned i=0; i<file_channels; i++) {
data2beoverwritten[i] = new float[tmpdatalen];
}
- orig->seek(startframe, 0);
+ orig->seek(startframe);
orig->read(file_channels, data2beoverwritten, tmpdatalen);
orig->close();
@@ -760,7 +805,7 @@ void SndFile::applyUndoFile(const QString& original, const QString& tmpfile, uns
for (unsigned i=0; i<file_channels; i++) {
tmpfiledata[i] = new float[tmpdatalen];
}
- tmp.seek(0, 0);
+ tmp.seek(0);
tmp.read(file_channels, tmpfiledata, tmpdatalen);
tmp.close();
@@ -770,7 +815,7 @@ void SndFile::applyUndoFile(const QString& original, const QString& tmpfile, uns
return;
}
- orig->seek(startframe, 0);
+ orig->seek(startframe);
orig->write(file_channels, tmpfiledata, tmpdatalen);
// Delete dataholder for temporary file
@@ -784,7 +829,7 @@ void SndFile::applyUndoFile(const QString& original, const QString& tmpfile, uns
audio->msgIdle(false);
return;
}
- tmp.seek(0, 0);
+ tmp.seek(0);
tmp.write(file_channels, data2beoverwritten, tmpdatalen);
tmp.close();
diff --git a/muse/muse/wave.h b/muse/muse/wave.h
index 0db8c27c..42054f87 100644
--- a/muse/muse/wave.h
+++ b/muse/muse/wave.h
@@ -48,8 +48,10 @@ class SndFile {
static QHash<QString, SndFile*> sndFiles;
static QList<SndFile*> createdFiles;
static int recFileNumber;
+
QFileInfo _finfo;
- SNDFILE* sf;
+ SNDFILE* sfRT; // used by rt process (prefetch)
+ SNDFILE* sfUI; // used by ui process
SF_INFO sfinfo;
SampleV** cache;
int csize; // frames in cache
@@ -90,7 +92,7 @@ class SndFile {
size_t read(int channel, float**, size_t);
size_t write(int channel, float**, size_t);
- off_t seek(off_t frames, int whence);
+ off_t seek(off_t frames);
void read(SampleV* s, int mag, unsigned pos);
QString strerror() const;
@@ -147,8 +149,8 @@ class SndFileR {
size_t write(int channel, float** f, size_t n) {
return sf->write(channel, f, n);
}
- off_t seek(off_t frames, int whence) {
- return sf->seek(frames, whence);
+ off_t seek(off_t frames) {
+ return sf->seek(frames);
}
void read(SampleV* s, int mag, unsigned pos) {
sf->read(s, mag, pos);
diff --git a/muse/muse/waveedit/waveview.cpp b/muse/muse/waveedit/waveview.cpp
index 38d9f052..f1352f6d 100644
--- a/muse/muse/waveedit/waveview.cpp
+++ b/muse/muse/waveedit/waveview.cpp
@@ -729,7 +729,7 @@ void WaveView::editExternal(unsigned file_format, unsigned file_samplerate, unsi
}
else {
// Re-read file again
- exttmpFile.seek(0, 0);
+ exttmpFile.seek(0);
size_t sz = exttmpFile.read(file_channels, tmpdata, tmpdatalen);
if (sz != tmpdatalen) {
// File must have been shrunken - not good. Alert user.
diff --git a/muse/muse/waveevent.cpp b/muse/muse/waveevent.cpp
index 2d54cc99..82d451ae 100644
--- a/muse/muse/waveevent.cpp
+++ b/muse/muse/waveevent.cpp
@@ -115,7 +115,7 @@ void WaveEventBase::read(unsigned offset, float** buffer, int channel, int n)
{
if (f.isNull())
return;
- f.seek(offset + _spos, 0);
+ f.seek(offset + _spos);
f.read(channel, buffer, n);
}
diff --git a/muse/muse/wavetrack.cpp b/muse/muse/wavetrack.cpp
index 10753640..7aa299fc 100644
--- a/muse/muse/wavetrack.cpp
+++ b/muse/muse/wavetrack.cpp
@@ -77,10 +77,16 @@ void WaveTrack::fetchData(unsigned pos, unsigned samples, int widx)
float** bp = readBuffer[widx];
for (int i = 0; i < channels(); ++i)
memset(bp[i], 0, samples * sizeof(float));
- PartList* pl = parts();
+ PartList* pl = parts();
for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
Part* part = ip->second;
+
+ // DEBUG
+ int type = int(part->type());
+ if (type != AL::FRAMES)
+ printf("part has wrong type\n");
+
if (part->mute())
continue;
unsigned p_spos = part->frame();
@@ -117,11 +123,14 @@ void WaveTrack::fetchData(unsigned pos, unsigned samples, int widx)
if (nn > samples)
nn = samples;
}
- float* bpp[channels()];
- for (int i = 0; i < channels(); ++i)
- bpp[i] = bp[i] + dstOffset;
-
- event.read(srcOffset, bpp, channels(), nn);
+ if (dstOffset) {
+ float* bpp[channels()];
+ for (int i = 0; i < channels(); ++i)
+ bpp[i] = bp[i] + dstOffset;
+ event.read(srcOffset, bpp, channels(), nn);
+ }
+ else
+ event.read(srcOffset, bp, channels(), nn);
}
}
}
@@ -381,7 +390,7 @@ void WaveTrack::process()
void WaveTrack::clone(WaveTrack* t)
{
-printf("cline WaveTrack\n");
+printf("clone WaveTrack\n");
QString name;
for (int i = 1; ; ++i) {
name.sprintf("%s-%d", t->name().toLatin1().data(), i);