/[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 3917 - (hide annotations) (download)
Thu Jun 10 12:58:37 2021 UTC (2 years, 10 months ago) by schoenebeck
File size: 5748 byte(s)
* gig engine: use libgig's new IO-per-thread feature to avoid file I/O
  concurrency issues with .gig file.

* Bumped version (2.2.0.svn1).

1 schoenebeck 53 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5 iliev 2012 * Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 3917 * Copyright (C) 2005-2021 Christian Schoenebeck *
7     * Copyright (C) 2009 Grigor Iliev *
8 schoenebeck 53 * *
9     * This program is free software; you can redistribute it and/or modify *
10     * it under the terms of the GNU General Public License as published by *
11     * the Free Software Foundation; either version 2 of the License, or *
12     * (at your option) any later version. *
13     * *
14     * This program is distributed in the hope that it will be useful, *
15     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17     * GNU General Public License for more details. *
18     * *
19     * You should have received a copy of the GNU General Public License *
20     * along with this program; if not, write to the Free Software *
21     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
22     * MA 02111-1307 USA *
23     ***************************************************************************/
24    
25     #include "Stream.h"
26 schoenebeck 1424 #include "../../common/global_private.h"
27    
28 schoenebeck 53 namespace LinuxSampler { namespace gig {
29    
30 iliev 2012 Stream::Stream (
31     ::gig::buffer_t* pDecompressionBuffer,
32     uint BufferSize,
33     uint BufferWrapElements) : LinuxSampler::StreamBase< ::gig::DimensionRegion>(BufferSize, BufferWrapElements)
34     {
35     this->pDecompressionBuffer = pDecompressionBuffer;
36     }
37 schoenebeck 53
38 iliev 2012 long Stream::Read(uint8_t* pBuf, long SamplesToRead) {
39     ::gig::Sample* pSample = pRegion->pSample;
40 schoenebeck 53 long total_readsamples = 0, readsamples = 0;
41     bool endofsamplereached;
42    
43     // refill the disk stream buffer
44     if (this->DoLoop) { // honor looping
45 iliev 2012 ::gig::playback_state_t pbs;
46     pbs.position = PlaybackState.position;
47     pbs.reverse = PlaybackState.reverse;
48     pbs.loop_cycles_left = PlaybackState.loop_cycles_left;
49    
50     total_readsamples = pSample->ReadAndLoop(pBuf, SamplesToRead, &pbs, pRegion, pDecompressionBuffer);
51     PlaybackState.position = pbs.position;
52     PlaybackState.reverse = pbs.reverse;
53     PlaybackState.loop_cycles_left = pbs.loop_cycles_left;
54 schoenebeck 53 endofsamplereached = (this->PlaybackState.position >= pSample->SamplesTotal);
55 persson 2837 dmsg(5,("Refilled stream %d with %ld (SamplePos: %lu)", this->hThis, total_readsamples, this->PlaybackState.position));
56 schoenebeck 53 }
57     else { // normal forward playback
58    
59     pSample->SetPos(this->SampleOffset); // recover old position
60    
61     do {
62 iliev 2012 readsamples = pSample->Read(&pBuf[total_readsamples * pSample->FrameSize], SamplesToRead, pDecompressionBuffer);
63     SamplesToRead -= readsamples;
64 schoenebeck 53 total_readsamples += readsamples;
65 iliev 2012 } while (SamplesToRead && readsamples > 0);
66 schoenebeck 53
67     // we have to store the position within the sample, because other streams might use the same sample
68     this->SampleOffset = pSample->GetPos();
69    
70     endofsamplereached = (SampleOffset >= pSample->SamplesTotal);
71 persson 2837 dmsg(5,("Refilled stream %d with %ld (SamplePos: %lu)", this->hThis, total_readsamples, this->SampleOffset));
72 schoenebeck 53 }
73    
74     // update stream state
75     if (endofsamplereached) SetState(state_end);
76     else SetState(state_active);
77    
78     return total_readsamples;
79     }
80    
81 iliev 2012 void Stream::Launch (
82     Stream::Handle hStream,
83     reference_t* pExportReference,
84     ::gig::DimensionRegion* pRgn,
85     unsigned long SampleOffset,
86     bool DoLoop
87     ) {
88     SampleDescription info;
89     info.ChannelsPerFrame = pRgn->pSample->Channels;
90     info.FrameSize = pRgn->pSample->FrameSize;
91     info.BytesPerSample = pRgn->pSample->BitDepth / 8;
92 schoenebeck 3054 info.TotalSampleCount = (int)pRgn->pSample->SamplesTotal;
93 schoenebeck 53
94 iliev 2012 Sample::PlaybackState playbackState;
95     playbackState.position = SampleOffset;
96     playbackState.reverse = false;
97     playbackState.loop_cycles_left = pRgn->pSample->LoopPlayCount;
98 schoenebeck 53
99 schoenebeck 3917 // assuming libgig's file-IO-per-thread feature is enabled: by default
100     // the file stream is closed for this thread, so open it for being able
101     // to read the .gig file (see libgig's RIFF::File::SetIOPerThread() for
102     // details)
103     ::gig::File* gig = (::gig::File*) pRgn->pSample->GetParent();
104     ::RIFF::File* riff = gig->GetRiffFile();
105     if (riff->GetMode() == ::RIFF::stream_mode_closed) {
106     try {
107     riff->SetMode(::RIFF::stream_mode_read);
108     } catch (...) {
109     dmsg(1,("Failed opening disk stream\n"));
110     }
111     }
112    
113 iliev 2012 LinuxSampler::StreamBase< ::gig::DimensionRegion>::Launch (
114     hStream, pExportReference, pRgn, info, playbackState, SampleOffset, DoLoop
115     );
116 schoenebeck 53 }
117    
118     }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC