a4749bb1a0dbf98642444540d81a8af3deb5b9fb
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / samples.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2009 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22
23
24 // An object which contains samples
25
26
27 #include "bcresources.h"
28 #include "bcwindowbase.h"
29 #include "samples.h"
30 #include <stdio.h>
31 #include <sys/shm.h>
32 #include <unistd.h>
33
34
35 Samples::Samples()
36 {
37         reset();
38 }
39
40 // Allocate number of samples
41 Samples::Samples(int samples)
42 {
43         reset();
44         allocate(samples, 1);
45 }
46
47 Samples::Samples(Samples *src)
48 {
49         reset();
50         int src_sz = src->get_allocated();
51         if( use_shm ) {
52                 share(src->get_shmid());
53                 set_allocated(src_sz);
54         }
55         else {
56                 share(src->data);
57                 set_allocated(0);
58         }
59         set_offset(src->get_offset());
60 }
61
62 Samples::~Samples()
63 {
64         clear_objects();
65 }
66
67 void Samples::reset()
68 {
69         BC_Resources *resources = BC_WindowBase::get_resources();
70         use_shm = !resources || !resources->use_shm ? 0 : 1;
71         shmid = -1;
72         data = 0;
73         allocated = 0;
74         offset = 0;
75 }
76
77 void Samples::clear_objects()
78 {
79         if(use_shm)
80         {
81                 if(data) shmdt(data);
82         }
83         else if( allocated )
84         {
85                 delete [] data;
86         }
87
88         reset();
89 }
90
91
92 void Samples::share(int shmid)
93 {
94         if(data)
95         {
96                 if(use_shm)
97                         shmdt(data);
98                 else
99                         delete [] data;
100         }
101
102         this->use_shm = 1;
103         data = (double*)shmat(shmid, NULL, 0);
104         this->allocated = 0;
105         this->shmid = shmid;
106 }
107 void Samples::share(double *buffer)
108 {
109         if(data)
110         {
111                 if(use_shm)
112                         shmdt(data);
113                 else
114                         delete [] data;
115         }
116         this->use_shm = 0;
117         data = buffer;
118         this->allocated = 0;
119         this->shmid = -1;
120 }
121
122
123 void Samples::allocate(int samples, int use_shm)
124 {
125         if( !this->use_shm ) use_shm = 0;
126         if( data &&
127                 this->allocated >= samples &&
128                 this->use_shm == use_shm ) return;
129
130         if( data ) {
131                 if( this->use_shm )
132                         shmdt(data);
133                 else
134                         delete [] data;
135         }
136
137         this->use_shm = use_shm;
138
139         if( use_shm ) {
140                 shmid = shmget(IPC_PRIVATE,
141                         (samples + 1) * sizeof(double),
142                         IPC_CREAT | 0777);
143                 data = (double*)shmat(shmid, NULL, 0);
144         // This causes it to automatically delete when the program exits.
145                 shmctl(shmid, IPC_RMID, 0);
146         }
147         else {
148                 shmid = -1;
149                 data = new double[samples];
150         }
151
152         this->allocated = samples;
153 }
154
155 // Get the buffer
156 double* Samples::get_data()
157 {
158         return data + offset;
159 }
160
161 // Get number of samples allocated
162 int Samples::get_allocated()
163 {
164         return allocated;
165 }
166
167 // Set number of samples allocated
168 void Samples::set_allocated(int allocated)
169 {
170         this->allocated = allocated;
171 }
172
173 int Samples::get_shmid()
174 {
175         return shmid;
176 }
177
178 void Samples::set_offset(int offset)
179 {
180         this->offset = offset;
181 }
182
183 int Samples::get_offset()
184 {
185         return offset;
186 }
187