aboutsummaryrefslogtreecommitdiff
path: root/src/lib/hd24fs.h
blob: b91d4c1daf00ba477405cf899fda2b8f024c4f52 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
#ifndef __hd24fs_h__
#define __hd24fs_h__

#include <config.h>
#include <stdio.h>
#include <string>
#include <hd24utils.h>
#include "memutils.h"
#include "convertlib.h"
#define CLUSTER_UNDEFINED (0xFFFFFFFF)

#if defined(LINUX) || defined(DARWIN)
#	define FSHANDLE int
#	define FSHANDLE_INVALID -1
#endif

#ifdef WINDOWS
#	include <windows.h>
#	include <winioctl.h>
#	define FSHANDLE HANDLE
#	define FSHANDLE_INVALID INVALID_HANDLE_VALUE
#endif

using namespace std;

class hd24fs;
class hd24project;
class hd24raw;
class hd24song;

class AudioStorage
{
public:
	virtual __uint32 samplerate() { return 0; };
	virtual void currentlocation(__uint32 newpos) { return; };
	virtual __uint32 currentlocation() { return 0; };
	virtual __uint32 getlocatepos(int locatepoint) { return 0; };
	virtual __uint32 setlocatepos(int locatepoint,__uint32 newpos) { return 0; };
	virtual bool trackarmed(__uint32 base1tracknum) { return false; }
	virtual void trackarmed(__uint32 base1tracknum,bool arm) { return; }
	virtual ~AudioStorage() { return; } ;
};

class hd24song : public AudioStorage
{
	friend class hd24project;
	friend class hd24fs;
	friend class hd24transferjob;
	friend class hd24transferengine;
	private:
		__uint32 framespersec;
		unsigned char* buffer;		// for songinfo
		unsigned char* audiobuffer;	// for audio data 
		unsigned char* scratchbook;	// for write-back audio data
		__uint32* blocksector;
		int evenodd; /* specifies if we are dealing with 
				 even or odd samples in high speed mode. */
		bool lengthened; /* Indicate if reallocating song length change occured */
		bool busyrecording;
		int mysongid;
		int polling;
		int currentreadmode;
		int currcachebufnum;
		bool rehearsemode;
		bool lastallocentrynum;
		hd24fs* parentfs;
		unsigned char** cachebuf_ptr;
		__uint32* cachebuf_blocknum;
		hd24project* parentproject;
		hd24song(hd24project* p_parent,__uint32 p_songid);
		unsigned char* getcachedbuffer(long unsigned int);
		void	queuecacheblock(__uint32 blocknum);
		void	loadblockintocache(__uint32 blocknum);
		void	setblockcursor(__uint32 blocknum);
		void 	memoizeblocksectors(__uint32 lastblock);
		__uint32 memblocksector(__uint32 blocknum);
		__uint32 blocktoqueue;		// next block to cache
		__uint32 songcursor;		// current cursor pos within song, in samples
		__uint32 allocentrynum;		// which allocation entry is currently being used
		__uint32 allocstartblock;	// the first audioblock in given entry
		__uint32 allocstartsector;	// the sector pointed to by that entry
		__uint32 allocaudioblocks;	// the number of audioblocks in the block
		__uint32 divider;
		__uint32 lastreadblock;
		__uint32 lastavailablecacheblock;
		__uint32 mustreadblock;
		__uint32 track_armed[24];
		__uint32 track_readenabled[24]; // used to speed up copy mode.
		void unmark_used_clusters(unsigned char* sectors_orphan);
		__uint32 used_alloctable_entries();
		__uint32 audioblocks_in_alloctable();
		void silenceaudioblocks(__uint32 allocsector,__uint32 blocks);
		bool allocatenewblocks(long unsigned int, bool, char*, int*, int (*)());

	public:
		~hd24song();
		string* songname();
		__uint32 songid();
		hd24fs* fs();
		static void sectorinit(unsigned char* sectorbuf);
		static void settrackcount(unsigned char* sectorbuf,__uint32 trackcount);
		static void songname(unsigned char* sectorbuf,string newname);
		void songname(string newname);
		static string* songname(hd24fs* parentfs,unsigned char* sectorbuf);
		void bufferpoll();
		
		void readenabletrack(__uint32 tracknum);
		void readenabletrack(__uint32 tracknum,bool enable);

		bool isrehearsemode();
		void setrehearsemode(bool p_rehearsemode);
		bool recording();

		bool trackarmed(__uint32 tracknum);
		void trackarmed(__uint32 tracknum,bool arm);

		bool istrackmonitoringinput(__uint32 tracknum);
		void startrecord(int record_mode);
		void stoprecord();
		__uint32 samplerate();
		static void samplerate(unsigned char* sectorbuf,__uint32 samplerate);
		void samplerate(__uint32 newrate);
		static __uint32 samplerate(unsigned char* songbuf);
		__uint32 bitdepth();
		__uint32 physical_channels();
		static __uint32 physical_channels(unsigned char* songbuf);
		void physical_channels(__uint32 newchannelcount);
		static void physical_channels(unsigned char* songbuf,__uint32 newchannelcount);
		__uint32 logical_channels();
		static __uint32 logical_channels(unsigned char* songbuf);
		void logical_channels(__uint32 newchannelcount);
		static void logical_channels(unsigned char* songbuf,__uint32 channelcount);
		__uint32 songlength_in_samples();
		__uint32 songlength_in_samples(__uint32 newlen);
		__uint32 songlength_in_samples(__uint32 newlen,bool silence);
		__uint32 songlength_in_samples(__uint32 newlen,bool silence,char* savemessage,int* cancel);
		__uint32 songlength_in_samples(__uint32 newlen,bool silence,char* savemessage,int* cancel,int (*checkfunc)());

		__uint32 display_hours();
		__uint32 display_hours(__uint32 offset);
		static __uint32 display_hours(__uint32 offset,__uint32 samrate);
		
		__uint32 display_minutes();
		__uint32 display_minutes(__uint32 offset);
		static __uint32 display_minutes(__uint32 offset,__uint32 samrate);

		__uint32 display_seconds();
		__uint32 display_seconds(__uint32 offset);
		static __uint32 display_seconds(__uint32 offset,__uint32 samrate);

		__uint32 display_subseconds();
		__uint32 display_subseconds(__uint32 offset);
		static __uint32 display_subseconds(__uint32 offset,__uint32 samrate);

		string*  display_duration();
		string*  display_duration(__uint32 offset);
		string*  display_duration(__uint32 offset,__uint32 samrate);

		string*  display_cursor();
		__uint32 cursorpos();
		__uint32 locatepointcount();
		__uint32 getlocatepos(int locatepoint);

		__uint32 currentlocation();
		void currentlocation(__uint32 offset);
		__uint32 golocatepos(__uint32 offset);

		__uint32 setlocatepos(int locatepoint,__uint32 offset);
		void setlocatename(int locatepoint,string newname);
		string* getlocatename(int locatepoint);
		bool iswriteprotected();
		void setwriteprotected(bool prot);
		void getmultitracksample(long* mtsample,int readmode);
		int getmtrackaudiodata(__uint32 firstsamnum,__uint32 samples,unsigned char* buffer,int readmode);
		int putmtrackaudiodata(__uint32 firstsamnum,__uint32 samples,unsigned char* buffer,int writemode);
		void deinterlaceblock(unsigned char* buffer,unsigned char* targetbuffer);
		void interlaceblock(unsigned char* buffer,unsigned char* targetbuffer);
		static const int  LOCATEPOS_SONGSTART;	
		static const int  LOCATEPOS_LOOPSTART;	
		static const int  LOCATEPOS_LOOPEND;
		static const int  LOCATEPOS_PUNCHIN;
		static const int  LOCATEPOS_PUNCHOUT;
		static const int  LOCATEPOS_EDITIN;	
		static const int  LOCATEPOS_EDITOUT;	
		static const int  LOCATEPOS_LAST;
		static const int  READMODE_COPY;
		static const int  READMODE_REALTIME;
		static const int  WRITEMODE_COPY;
		static const int  WRITEMODE_REALTIME;

		__uint32 getnextfreesector(__uint32 allocsector);
		bool has_unexpected_end();	  // indicates if there is an 'unexpected end of song' error
		bool is_fixable_unexpected_end(); // ...and if so, if we know how to fix it.
		bool setallocinfo(bool silencenew);
		bool setallocinfo(bool silencenew,char* message,int* cancel,int (*checkfunc)());
		__uint32 requiredaudioblocks(__uint32 songlen);
		void appendorphanclusters(unsigned char*,bool allowsongresize);
		void save();
};

class hd24project 
{
	friend class hd24fs;
	friend class hd24song;

	private:
		unsigned char* buffer;
		hd24fs*	parentfs;
		__sint32 myprojectid;
		hd24song* songlist;	
		hd24project(hd24fs* p_parent,__sint32 projectid);
		hd24project(hd24fs* p_parent,__sint32 projectid,__uint32 projsector,const char* projectname,bool isnew);
		__uint32 getsongsectornum(int i);
		void setsongsectornum(int i,__uint32 newsector);
		void save(__uint32 projsector);
		void populatesongusagetable(unsigned char* songused);
		__uint32 getunusedsongslot();
		void initvars(hd24fs* p_parent,__sint32 p_projectid);
	public:
		~hd24project();
		string* projectname();
		void projectname(string newname);
		__sint32 lastsongid();
		void lastsongid(signed long songid);
		__uint32 songcount();
		__uint32 maxsongs();
		__sint32 projectid();
		hd24song* getsong(__uint32 songid);
		hd24song* createsong(const char* songname,__uint32 trackcount,__uint32 samplerate);
		__uint32 deletesong(__uint32 songid);
		void save();
		void sort();
};

class hd24fs 
{
	friend class hd24project;
	friend class hd24song;
	friend class hd24raw;
	friend class hd24utils;

	private:
		const char* imagedir;
		int transportstatus;
		bool writeprotected;
		bool allinput;
		bool autoinput;
		bool forcemode;
		bool formatting; // true during a format operation
		bool headermode;
		bool maintenancemode;
		bool wavefixmode;
		__uint32 highestFSsectorwritten;

		__uint32 nextfreeclusterword;	// memoization cache for write allocation

		FSHANDLE devhd24;	// device handle
		FSHANDLE hd24header;	// header device handle
		bool m_isOpen;
		bool gotlastsectornum;
		__uint32 foundlastsectornum;
		int p_mode;
		hd24project* projlist;	
		string* devicename;	
		unsigned char* sector_boot;
		unsigned char* sector_diskinfo;
		unsigned char* sectors_driveusage;	
		unsigned char* sectors_orphan;	
		unsigned char* sectors_songusage;	
		long readsectors(FSHANDLE handle, __uint32 secnum, unsigned char* buffer,int sectors);
		long readsector(FSHANDLE handle, __uint32 secnum, unsigned char* buffer);
		long readsector_noheader(FSHANDLE handle, __uint32 secnum, unsigned char* buffer);
		long readsector_noheader(hd24fs* currenthd24, __uint32 secnum, unsigned char* buffer);
		long writesectors(FSHANDLE handle, __uint32 secnum, unsigned char* buffer,int sectors);
		long writesector(FSHANDLE handle, __uint32 secnum, unsigned char* buffer);

		string* gethd24currentdir(int, char**);
		void hd24close();
		void hd24closedevice(FSHANDLE handle);
		static void hd24seek(FSHANDLE handle,__uint64 seekpos);
		void clearbuffer(unsigned char* buffer);
		void clearbuffer(unsigned char* buffer,unsigned int bytes);
		FSHANDLE findhd24device();
		FSHANDLE findhd24device(int mode);
		FSHANDLE findhd24device(int mode, int base0devnum);
		FSHANDLE findhd24device(int mode, string* dev,bool force,bool tryharder);
		static bool isinvalidhandle(FSHANDLE handle);
		unsigned char* readbootinfo();
		unsigned char* readdiskinfo();
		unsigned char* readdriveusageinfo();
		unsigned char* resetsongusage();
		unsigned char* resetdriveusage();
		unsigned char* calcsongusage();
		void refreshsongusage();
		unsigned char* getsector_bootinfo();
		unsigned char* getsector_diskinfo();
		unsigned char* getsectors_driveusage();
		unsigned char* getcopyofusagetable(); // allocates memory and fills it up with a copy of the current usage table
		void initvars();
		__uint32 driveusagesectorcount();
		__uint32 clustercount();
		__uint32 driveusagefirstsector();
		__uint32 getblockspercluster();
		__uint32 getprojectsectornum(__uint32 base1proj);
		bool isfreecluster(__uint32 clusternum);
		bool isfreecluster(__uint32 clusternum,unsigned char* usagebuffer);
		__uint32 freeclustercount();
		__uint32 getlastsectornum();
		__uint32 getlastsectornum(FSHANDLE handle);
		__uint32 headersectors;
		void writebackupblock(__uint32 sector,__uint32 blocksize,
				      __uint32 lastsec,bool fullcommit);
		__uint32 getnextfreesectorword();
		__uint32 getnextfreeclusterword();
		__uint32 getnextfreesector(__uint32 cluster);
		void enablebit(__uint32 ibit,unsigned char* usagebuffer);
		void disablebit(__uint32 ibit,unsigned char* usagebuffer);
		bool isbitzero(__uint32 ibit,unsigned char* usagebuffer);
		long unsigned int songentry2songsector(long unsigned int entry);
		long unsigned int songsector2songentry(long unsigned int entry);
		void allocsongentry(__uint32 entrynum);
		void allocatecluster(__uint32 clusternum);
		void allocatecluster(__uint32 clusternum,unsigned char* usagebuffer);
		void freecluster(__uint32 clusternum);
		void freecluster(__uint32 clusternum,unsigned char* usagebuffer);
		signed long nextunusedsongentry();
		void useinternalboot(unsigned char*, long unsigned int);
		__uint32 getunusedsongsector();
		__uint32 songsondisk();
		void songsondisk(__uint32 songsondisk);
		void setprojectsectornum(int i,__uint32 newsector);
		void setimagedir(const char* newdir);
		int deviceid;
	public:
		__uint32 lasterror;
		void force_reload();
		static void setname(unsigned char* namebuf,string newname,__uint32 shortnameoff,__uint32 longnameoff);
		void dumpclusterusage();
		void dumpclusterusage(unsigned char* buffer);
		void dumpclusterusage2();
		void dumpclusterusage2(unsigned char* buffer);
		unsigned char* findorphanclusters();
		static const int TRANSPORTSTATUS_PLAY;
		static const int TRANSPORTSTATUS_STOP;
		static const int TRANSPORTSTATUS_REC;
		__uint32 cluster2sector(__uint32 clusternum);
		__uint32 sector2cluster(__uint32 sectornum);
		__uint32 songentry2sector(__uint32 entrynum);
		__uint32 songsector2entry(__uint32 sectornum);
		void settransportstatus(int newstatus);
		int gettransportstatus();
		bool	isallinput();
		void	setallinput(bool p_allinput);
		void	setallinput(void);
		bool	isautoinput();
		void	setautoinput(bool p_autoinput);
		void	setautoinput(void);

		hd24fs(const char* imagedir);
		hd24fs(const char* imagedir,int mode);
		hd24fs(const char* imagedir,int mode,int base0devnum);
		hd24fs(const char* imagedir,int mode,string* dev,bool force);		
		~hd24fs();
		__uint32 getblocksizeinsectors();
		__uint32 getbytesperaudioblock();
		static void fstfix(unsigned char* bootblock,int fixsize);
		bool isOpen();	
		int mode();
		string* volumename();
		string* getdevicename();
		int getdeviceid();
		void setdevicename(const char* orig,string* newname);
		void setvolumename(string newname);
		string* version();
		__uint32 hd24devicecount();
		__sint32 lastprojectid();
		void lastprojectid(signed long projectid);
		__uint32 projectcount();
		__uint32 maxprojects();
		__uint32 maxsongsperproject();	
		hd24project* getproject(__sint32 projectid);
		hd24project* createproject(const char* projectname);
		void setmaintenancemode(int mode);
		int getmaintenancemode();
		void setwavefixmode(int mode);
		int getwavefixmode();
		string* gethd24currentdir();
		static const int MODE_RDONLY;
		static const int MODE_RDWR;
		string* freespace(__uint32 rate,__uint32 tracks);
		bool useheaderfile(string headerfilename);
		bool isexistingdevice(string *devname);
		bool commit(bool fullcommit);
		bool commit();		
		long unsigned int setsectorchecksum(unsigned char* buffer,unsigned int startoffset,unsigned int startsector,unsigned int sectors);
		void savedriveinfo();
		void savedriveusage();
		__uint32 writesuperblock(__uint32 lastsectornum);
		void cleardriveinfo(unsigned char* buffer);
		__uint32 writedriveinfo();
		__uint32 writesongusage();
		__uint32 writedriveusage();
		__uint32 quickformat(char* lasterror);
		__uint32 deleteproject(__sint32 projid);
		void write_enable();
		void write_disable();
};

/* Provides sector level access to hd24 disks 
 * (functionality which is private in hd24fs) 
 */
class hd24raw 
{
	friend class hd24fs;

	private:
		hd24fs* fsys;
		
	public:
		hd24raw(hd24fs* fsys);
		hd24raw(hd24fs* fsys,bool notranslate);
		~hd24raw() {};
		long readsectors(__uint32 secnum, unsigned char* buffer,int sectors);
		long writesectors(__uint32 secnum, unsigned char* buffer,int sectors);
		__uint32 getnextfreesector(__uint32 cluster);
		__uint32 getprojectsectornum(__uint32 projectid);
		__uint32 getlastsectornum();
		__uint32 songsondisk();
		__uint32 quickformat(char* lasterror); 
};

#endif