source: trunk/src_apollo/org/apollo/io/AudioPathManager.java@ 315

Last change on this file since 315 was 315, checked in by bjn8, 16 years ago

Apollo spin-off added

File size: 5.7 KB
Line 
1package org.apollo.io;
2
3import java.io.BufferedReader;
4import java.io.File;
5import java.io.FileReader;
6import java.io.FileWriter;
7import java.io.IOException;
8import java.io.UnsupportedEncodingException;
9import java.util.Random;
10
11import org.apollo.audio.structure.AudioStructureModel;
12import org.apollo.util.AudioSystemLog;
13import org.apollo.util.RegExpFileFilter;
14
15/**
16 * Generates audio paths.
17 *
18 * @author Brook Novak
19 *
20 */
21public class AudioPathManager {
22
23 private AudioPathManager() {
24 // util constructor
25 }
26
27 /** Suffixed with the native file separator */
28 public static final String AUDIO_HOME_DIRECTORY = "audio" + File.separatorChar;
29 // TODO: TMP FOR WORKING IN LINUX LABS: Avoids using my quota
30 //public static final String AUDIO_HOME_DIRECTORY = "/research/bjn8/apollosaudio/";
31
32 /** Stores all virtual names created by this repository. */
33 private static final String VIRTUAL_NAME_BASEFILE = ".vnames";
34
35 public static final int PREAMBLE_LENGTH = 6;
36
37 private static long counter = 0;
38
39 private static Random rand = new Random(System.currentTimeMillis());
40
41 /**
42 * Class initializer.
43 * Ensures that the home directory(ies) exist and preps the counter
44 */
45 static {
46
47 // Ensure audio directory exists
48 File dir = new File(AUDIO_HOME_DIRECTORY);
49 if (!dir.exists()) {
50 if (!dir.mkdir()) {
51 AudioSystemLog.println("Unable to create missing audio home directory");
52 }
53 }
54
55 // Load counter
56 loadCounter(dir);
57 }
58
59 /**
60 * Loads the counter
61 * @param dir The dir where the audio files live.
62 */
63 public static void loadCounter(File dir) {
64 String[] files = dir.list(new RegExpFileFilter("^[A-Z]+\\d+.*$"));
65 long count = 0;
66 if (files != null) {
67 for (String f : files) {
68
69 int start = -1, end = -1;
70 for (int i = 0; i < f.length(); i++) {
71 if (Character.isDigit(f.charAt(i)) && start == -1) {
72 start = i;
73 } else if (!Character.isDigit(f.charAt(i)) && start != -1) {
74 end = i;
75 break;
76 }
77 }
78
79 if (start >= 0 && end == -1) end = f.length();
80
81 if (start > 0 && end >= start) { // not start >= 0 since missing preable
82
83 String tmp = f.substring(start, end);
84 long l = Long.parseLong(tmp);
85 if (l >= count)
86 count = l + 1;
87 }
88 }
89 }
90
91 counter = count;
92 }
93
94 /**
95 * @return The current counter.
96 */
97 public static long getCounter() {
98 return counter;
99 }
100
101 /**
102 * Generates a filename that is unique within the AUDIO_HOME_DIRECTORY.
103 *
104 * @param extension
105 * The extension of the filename to generate. Exclude period.
106 *
107 * @return
108 * A free unused filename with the given extension. Excludes directory.
109 * Even if the path return is not used, it will never be re-generated.
110 */
111 public static String generateLocateFileName(String extension) {
112
113 String filename = generateRandomFilenameBase() + "." + extension;
114
115 File f = new File(AUDIO_HOME_DIRECTORY + filename);
116
117 if (AudioStructureModel.getInstance().getTrackGraphInfo(filename, null) != null ||
118 f.exists()) { // recurse: until found a free path:
119 return generateLocateFileName(extension);
120 }
121
122 return filename;
123 }
124
125 private static String generateRandomFilenameBase() {
126
127 counter++;
128 if (counter < 0) counter = 0; // wraps positivey
129
130 // Generate random alpha preamble
131 byte[] bytes = new byte[PREAMBLE_LENGTH];
132 rand.nextBytes(bytes);
133
134
135 for (int i = 0; i < PREAMBLE_LENGTH; i++) {
136 if (bytes[i] < 0) bytes[i] *= -1;
137 int alphacap = (65 + (Math.abs(bytes[i]) % 26)); // A-Z in US ASCII encoding
138 bytes[i] = (byte) alphacap;
139
140 }
141
142 // Decode ASCII Byte array to javas UTF-16 encoding
143 String preamble = null;
144
145 try {
146 preamble = new String(bytes, "US-ASCII");
147 } catch (UnsupportedEncodingException e) {
148 e.printStackTrace();
149 preamble = "AUDIO";
150 }
151
152 // Build the filename string
153 return preamble + counter;
154
155 }
156
157
158
159 /**
160 * Lots of room for improvement here, ensures that a virtual filename is unique .. stores
161 * allocated virtual filenames on file.
162 *
163 * @return
164 * The new virtual filename.
165 */
166 public static String generateVirtualFilename() {
167
168 // Ensure that the name base file exists. Assumes the audio home directory exists.
169 File vnameBase = new File(AUDIO_HOME_DIRECTORY + VIRTUAL_NAME_BASEFILE);
170 if (!vnameBase.exists()) {
171 try {
172 vnameBase.createNewFile();
173 } catch (IOException e) {
174 e.printStackTrace();
175 }
176 }
177
178 String vname = null;
179
180 while (vname == null) {
181 vname = generateRandomFilenameBase() + ".vrt";
182 assert(vname != null);
183
184 BufferedReader in = null;
185 String line = null;
186
187 try {
188
189 // Open the vbase for reading
190 in = new BufferedReader(new FileReader(vnameBase));
191
192 // Read the sbase file and check all names
193 while ((line = in.readLine()) != null) {
194 line = line.trim();
195 if (line.equalsIgnoreCase(vname)) break;
196 }
197
198 } catch (Exception e) {
199 e.printStackTrace();
200 break; // just use the last generated filename...
201
202 // Clean up
203 } finally {
204 if (in != null) {
205 try {
206 in.close();
207 } catch (IOException e) {
208 e.printStackTrace();
209 }
210 }
211 }
212
213 // Check to see if name is infact unique
214 if (AudioStructureModel.getInstance().getLinkedTrackGraphInfo(vname, null) == null &&
215 (line == null || !line.equalsIgnoreCase(vname))) {
216 // If so, then enter new entry into the db.
217 FileWriter out = null;
218
219 try {
220 // Open the vbase for appending
221 out = new FileWriter(vnameBase, true);
222 out.write("\n" + vname);
223
224 } catch (IOException e) {
225 e.printStackTrace();
226
227 // Clean up
228 } finally {
229 if (out != null) {
230 try {
231 out.close();
232 } catch (IOException e) {
233 e.printStackTrace();
234 }
235 }
236 }
237
238 } else vname = null;
239 }
240
241 // Return the generated vname
242 return vname;
243
244 }
245}
Note: See TracBrowser for help on using the repository browser.