df9cc46b9126a103b8b12d3d957db980251d4c2c
[ardour.git] / libs / ardour / ardour / filesource.h
1 /*
2     Copyright (C) 2000 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18     $Id$
19 */
20
21 #ifndef __playlist_file_buffer_h__ 
22 #define __playlist_file_buffer_h__
23
24 // darwin supports 64 by default and doesn't provide wrapper functions.
25 #if defined (__APPLE__)
26 typedef off_t off64_t;
27 #define open64 open
28 #define close64 close
29 #define lseek64 lseek
30 #define pread64 pread
31 #define pwrite64 pwrite
32 #endif
33
34 #include <vector>
35 #include <string>
36
37 #include <ardour/source.h>
38
39 struct tm;
40
41 using std::string;
42
43 namespace ARDOUR {
44
45 class FileSource : public Source {
46   public:
47         FileSource (string path, jack_nframes_t rate, bool repair_first = false, SampleFormat samp_format=FormatFloat);
48         FileSource (const XMLNode&, jack_nframes_t rate);
49         ~FileSource ();
50
51         int set_name (std::string str, bool destructive);
52
53         void set_allow_remove_if_empty (bool yn);
54
55         jack_nframes_t length() const { return _length; }
56         jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
57         jack_nframes_t write (Sample *src, jack_nframes_t cnt, char * workbuf);
58         void           mark_for_remove();
59         string         peak_path(string audio_path);
60         string         path() const { return _path; }
61
62         virtual int            seek (jack_nframes_t frame) {return 0; }
63         virtual jack_nframes_t last_capture_start_frame() const { return 0; }
64         virtual void           mark_capture_start (jack_nframes_t) {}
65         virtual void           mark_capture_end () {}
66         virtual void           clear_capture_marks() {}
67
68         int update_header (jack_nframes_t when, struct tm&, time_t);
69
70         int move_to_trash (const string trash_dir_name);
71
72         static bool is_empty (string path);
73         void mark_streaming_write_completed ();
74
75         void   mark_take (string);
76         string take_id() const { return _take_id; }
77
78         static void set_bwf_country_code (string x);
79         static void set_bwf_organization_code (string x);
80         static void set_bwf_serial_number (int);
81         
82         static void set_search_path (string);
83
84   protected:
85         int            fd;
86         string        _path;
87         bool           remove_at_unref;
88         bool           is_bwf;
89         off64_t        data_offset;
90         string        _take_id;
91         SampleFormat  _sample_format;
92         int           _sample_size;
93         bool           allow_remove_if_empty;
94
95         static char bwf_country_code[3];
96         static char bwf_organization_code[4];
97         static char bwf_serial_number[13];
98
99         struct GenericChunk {
100             char    id[4];
101             int32_t  size; 
102         };
103
104         struct WAVEChunk : public GenericChunk {
105             char    text[4];      /* wave pseudo-chunk id "WAVE" */
106         };
107
108         struct FMTChunk : public GenericChunk {
109             int16_t   formatTag;           /* format tag; currently pcm   */
110             int16_t   nChannels;           /* number of channels         */
111             uint32_t  nSamplesPerSec;      /* sample rate in hz          */
112             int32_t   nAvgBytesPerSec;     /* average bytes per second   */
113             int16_t   nBlockAlign;         /* number of bytes per sample */
114             int16_t   nBitsPerSample;      /* number of bits in a sample */
115         };
116
117         struct BroadcastChunk : public GenericChunk {
118             char   description[256];
119             char   originator[32];
120             char   originator_reference[32];
121             char   origination_date[10];
122             char   origination_time[8];
123             int32_t time_reference_low;
124             int32_t time_reference_high;
125             int16_t version;               /* 1.0 because we have umid and 190 bytes of "reserved" */
126             char   umid[64];
127             char   reserved[190];
128             /* we don't treat coding history as part of the struct */
129         };
130
131         struct ChunkInfo {
132             string        name;
133             uint32_t size;
134             off64_t         offset;
135             
136             ChunkInfo (string s, uint32_t sz, off64_t o) 
137                     : name (s), size (sz), offset (o) {}
138         };
139
140         vector<ChunkInfo> chunk_info;
141         
142         struct {
143             WAVEChunk               wave;
144             FMTChunk                format;
145             GenericChunk            data;
146             BroadcastChunk          bext;
147             vector<string>          coding_history;
148             bool                    bigendian;
149         } header;
150
151         int init (string, bool must_exist, jack_nframes_t);
152         jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
153
154         ssize_t file_write (Sample *src, jack_nframes_t framepos, jack_nframes_t cnt, char * workbuf) {
155                 switch (_sample_format) {
156                 case FormatInt24: return write_pcm_24(src, framepos, cnt, workbuf);
157                 default: return write_float(src, framepos, cnt, workbuf);
158                 };
159         }
160         
161         ssize_t file_read  (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const  {
162                 switch (_sample_format) {
163                 case FormatInt24: return read_pcm_24(dst, start, cnt, workbuf);
164                 default: return read_float(dst, start, cnt, workbuf);
165                 };
166         }
167         
168         ssize_t write_float(Sample *src, jack_nframes_t framepos, jack_nframes_t cnt, char * workbuf);
169         ssize_t read_float (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
170         ssize_t write_pcm_24(Sample *src, jack_nframes_t framepos, jack_nframes_t cnt, char * workbuf);
171         ssize_t read_pcm_24 (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
172         
173         int discover_chunks (bool silent);
174         ChunkInfo* lookup_chunk (string name);
175
176         int write_header ();
177         int read_header (bool silent);
178
179         int check_header (jack_nframes_t rate, bool silent);
180         int fill_header (jack_nframes_t rate);
181         
182         int read_broadcast_data (ChunkInfo&);
183         void compute_header_size ();
184         
185         static const int32_t wave_header_size = sizeof (WAVEChunk) + sizeof (FMTChunk) + sizeof (GenericChunk);
186         static const int32_t bwf_header_size = wave_header_size + sizeof (BroadcastChunk);
187
188         static string search_path;
189
190         int repair (string, jack_nframes_t);
191
192         void swap_endian (GenericChunk & chunk) const;
193         void swap_endian (FMTChunk & chunk) const;
194         void swap_endian (BroadcastChunk & chunk) const;
195         void swap_endian (Sample *buf, jack_nframes_t cnt) const;
196 };
197
198 }
199
200 #endif /* __playlist_file_buffer_h__ */