/[svn]/linuxsampler/tags/v0_1_0/src/stream.cpp
ViewVC logotype

Annotation of /linuxsampler/tags/v0_1_0/src/stream.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 44 - (hide annotations) (download)
Sun Apr 11 17:25:40 2004 UTC (20 years, 1 month ago) by (unknown author)
File size: 5393 byte(s)
This commit was manufactured by cvs2svn to create tag 'v0_1_0'.
1 schoenebeck 9 /***************************************************************************
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     // FIXME: already independent of audio channels, but assumes sample depth defined by 'sample_t' (usually 16 bit)
26    
27    
28     // *********** Stream **************
29     // *
30    
31     uint Stream::UnusedStreams = 0;
32    
33     /// Returns number of refilled sample points or a value < 0 on error.
34     int Stream::ReadAhead(unsigned long SampleCount) {
35     if (this->State == state_unused) return -1;
36     if (this->State == state_end) return 0;
37     if (!SampleCount) return 0;
38     if (!pRingBuffer->write_space()) return 0;
39    
40     long total_readsamples = 0, readsamples = 0;
41     long samplestoread = SampleCount / pSample->Channels;
42 schoenebeck 26 sample_t* pBuf = pRingBuffer->get_write_ptr();
43     bool endofsamplereached;
44 schoenebeck 9
45     // refill the disk stream buffer
46 schoenebeck 26 if (this->DoLoop) { // honor looping
47     total_readsamples = pSample->ReadAndLoop(pBuf, samplestoread, &this->PlaybackState);
48     endofsamplereached = (this->PlaybackState.position >= pSample->SamplesTotal);
49     dmsg(5,("Refilled stream %d with %d (SamplePos: %d)", this->hThis, total_readsamples, this->PlaybackState.position));
50     }
51     else { // normal forward playback
52 schoenebeck 9
53 schoenebeck 26 pSample->SetPos(this->SampleOffset); // recover old position
54 schoenebeck 9
55 schoenebeck 26 do {
56     readsamples = pSample->Read(&pBuf[total_readsamples * pSample->Channels], samplestoread);
57     samplestoread -= readsamples;
58     total_readsamples += readsamples;
59     } while (samplestoread && readsamples > 0);
60    
61     // we have to store the position within the sample, because other streams might use the same sample
62     this->SampleOffset = pSample->GetPos();
63    
64     endofsamplereached = (SampleOffset >= pSample->SamplesTotal);
65     dmsg(5,("Refilled stream %d with %d (SamplePos: %d)", this->hThis, total_readsamples, this->SampleOffset));
66     }
67    
68 schoenebeck 9 // we must delay the increment_write_ptr_with_wrap() after the while() loop because we need to
69     // ensure that we read exactly SampleCount sample, otherwise the buffer wrapping code will fail
70     pRingBuffer->increment_write_ptr_with_wrap(total_readsamples * pSample->Channels);
71    
72     // update stream state
73     if (endofsamplereached) SetState(state_end);
74     else SetState(state_active);
75    
76 schoenebeck 26 return total_readsamples;
77 schoenebeck 9 }
78    
79     void Stream::WriteSilence(unsigned long SilenceSampleWords) {
80     memset(pRingBuffer->get_write_ptr(), 0, SilenceSampleWords);
81     pRingBuffer->increment_write_ptr_with_wrap(SilenceSampleWords);
82     }
83    
84     Stream::Stream(uint BufferSize, uint BufferWrapElements) {
85 schoenebeck 26 this->pExportReference = NULL;
86     this->State = state_unused;
87     this->hThis = 0;
88     this->pSample = NULL;
89     this->SampleOffset = 0;
90     this->PlaybackState.position = 0;
91     this->PlaybackState.reverse = false;
92     this->pRingBuffer = new RingBuffer<sample_t>(BufferSize, BufferWrapElements);
93 schoenebeck 9 UnusedStreams++;
94     }
95    
96     Stream::~Stream() {
97     Reset();
98     if (pRingBuffer) delete pRingBuffer;
99     }
100    
101     /// Called by disk thread to activate the disk stream.
102 schoenebeck 26 void Stream::Launch(Stream::Handle hStream, reference_t* pExportReference, gig::Sample* pSample, unsigned long SampleOffset, bool DoLoop) {
103 schoenebeck 9 UnusedStreams--;
104 schoenebeck 26 this->pExportReference = pExportReference;
105     this->hThis = hStream;
106     this->pSample = pSample;
107     this->SampleOffset = SampleOffset;
108     this->PlaybackState.position = SampleOffset;
109     this->PlaybackState.reverse = false;
110     this->PlaybackState.loop_cycles_left = pSample->LoopPlayCount;
111     this->DoLoop = DoLoop;
112 schoenebeck 9 SetState(state_active);
113     }

  ViewVC Help
Powered by ViewVC