/[svn]/linuxsampler/trunk/src/engines/gig/Stream.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/engines/gig/Stream.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 53 - (hide annotations) (download)
Mon Apr 26 17:15:51 2004 UTC (19 years, 11 months ago) by schoenebeck
File size: 5590 byte(s)
* completely restructured source tree
* implemented multi channel support
* implemented instrument manager, which controls sharing of instruments
  between multiple sampler engines / sampler channels
* created abstract classes 'AudioOutputDevice' and 'MidiInputDevice' for
  convenient implementation of further audio output driver and MIDI input
  driver for LinuxSampler
* implemented following LSCP commands: 'SET CHANNEL MIDI INPUT TYPE',
  'LOAD ENGINE', 'GET CHANNELS', 'ADD CHANNEL', 'REMOVE CHANNEL',
  'SET CHANNEL AUDIO OUTPUT TYPE'
* temporarily removed all command line options
* LSCP server is now launched by default

1 schoenebeck 53 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003 by Benno Senoner *
6     * *
7     * This program is free software; you can redistribute it and/or modify *
8     * it under the terms of the GNU General Public License as published by *
9     * the Free Software Foundation; either version 2 of the License, or *
10     * (at your option) any later version. *
11     * *
12     * This program is distributed in the hope that it will be useful, *
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15     * GNU General Public License for more details. *
16     * *
17     * You should have received a copy of the GNU General Public License *
18     * along with this program; if not, write to the Free Software *
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20     * MA 02111-1307 USA *
21     ***************************************************************************/
22    
23     #include "Stream.h"
24    
25     namespace LinuxSampler { namespace gig {
26    
27     uint Stream::UnusedStreams = 0;
28    
29     /// Returns number of refilled sample points or a value < 0 on error.
30     int Stream::ReadAhead(unsigned long SampleCount) {
31     if (this->State == state_unused) return -1;
32     if (this->State == state_end) return 0;
33     if (!SampleCount) return 0;
34     if (!pRingBuffer->write_space()) return 0;
35    
36     long total_readsamples = 0, readsamples = 0;
37     long samplestoread = SampleCount / pSample->Channels;
38     sample_t* pBuf = pRingBuffer->get_write_ptr();
39     bool endofsamplereached;
40    
41     // refill the disk stream buffer
42     if (this->DoLoop) { // honor looping
43     total_readsamples = pSample->ReadAndLoop(pBuf, samplestoread, &this->PlaybackState);
44     endofsamplereached = (this->PlaybackState.position >= pSample->SamplesTotal);
45     dmsg(5,("Refilled stream %d with %d (SamplePos: %d)", this->hThis, total_readsamples, this->PlaybackState.position));
46     }
47     else { // normal forward playback
48    
49     pSample->SetPos(this->SampleOffset); // recover old position
50    
51     do {
52     readsamples = pSample->Read(&pBuf[total_readsamples * pSample->Channels], samplestoread);
53     samplestoread -= readsamples;
54     total_readsamples += readsamples;
55     } while (samplestoread && readsamples > 0);
56    
57     // we have to store the position within the sample, because other streams might use the same sample
58     this->SampleOffset = pSample->GetPos();
59    
60     endofsamplereached = (SampleOffset >= pSample->SamplesTotal);
61     dmsg(5,("Refilled stream %d with %d (SamplePos: %d)", this->hThis, total_readsamples, this->SampleOffset));
62     }
63    
64     // we must delay the increment_write_ptr_with_wrap() after the while() loop because we need to
65     // ensure that we read exactly SampleCount sample, otherwise the buffer wrapping code will fail
66     pRingBuffer->increment_write_ptr_with_wrap(total_readsamples * pSample->Channels);
67    
68     // update stream state
69     if (endofsamplereached) SetState(state_end);
70     else SetState(state_active);
71    
72     return total_readsamples;
73     }
74    
75     void Stream::WriteSilence(unsigned long SilenceSampleWords) {
76     memset(pRingBuffer->get_write_ptr(), 0, SilenceSampleWords);
77     pRingBuffer->increment_write_ptr_with_wrap(SilenceSampleWords);
78     }
79    
80     Stream::Stream(uint BufferSize, uint BufferWrapElements) {
81     this->pExportReference = NULL;
82     this->State = state_unused;
83     this->hThis = 0;
84     this->pSample = NULL;
85     this->SampleOffset = 0;
86     this->PlaybackState.position = 0;
87     this->PlaybackState.reverse = false;
88     this->pRingBuffer = new RingBuffer<sample_t>(BufferSize, BufferWrapElements);
89     UnusedStreams++;
90     }
91    
92     Stream::~Stream() {
93     Reset();
94     if (pRingBuffer) delete pRingBuffer;
95     }
96    
97     /// Called by disk thread to activate the disk stream.
98     void Stream::Launch(Stream::Handle hStream, reference_t* pExportReference, ::gig::Sample* pSample, unsigned long SampleOffset, bool DoLoop) {
99     UnusedStreams--;
100     this->pExportReference = pExportReference;
101     this->hThis = hStream;
102     this->pSample = pSample;
103     this->SampleOffset = SampleOffset;
104     this->PlaybackState.position = SampleOffset;
105     this->PlaybackState.reverse = false;
106     this->PlaybackState.loop_cycles_left = pSample->LoopPlayCount;
107     this->DoLoop = DoLoop;
108     SetState(state_active);
109     }
110    
111     }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC