Another OSX fix...
[ardour.git] / libs / ardour / ardour / buffer.h
1 /*
2     Copyright (C) 2006 Paul Davis 
3     Written by Dave Robillard, 2006
4     
5     This program is free software; you can redistribute it and/or modify it
6     under the terms of the GNU General Public License as published by the Free
7     Software Foundation; either version 2 of the License, or (at your option)
8     any later version.
9     
10     This program is distributed in the hope that it will be useful, but WITHOUT
11     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13     for more details.
14     
15     You should have received a copy of the GNU General Public License along
16     with this program; if not, write to the Free Software Foundation, Inc.,
17     675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #ifndef __ardour_buffer_h__
21 #define __ardour_buffer_h__
22
23 #define _XOPEN_SOURCE 600
24 #include <cstdlib> // for posix_memalign
25 #include <cassert>
26 #include <ardour/types.h>
27 #include <jack/jack.h>
28
29 namespace ARDOUR {
30
31
32 /* Yes, this is a bit of a mess right now.  I'll clean it up when everything
33  * using it works out.. */
34
35
36 /** A buffer of recordable/playable data.
37  *
38  * This is a datatype-agnostic base class for all buffers (there are no
39  * methods to actually access the data).  This provides a way for code that
40  * doesn't care about the data type to still deal with buffers (which is
41  * why the base class can't be a template).
42  * 
43  * To actually read/write buffer contents, use the appropriate derived class.
44  */
45 class Buffer
46 {
47 public:
48         Buffer(DataType type, size_t capacity)
49         : _type(type), _capacity(capacity), _size(0) 
50         {}
51
52         virtual ~Buffer() {}
53
54         /** Maximum capacity of buffer.
55          * Note in some cases the entire buffer may not contain valid data, use size. */
56         size_t capacity() const { return _capacity; }
57
58         /** Amount of valid data in buffer.  Use this over capacity almost always. */
59         size_t size() const { return _size; }
60
61         /** Type of this buffer.
62          * Based on this you can static cast a Buffer* to the desired type. */
63         virtual DataType type() const { return _type; }
64
65         /** Jack type (eg JACK_DEFAULT_AUDIO_TYPE) */
66         const char* jack_type() const { return type_to_jack_type(type()); }
67         
68         /** String type as saved in session XML files (eg "audio" or "midi") */
69         const char* type_string() const { return type_to_string(type()); }
70
71         /* The below static methods need to be separate from the above methods
72          * because the conversion is needed in places where there's no Buffer.
73          * These should probably live somewhere else...
74          */
75
76         static const char* type_to_jack_type(DataType t) {
77                 switch (t) {
78                         case AUDIO: return JACK_DEFAULT_AUDIO_TYPE;
79                         //case MIDI:  return JACK_DEFAULT_MIDI_TYPE;
80                         default:    return "";
81                 }
82         }
83         
84         static const char* type_to_string(DataType t) {
85                 switch (t) {
86                         case AUDIO: return "audio";
87                         case MIDI:  return "midi";
88                         default:    return "unknown"; // reeeally shouldn't ever happen
89                 }
90         }
91
92         /** Used for loading from XML (route default types etc) */
93         static DataType type_from_string(const string& str) {
94                 if (str == "audio")
95                         return AUDIO;
96                 else if (str == "midi")
97                         return MIDI;
98                 else
99                         return NIL;
100         }
101
102 protected:
103         DataType _type;
104         size_t   _capacity;
105         size_t   _size;
106 };
107
108
109 /* Inside every class with a type in it's name is a template waiting to get out... */
110
111
112 /** Buffer containing 32-bit floating point (audio) data. */
113 class AudioBuffer : public Buffer
114 {
115 public:
116         AudioBuffer(size_t capacity)
117                 : Buffer(AUDIO, capacity)
118                 , _data(NULL)
119         {
120                 _size = capacity; // For audio buffers, size = capacity (always)
121 #ifdef NO_POSIX_MEMALIGN
122                 _data =  (Sample *) malloc(sizeof(Sample) * capacity);
123 #else
124                 posix_memalign((void**)_data, 16, sizeof(Sample) * capacity);
125 #endif  
126                 assert(_data);
127                 memset(_data, 0, sizeof(Sample) * capacity);
128         }
129
130         const Sample* data() const { return _data; }
131         Sample*       data()       { return _data; }
132
133 private:
134         // These are undefined (prevent copies)
135         AudioBuffer(const AudioBuffer& copy);            
136         AudioBuffer& operator=(const AudioBuffer& copy);
137
138         Sample* _data; ///< Actual buffer contents
139 };
140
141
142 } // namespace ARDOUR
143
144 #endif // __ardour_buffer_h__