aa2b = ResourceUtils.getRelativePathSections(a,b);
43 | assertEquals(2,aa2b.size());
44 | assertEquals("..",aa2b.get(0))
45 | assertEquals("b",aa2b.get(1))
46 |
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/net/sf/jtpl/TemplateFactory.java:
--------------------------------------------------------------------------------
1 | package net.sf.jtpl;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.io.InputStreamReader;
6 | import java.io.Reader;
7 |
8 | /**
9 | * Templates may be loaded any way you want using the different constructor,
10 | * but this helper supports the practice of keeping them in the same package
11 | * as the class that loads them.
12 | *
13 | * When bundling templates inside jars the files should really be in a folder
14 | * matching the namespace of the component, so they don't collide with files
15 | * of the same name from other jars.
16 | */
17 | public abstract class TemplateFactory {
18 |
19 | /**
20 | * Loads template for a class assuming that it is placed in the corresponding folder
21 | * in src/main/resources/ (maven project) or in the same package in a jar.
22 | * @param filename The filename of the template
23 | * @param samePackage The class that loads the template, providing namespace and class loader
24 | * @return The template
25 | * @throws RuntimeException if loading fails, considered unrecoverable, wrapping IOException
26 | */
27 | public static Template getTemplate(String filename, Class samePackage) {
28 | String parent = samePackage.getPackage().getName().replace('.', '/');
29 | String path = parent + '/' + filename;
30 | InputStream htmlin = samePackage.getClassLoader().getResourceAsStream(path);
31 | if (htmlin == null) {
32 | throw new RuntimeException("Failed to load template " + path);
33 | }
34 | Reader htmlr = new InputStreamReader(htmlin);
35 | // TODO should we buffer content here or leave it to Template to take adequate care of the reader?
36 | try {
37 | return new Template(htmlr);
38 | } catch (IOException e) {
39 | // Really not recoverable
40 | throw new RuntimeException("Unable to read classpath template " + path, e);
41 | }
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/resources/formats/Live/DataBlockUnknowns.txt:
--------------------------------------------------------------------------------
1 | Live Data Blocks
2 |
3 | FileRef : 00 00 00 00 01 4E 00 02 00 00
4 | Source Context : 00 00 00 00 01 3E 00 02 00 01
5 |
6 |
7 | Stuff 1 :
8 |
9 | Source Context :
10 |
11 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
12 | 00 00 CA A4 C7 7D 48 2B 00 00 00 04 4A 33
13 |
14 | File Ref :
15 |
16 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
17 | 00 00 CA A4 C7 7D 48 2B 00 00 00 04 4A 34
18 |
19 | Stuff 2 :
20 |
21 | Source Context :
22 |
23 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
24 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
25 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
26 | 00 00 00 00 00 00 00 04 4A 34 CA A4 C8 48 00 00
27 | 00 00 00 00 00 00 FF FF FF FF 00 00 09 20 00 00
28 | 00 00 00 00 00 00 00 00 00 00 00 00 00
29 |
30 | File Ref :
31 |
32 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
33 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
34 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
35 | 00 00 00 00 00 00 00 00 00 00 00 05 C5 70 BF C1
36 | 2C D1 00 00 00 00 00 00 00 00 FF FF FF FF 00 00
37 | 09 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00
38 | 00
39 |
40 | File Ref :
41 |
42 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
43 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
44 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
45 | 00 00 00 00 00 00 00 00 05 BB 93 C0 AC 3F AB 00
46 | 00 00 00 00 00 00 00 FF FF FF FF 00 00 09 20 00
47 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00
48 |
49 | Stuff 3 :
50 |
51 | Source Context :
52 |
53 | 00 10 00 08 00 00 CA A4 B9 6D 00 00 00 11 00 08
54 | 00 00 CA A4 BA 38 00 00 00 01 00 08 00 04 4A 33
55 | 00 00 BE D7 00 02 00
56 |
57 | File Ref :
58 |
59 | 00 00 10 00 08 00 00 CA A4 B9 6D 00 00 00 11 00
60 | 08 00 00 BF C1 2C D1 00 00 00 01 00 0C 00 04 4A
61 | 34 00 04 4A 33 00 00 BE D7 00 02 00
62 |
63 |
64 | Stuff 4 :
65 |
66 | Source Context :
67 |
68 | 00 0E 00 14 00
69 |
70 | File Ref :
71 |
72 | 00 00 0E 00 0C 00
73 |
74 |
--------------------------------------------------------------------------------
/src/main/com/relivethefuture/dkb/SampleTableFormat.groovy:
--------------------------------------------------------------------------------
1 | package com.relivethefuture.dkb
2 |
3 | import ca.odell.glazedlists.GlazedLists
4 | import ca.odell.glazedlists.gui.AdvancedTableFormat
5 | import ca.odell.glazedlists.gui.WritableTableFormat
6 | import com.relivethefuture.generic.Sample
7 |
8 | class SampleTableFormat implements AdvancedTableFormat,WritableTableFormat {
9 |
10 | def columnNames = ["Note","Name", "Size (k)","Exclude"]
11 | def classes = [Integer.class, String.class,Integer.class,Boolean.class]
12 |
13 | Class getColumnClass(int index) {
14 | return classes[index]
15 | }
16 |
17 | Comparator getColumnComparator(int index) {
18 | if(index == 3) {
19 | return SampleComparator.EXCLUDED.tableComparator
20 | } else if(index == 2) {
21 | return SampleComparator.SIZE.tableComparator
22 | } else if(index == 1) {
23 | return SampleComparator.NAME.tableComparator
24 | } else {
25 | return SampleComparator.NOTE.tableComparator
26 | }
27 | }
28 |
29 | boolean isEditable(Sample sample, int index) {
30 | return (index == 3)
31 | }
32 |
33 | Sample setColumnValue(Sample sample, Object newValue, int index) {
34 | if(index == 3) {
35 | sample.exclude = newValue
36 | }
37 | return sample
38 | }
39 |
40 | int getColumnCount() {
41 | return columnNames.size()
42 | }
43 |
44 | String getColumnName(int index) {
45 | return columnNames[index]
46 | }
47 |
48 | Object getColumnValue(Sample sample, int index) {
49 | if(index == 3) {
50 | return sample.exclude
51 | } else if(index == 2) {
52 | return Math.floor(sample.size / 1024) as Integer
53 | } else if(index == 1) {
54 | return sample.name
55 | } else {
56 | return sample.root
57 | }
58 |
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/DrumKitBuilder2.iml:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/src/main/javaFlacEncoder/FLACStreamIdentifier.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 Preston Lacey http://javaflacencoder.sourceforge.net/
3 | * All Rights Reserved.
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | package javaFlacEncoder;
21 |
22 | /**
23 | * Provides the stream identifier used at beginning of flac streams.
24 | * @author Preston Lacey
25 | */
26 | public class FLACStreamIdentifier {
27 | static final byte streamMarkerByte1 = 0x66;
28 | static final byte streamMarkerByte2 = 0x4c;
29 | static final byte streamMarkerByte3 = 0x61;
30 | static final byte streamMarkerByte4 = 0x43;
31 | static final byte[] marker = { streamMarkerByte1,
32 | streamMarkerByte2,
33 | streamMarkerByte3,
34 | streamMarkerByte4,
35 | };
36 |
37 | /**
38 | * Get an EncodedElement containing the marker(which is itself in a byte
39 | * array).
40 | * @return EncodedElement containing the marker.
41 | */
42 | public static EncodedElement getIdentifier() {
43 | EncodedElement ele = new EncodedElement();
44 | ele.setData(marker.clone());
45 | ele.setUsableBits(32);
46 | return ele;
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/griffon-app/views/drumkitbuilder2/DrumKitBuilderMenuBar.groovy:
--------------------------------------------------------------------------------
1 | package drumkitbuilder2
2 |
3 | import javax.swing.event.PopupMenuListener
4 |
5 | import static griffon.util.GriffonApplicationUtils.getIsMacOSX
6 |
7 | menuBar = menuBar {
8 | menu(text: app.getMessage('application.menu.File.name', ' File'),
9 | mnemonic: app.getMessage('application.menu.File.mnemonic', 'F')) {
10 | menuItem(browseAction)
11 | menuItem(configureAction)
12 | menuItem(exportAction)
13 | menu(id: 'openRecentMenu', enabled: false,
14 | text: app.getMessage('application.menu.OpenRecent.name', ' Open Recent...'),
15 | mnemonic: app.getMessage('application.menu.OpenRecent.mnemonic', 'E'))
16 | separator()
17 | if (!isMacOSX) {
18 | separator()
19 | menuItem(quitAction)
20 | }
21 | }
22 |
23 | if (!isMacOSX) glue()
24 | menu(text: app.getMessage('application.menu.Help.name', 'Help'),
25 | mnemonic: app.getMessage('application.menu.Help.mnemonic', 'H')) {
26 | if (!isMacOSX) {
27 | menuItem(aboutAction)
28 | }
29 | menuItem(helpAction)
30 | }
31 | }
32 |
33 | openRecentMenu.popupMenu.addPopupMenuListener([
34 | popupMenuWillBecomeVisible: {
35 | println openRecentMenu
36 | openRecentMenu.removeAll()
37 | model.recentFolders.eachWithIndex { file, int i ->
38 | openRecentMenu.add(action(
39 | name: "${i + 1}. ${file.name}".toString(),
40 | mnemonic: 1 + i,
41 | closure: { controller.scan(file) }
42 | ))
43 | }
44 | if (model.recentScripts.size()) {
45 | openRecentMenu.add(separator())
46 | openRecentMenu.add(clearRecentFoldersAction)
47 | }
48 | },
49 | popupMenuWillBecomeInvisible: {/*empty*/},
50 | popupMenuCanceled: {/*empty*/}
51 | ] as PopupMenuListener)
52 |
53 | return menuBar
--------------------------------------------------------------------------------
/src/main/com/relivethefuture/kitbuilder/output/OutputConfig.java:
--------------------------------------------------------------------------------
1 | package com.relivethefuture.kitbuilder.output;
2 |
3 | import com.relivethefuture.formats.SamplerFormat;
4 | import com.relivethefuture.generic.*;
5 | import com.relivethefuture.generic.InstrumentFactory;
6 | import com.relivethefuture.kitbuilder.writers.InstrumentWriter;
7 |
8 | /**
9 | */
10 | public class OutputConfig extends GenericOutput {
11 |
12 | private SamplerFormat format;
13 | private InstrumentWriter writer;
14 | private InstrumentFactory instrumentFactory;
15 |
16 | private SampleFactory sampleFactory;
17 | private ZoneFactory zoneFactory;
18 |
19 | public OutputConfig() {
20 | instrumentFactory = new BasicInstrumentFactory();
21 | sampleFactory = new BasicSampleFactory();
22 | zoneFactory = new BasicZoneFactory();
23 | }
24 |
25 | public InstrumentWriter getWriter() {
26 | return writer;
27 | }
28 |
29 | public void setWriter(InstrumentWriter writer) {
30 | this.writer = writer;
31 | }
32 |
33 | public SamplerFormat getFormat() {
34 | return format;
35 | }
36 |
37 | public void setFormat(SamplerFormat format) {
38 | this.format = format;
39 | if(getRelativePath() == null) {
40 | setRelativePath(format.type());
41 | }
42 | }
43 |
44 | public InstrumentFactory getInstrumentFactory() {
45 | return instrumentFactory;
46 | }
47 |
48 | public void setInstrumentFactory(InstrumentFactory instrumentFactory) {
49 | this.instrumentFactory = instrumentFactory;
50 | }
51 |
52 | public SampleFactory getSampleFactory() {
53 | return sampleFactory;
54 | }
55 |
56 | protected void setSampleFactory(SampleFactory sampleFactory) {
57 | this.sampleFactory = sampleFactory;
58 | }
59 |
60 | public ZoneFactory getZoneFactory() {
61 | return zoneFactory;
62 | }
63 |
64 | protected void setZoneFactory(ZoneFactory zoneFactory) {
65 | this.zoneFactory = zoneFactory;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/griffon-app/controllers/drumkitbuilder2/DialogController.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2007-2012 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | */
15 |
16 | package drumkitbuilder2
17 |
18 | import griffon.transform.Threading
19 |
20 | import java.awt.*
21 |
22 | /**
23 | * @author Andres Almiray
24 | */
25 | class DialogController {
26 | def model
27 | def view
28 | def builder
29 |
30 | protected dialog
31 |
32 | @Threading(Threading.Policy.INSIDE_UITHREAD_SYNC)
33 | def show = { Window window = null ->
34 | window = window ?: Window.windows.find {it.focused}
35 | if (!dialog || dialog.owner != window) {
36 | dialog = builder.dialog(
37 | owner: window,
38 | title: model.title,
39 | resizable: model.resizable,
40 | modal: model.modal) {
41 | container(view.content)
42 | }
43 | if (model.width > 0 && model.height > 0) {
44 | dialog.preferredSize = [model.width, model.height]
45 | }
46 | dialog.pack()
47 | }
48 | int x = window.x + (window.width - dialog.width) / 2
49 | int y = window.y + (window.height - dialog.height) / 2
50 | dialog.setLocation(x, y)
51 | dialog.visible = true
52 | }
53 |
54 | @Threading(Threading.Policy.INSIDE_UITHREAD_SYNC)
55 | def hide = { evt = null ->
56 | log.debug("Disposing of dialog")
57 | dialog?.visible = false
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/DrumKitBuilder2-griffonPlugins.iml:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/griffon-app/resources/templates/ableton/sections/MultiSamplePart.xml:
--------------------------------------------------------------------------------
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 | {relativePaths}
53 |
54 |
55 |
56 | {fileRefData}
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/resources/packaging/SampleMapBuilder.exe4j:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/test/unit/com/relivethefuture/dkb/PathUtilsTest.groovy:
--------------------------------------------------------------------------------
1 | package com.relivethefuture.dkb
2 |
3 | import com.relivethefuture.FilenameUtils
4 | import org.junit.Before
5 | import org.slf4j.Logger
6 | import org.slf4j.LoggerFactory
7 |
8 | import static org.junit.Assert.assertEquals
9 |
10 | /**
11 | * Created by martin on 20/04/13 at 16:54
12 | *
13 | */
14 | class PathUtilsTest {
15 |
16 | private final Logger logger = LoggerFactory.getLogger(PathUtilsTest.class);
17 |
18 | @Before
19 | public void setUp() throws Exception {
20 |
21 |
22 | }
23 |
24 | void testAddStructure() {
25 | File dest = new File("D:/a")
26 | File source = new File("D:/b/c/d/e/f")
27 |
28 | File a1 = PathUtils.addDirectoryStructure(dest, source, 1)
29 | assertEquals("D:\\a\\f",a1.getAbsolutePath())
30 | File a2 = PathUtils.addDirectoryStructure(dest, source, 2)
31 | assertEquals("D:\\a\\e\\f",a2.getAbsolutePath())
32 | File a3 = PathUtils.addDirectoryStructure(dest, source, 3)
33 | assertEquals("D:\\a\\d\\e\\f",a3.getAbsolutePath())
34 | File all = PathUtils.addDirectoryStructure(dest, source, 10)
35 | assertEquals("D:\\a\\b\\c\\d\\e\\f",all.getAbsolutePath())
36 | }
37 |
38 | void testAbsoluteOutput() {
39 | File outputDirectory = new File("D:/tmp")
40 | File sourceDirectory = new File("D:/audio/samples")
41 | String relativePath = null
42 | OutputLayout layout = new OutputLayout()
43 |
44 | layout.layoutStyle = LayoutStyle.ABSOLUTE
45 | layout.outputStructureDepth = 0
46 | File out = PathUtils.getOutputDirectoryForLayout(outputDirectory, sourceDirectory, layout, relativePath)
47 | assertEquals out, outputDirectory
48 | }
49 |
50 | void testRelativeOutput() {
51 | File outputDirectory = new File("D:/tmp")
52 | File sourceDirectory = new File("D:/audio/samples")
53 | String relativePath = "relative"
54 | OutputLayout layout = new OutputLayout()
55 |
56 | layout.layoutStyle = LayoutStyle.RELATIVE
57 | layout.outputStructureDepth = 0
58 | File out = PathUtils.getOutputDirectoryForLayout(outputDirectory, sourceDirectory, layout, relativePath)
59 | assertEquals out, new File(outputDirectory, relativePath)
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/javaFlacEncoder/ArrayRecycler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 Preston Lacey http://javaflacencoder.sourceforge.net/
3 | * All Rights Reserved.
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | package javaFlacEncoder;
21 |
22 | import java.util.concurrent.LinkedBlockingQueue;
23 |
24 | /**
25 | * The purpose of this class is to provide a source for reusable int arrays.
26 | * When using large numbers of arrays in succession, it is inefficient to
27 | * constantly go in an allocate/free loop. This way, we may pass a single,
28 | * thread-safe recycler to all objects. No matter where the arrays end their
29 | * life, we can then add it to the same resource store.
30 | *
31 | * @author Preston Lacey
32 | */
33 | public class ArrayRecycler {
34 | LinkedBlockingQueue usedIntArrays = null;
35 | ArrayRecycler() {
36 | usedIntArrays = new LinkedBlockingQueue();
37 | }
38 | public void add(int[] array) {
39 | usedIntArrays.add(array);
40 | }
41 |
42 | /**
43 | *
44 | * @param size
45 | * @return
46 | */
47 | public int[] getArray(int size) {
48 | int[] result = usedIntArrays.poll();
49 | if(result == null) {
50 | result = new int[size];
51 | //System.err.println("Created new int array from null");
52 | }
53 | else if(result.length < size) {
54 | usedIntArrays.offer(result);
55 | result = new int[size];
56 | //System.err.println("created new int array from bad size");
57 | }
58 | return result;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/com/relivethefuture/kitbuilder/KitFileNameGenerator.groovy:
--------------------------------------------------------------------------------
1 | package com.relivethefuture.kitbuilder;
2 |
3 | import com.relivethefuture.ResourceUtils;
4 | import com.relivethefuture.dkb.OutputLayout;
5 | import com.relivethefuture.formats.SamplerFormat;
6 | import com.relivethefuture.kitbuilder.model.FolderOfSamples;
7 | import com.relivethefuture.kitbuilder.output.OutputConfig;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | public class KitFileNameGenerator {
12 | private final Logger logger = LoggerFactory.getLogger(KitFileNameGenerator.class);
13 |
14 | private OutputLayout layout;
15 | private OutputConfig config;
16 |
17 | public String generateFileName(FolderOfSamples fos, String extra) {
18 |
19 | String mapFileName = "";
20 | if(extra == null) {
21 | extra = "";
22 | }
23 |
24 | SamplerFormat format = config.getFormat();
25 |
26 | logger.debug("Generate filename for " + fos.getSourceDirectory().getName() + " : " + config.getFormat() + " : " + extra);
27 | if(fos.getName() != null) {
28 | List pathSections = ResourceUtils.getPathSections(fos.getSourceDirectory());
29 | // If there are more sections in the path than required just remove them
30 | logger.debug("PS " + pathSections.size() + " : " + layout.getFilenameDepth());
31 | if(pathSections.size() > layout.getFilenameDepth()) {
32 | int spare = pathSections.size() - layout.getFilenameDepth();
33 | for(int i=0;i columnNames[index] },
26 | getColumnValue: { object, index ->
27 | switch(index) {
28 | case 0: return object.name;break;
29 | case 1: return object.samples.size();break;
30 | case 2: return object.sourceDirectory.absolutePath; break;
31 | default : return ""
32 | }
33 | }] as TableFormat)
34 | }
35 |
36 | splitPane(id: 'mainContent', resizeWeight: 0.45f, border: emptyBorder(0),orientation: JSplitPane.HORIZONTAL_SPLIT) {
37 | jxtitledPanel(title: "Folders", border: emptyBorder(0),
38 | constraints: context.CENTER) {
39 | scrollPane(border:matteBorder(color: Color.BLACK,top:0,left:0,bottom:0,right:1)) {
40 | table(id: "foldersTable", model: createFoldersTableModel(),selectionModel:model.selectedFolders, autoCreateRowSorter:false)
41 | def tableSorter = new TableComparatorChooser(foldersTable, model.folders, AbstractTableComparatorChooser.SINGLE_COLUMN)
42 |
43 | }
44 | }
45 | jxtitledPanel(title: "Kit", border:emptyBorder(0),
46 | constraints: context.CENTER) {
47 | scrollPane(border:matteBorder(color: Color.BLACK,top:0,left:1,bottom:0,right:0)) {
48 | table(id: "samplesTable", model: model.samplesTableModel, selectionModel:model.selectedSamples, autoCreateRowSorter:false, dragEnabled:true,dropMode:DropMode.INSERT_ROWS)
49 | }
50 | keyStrokeAction(component: samplesTable,
51 | keyStroke: 'SPACE',
52 | action: toggleSampleEnabled)
53 | }
54 | }
55 | mainContent
56 |
--------------------------------------------------------------------------------
/griffonw.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Griffon startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRIFFON_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\wrapper\griffon-wrapper.jar
73 |
74 | @rem Execute Griffon
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRIFFON_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GriffonWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRIFFON_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRIFFON_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/resources/formats/Live/OSX Data Blocks/Plan.txt:
--------------------------------------------------------------------------------
1 | 4 Null Bytes
2 |
3 | 2 Bytes Data length (including previous 4 bytes)
4 |
5 | 4 Bytes : 00 02 00 00
6 |
7 | 1 Byte length V , Maximum value of 27.
8 | V bytes : Volume Name (e.g. Macintosh)
9 | 27 - V bytes of null padding
10 | Same in all files : ca a4 c7 7d 48 2b 00 00 00
11 |
12 | 3 Bytes of something, always different
13 |
14 | 1 Byte length of audiofile name
15 |
16 | audiofile name (e.g. test.wav)
17 |
18 | all Null to byte 0x73
19 |
20 | 7 Bytes, all different : e.g.
21 | 05 BB 93 C0 AC 3F AB
22 | 04 FF D9 C0 38 E3 A1
23 | 05 bb 94 bf c1 2c d1
24 | 05 1c 39 c0 ac 3f ab
25 |
26 | 8 null bytes
27 |
28 | 4 bytes of FF
29 |
30 | Same in all files : 00 00 09 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
31 |
32 | 1 Byte length of parent directory name
33 |
34 | parent directory name
35 |
36 | Same in all files : 00 00 10 00 08 00 00 ca a4 b9 6d 00 00 00 11 00 08 00 00
37 |
38 | 4 bytes of stuff.
39 | 4 bytes (00 00 00 01).
40 |
41 | 2 bytes length : X
42 | X bytes
43 |
44 | 00 02
45 |
46 | 2 bytes length Y , string of old style path
47 | Y Bytes e.g Macintosh:Users:.User:.Documents:.test.wav
48 |
49 | 6 bytes : 00 00 0E 00 0C 00
50 | 2 bytes length Z
51 | Z bytes of UTF-16 sample name, e.g. ...B.i.p.o.l.a.r. .G.l.i.t.c.h.1...w.a.v
52 |
53 | Same in all files : 00 0f 00 14 00 09 00 4d 00 61 00 63 00 69 00 6e 00 74 00 6f 00 73 00 68 00 12 00
54 |
55 | 1 byte length A
56 | A bytes : Absolute path to sample file : Users/User/Documents/audio/Konkrete/Bi-Polar Kit/Bi-Polar Kit Samples/Bipolar Glitch1.wav
57 |
58 | Same in all files : 00 00 13 00 01 2F 00 00 15 00 02 00 0B FF FF 00 00
59 |
60 | -------------------------------
61 |
62 | struct String
63 | {
64 | uint8 Length;
65 | char Str[Length];
66 | };
67 |
68 | struct VolumeString
69 | {
70 | uint8 Length;
71 | char Str[Length];
72 | uint8 nulls[27-Length];
73 | };
74 |
75 | struct SampleFilename
76 | {
77 | uint8 Length;
78 | char Str[Length];
79 | uint8 padding[64-Length];
80 | };
81 |
82 | struct StringX
83 | {
84 | uint16 Length;
85 | char Str[Length];
86 | };
87 |
88 | struct utf16String
89 | {
90 | uint8 Length;
91 | uint8 null;
92 | uint16 chars[Length];
93 | };
94 |
95 | struct Main
96 | {
97 | uint32 Null;
98 | uint16 Size;
99 | uint32 AlmostNull;
100 | VolumeString volume;
101 | uint8 DiffA[12];
102 | SampleFilename sampleFile;
103 | uint8 MoreStuff[38];
104 | String parentDirectory;
105 | uint8 Stuff3[27];
106 | StringX a;
107 | uint16 zeroTwo;
108 | StringX b;
109 | uint32 oooooeoo;
110 | uint16 ocoo;
111 | utf16String utf16Sample;
112 | uint8 Stuff4[26];
113 | String absolutePath;
114 | uint8 Stuff5[17];
115 | };
116 |
117 |
--------------------------------------------------------------------------------
/griffon-app/controllers/drumkitbuilder2/ExportProgressController.groovy:
--------------------------------------------------------------------------------
1 | package drumkitbuilder2
2 |
3 | import griffon.transform.Threading
4 |
5 | import java.awt.Window
6 |
7 | class ExportProgressController {
8 | def model
9 | def view
10 | def builder
11 | protected dialog
12 |
13 | def fileScannerService
14 | def exportService
15 |
16 | Boolean cancelExport = false
17 |
18 | @Threading(Threading.Policy.INSIDE_UITHREAD_SYNC)
19 | void show(Window window) {
20 | window = window ?: Window.windows.find{it.focused}
21 | if(!dialog || dialog.owner != window) {
22 | if(dialog) app.windowManager.hide(dialog)
23 | log.debug("Creating export progress dialog")
24 | dialog = builder.dialog(
25 | owner: window,
26 | title: "Exporting...",
27 | resizable: false,
28 | modal: true) {
29 | container(view.content)
30 | }
31 | dialog.preferredSize = [600, 130]
32 | dialog.pack()
33 | }
34 | int x = window.x + (window.width - dialog.width) / 2
35 | int y = window.y + (window.height - dialog.height) / 2
36 | dialog.setLocation(x, y)
37 | log.debug("Trigger export")
38 | cancelExport = false
39 | doExport()
40 |
41 | app.windowManager.show(dialog)
42 |
43 | }
44 |
45 | void mvcGroupInit(Map args) {
46 | log.debug("Export MVC Init")
47 | }
48 |
49 | @Threading(Threading.Policy.INSIDE_UITHREAD_ASYNC)
50 | def cancel = { evt = null ->
51 | log.debug("Cancel")
52 | cancelExport = true
53 | app.windowManager.hide(dialog)
54 | }
55 |
56 | @Threading(Threading.Policy.INSIDE_UITHREAD_ASYNC)
57 | def doExport = {
58 | log.debug("Do Export")
59 | jxwithWorker(start: true) {
60 | onInit {
61 | exportService.start(fileScannerService.scanner)
62 | model.buttonLabel = "Cancel"
63 | }
64 | work {
65 | Float progress = 0f
66 | def status
67 | while((progress < 100) || cancelExport) {
68 | status = exportService.work()
69 | publish(status)
70 | progress = status[1]
71 | }
72 | }
73 | onUpdate { status ->
74 | model.currentFormat = status[0][0]
75 | model.overallProgress = Math.floor(status[0][1])
76 | }
77 | onDone {
78 | edt {
79 | model.currentFormat = "Complete"
80 | model.overallProgress = 100
81 | model.buttonLabel = "Close"
82 | log.debug("Export Done")
83 | }
84 | }
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/main/com/relivethefuture/dkb/PathUtils.groovy:
--------------------------------------------------------------------------------
1 | package com.relivethefuture.dkb
2 |
3 | import org.slf4j.Logger
4 | import org.slf4j.LoggerFactory
5 |
6 | import java.util.regex.Pattern
7 |
8 | class PathUtils {
9 |
10 | private static final Logger logger = LoggerFactory.getLogger(PathUtils.class);
11 |
12 | public static File getOutputDirectoryForLayout(File outputDirectory, File sourceDirectory, OutputLayout layout, String relativePath = null) {
13 | logger.debug("Get Output For Layout " + layout.getLayoutStyle().name)
14 | if(layout.getLayoutStyle() == LayoutStyle.ABSOLUTE) {
15 | // Using outputDir as base add on the number of directories from layout.outputStructureDepth
16 | return addDirectoryStructure(outputDirectory, sourceDirectory, layout.getOutputStructureDepth());
17 | } else if(layout.getLayoutStyle() == LayoutStyle.RELATIVE) {
18 | if(relativePath == null) {
19 | throw new Exception("Relative Path is null but layout is Relative")
20 | }
21 | // Using outputDir as base
22 | // 1. add on relativePath
23 | File extra = new File(outputDirectory, relativePath);
24 | // 2. add on the number of directories from layout.outputStructureDepth
25 | return addDirectoryStructure(extra, sourceDirectory, layout.getOutputStructureDepth());
26 | } else if(layout.getLayoutStyle() == LayoutStyle.SOURCE) {
27 | // Use instrument source directory as base
28 | return sourceDirectory;
29 | }
30 | return outputDirectory;
31 | }
32 |
33 | public static File addDirectoryStructure(File dest, File sourceDirectory, Integer depth) {
34 | if(depth == 0) {
35 | return dest
36 | }
37 |
38 | logger.debug("Add dir structure : " + dest.getAbsolutePath() + " : " + sourceDirectory.getAbsolutePath() + " : " + depth)
39 |
40 | String sourcePath = sourceDirectory.getAbsolutePath()
41 | Boolean isUnix = sourcePath.charAt(0) == '/'
42 | String p = Pattern.quote(isUnix ? "/" : "\\")
43 | String[] sourceParts = sourcePath.split(p)
44 |
45 | List slist = sourceParts.toList()
46 | if(!isUnix) {
47 | slist.remove(0)
48 | }
49 |
50 | Integer lastElement = slist.size()
51 |
52 | String extraParts = "";
53 | if(lastElement >= depth) {
54 | int start = lastElement - depth;
55 | for(int i=0;i, Comparable {
17 |
18 | private final Logger log = LoggerFactory.getLogger(FolderOfSamples.class);
19 |
20 | // Lists of sample file lists, each sublist contains a maximum of 127 sampleLists.
21 | public ArrayList samples;
22 | // Directory where the actual samples are
23 | private File directory;
24 |
25 | // Where the original samples are
26 | private File sourceDirectory;
27 | private String name;
28 |
29 | private Comparator comparator;
30 |
31 | public FolderOfSamples(File directory, ArrayList audioFiles) {
32 | this.sourceDirectory = directory;
33 | this.samples = audioFiles;
34 | name = directory.getName();
35 | }
36 |
37 | public File getSourceDirectory() {
38 | return sourceDirectory;
39 | }
40 |
41 | public void setSourceDirectory(File sourceDirectory) {
42 | this.sourceDirectory = sourceDirectory;
43 | }
44 |
45 | public void setDirectory(File dir) {
46 | directory = dir;
47 | }
48 |
49 | public File getDirectory() {
50 | return directory;
51 | }
52 |
53 | public String getName() {
54 | return name;
55 | }
56 |
57 | public void setName(String n) {
58 | this.name = n;
59 | }
60 |
61 | public int compare(FolderOfSamples folderOfSamples, FolderOfSamples folderOfSamples2) {
62 | return folderOfSamples.samples.size() - folderOfSamples2.samples.size();
63 | }
64 |
65 | public int compareTo(FolderOfSamples folderOfSamples) {
66 | return samples.size() - folderOfSamples.samples.size();
67 | }
68 |
69 | public FolderOfSamples (FolderOfSamples source) {
70 | samples = new ArrayList();
71 | Sample newSample = null;
72 | for(Sample s : source.samples) {
73 | newSample = new BasicSample(s);
74 | samples.add(newSample);
75 | }
76 |
77 | log.debug("Copied samples to FOS");
78 | directory = source.getDirectory();
79 | log.debug("Set directory to " + directory);
80 | name = source.name;
81 | }
82 |
83 | public Comparator getSampleComparator() {
84 | return comparator;
85 | }
86 |
87 | public void setSampleComparator(Comparator sorter) {
88 | this.comparator = sorter;
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/notes/ideas.txt:
--------------------------------------------------------------------------------
1 | 1. Drag and drop
2 |
3 | Allow drag and drop of directories from explorer into main window and use that as root
4 |
5 | 2. Better Finder dialog (mac) and browser that shows sidebar etc. or at least accepts key commands (mac) for switching quickly.
6 |
7 | Investigate mac dialog options
8 |
9 | 3. Ability to bookmark favorite locations.
10 |
11 | Think about bookmark system
12 |
13 | 4. The instructions should make a clear note NOT to select inside a folder, but to select the folder itself because it won't work if you go into the folder and choose select. Otherwise, remove the option to hit 'select' when you haven't actually selected a folder.
14 |
15 | Look at this as part of 2 as its a mac bug
16 |
17 | 5. Drag to reorder isn't obvious. Get mouse to show a 'finger/hand' symbol on hover.
18 |
19 | Started but hand cursor disappears after something happens
20 |
21 | 6. Dynamically update the path display in the table to show how export would work
22 |
23 | Options to create file depth/folder depth aren't exactly obvious.
24 | Maybe this setting should be on the same page as the map builder and there should be a column that shows you the resulting path
25 | and how it looks and is named (like you showed in your documentation, but dynamically with the actual results).
26 |
27 | 7. Directory selection in left table
28 |
29 | Option to select or shift select Folders on left to be included in the export.
30 |
31 | Add 'export selected' and 'export all' options
32 |
33 | 8. Reaktor embed samples
34 |
35 | Option to embed samples into the map is really missing/wanted feature by users.
36 |
37 | 9. Create new icons for toolbar
38 |
39 | Rescan icon isn't clear. Other icons aren't great either.
40 |
41 | 10. Add note number column to right table
42 |
43 | Kit ordering should show numbers in the first Column (Note Number, Name, Size, Exclude for example).
44 |
45 | 11. Change 'Layout' to Output Locations: Base+Relative Path, Original Source, Individual or something more obvious..
46 |
47 | 12. Choose settings before export.
48 |
49 | I'd prefer to choose settings for output when I hit export. So, hit EXPORT and get a dialog for output settings. Choose one and hit 'don't remind me again' if you don't want to be bothered by it anymore.
50 |
51 | 13. Export window should close automatically on complete.
52 |
53 | 14. Close button on export config window.
54 |
55 | Clicking cancel/ok for changing paths is good, but not if you can accidentally close the window by hitting the window close button. The close window button is closer to the LAYOUT setting, so I just changed layout and hit close a couple times wondering why my settings didn't stick. Then I looked below and saw the dialog for 'cancel/ok'. When you close that window, it should prompt you to choose cancel or ok or something like that as it isn't clear now.
56 | Change OK to 'apply'. Maybe that helps too.
57 |
58 | Either remove, make it do OK or show an OK / Cancel dialog
--------------------------------------------------------------------------------
/src/main/com/relivethefuture/audio/AudioFilePlayer.java:
--------------------------------------------------------------------------------
1 | package com.relivethefuture.audio;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 |
6 | import javax.sound.sampled.*;
7 | import java.io.File;
8 | import java.io.IOException;
9 | import java.util.ArrayList;
10 | import java.util.List;
11 |
12 | /**
13 | * Created by martin on 11/01/12 at 11:46
14 | */
15 | public class AudioFilePlayer {
16 |
17 | private final Logger logger = LoggerFactory.getLogger(AudioFilePlayer.class);
18 |
19 | private Clip currentClip;
20 |
21 | private List clips;
22 |
23 | private int currentClipIndex = 0;
24 |
25 | public AudioFilePlayer() {
26 | clips = new ArrayList(8);
27 | try {
28 | for (int i = 0; i < 8; i++) {
29 | Clip clip = AudioSystem.getClip();
30 | clips.add(clip);
31 | }
32 | } catch (LineUnavailableException e) {
33 | logger.error("Cant create audio clip",e);
34 | }
35 |
36 | updateCurrentClip();
37 |
38 | }
39 |
40 | private void updateCurrentClip() {
41 | currentClip = clips.get(currentClipIndex++);
42 | if(currentClipIndex == 8) {
43 | currentClipIndex = 0;
44 | }
45 | }
46 |
47 | public void play(File file) {
48 | try {
49 | currentClip.close();
50 | AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file);
51 | AudioFormat sourceFormat = audioInputStream.getFormat();
52 | DataLine.Info info = new DataLine.Info(SourceDataLine.class,
53 | sourceFormat, AudioSystem.NOT_SPECIFIED);
54 | boolean bIsSupportedDirectly = AudioSystem.isLineSupported(info);
55 | if (!bIsSupportedDirectly) {
56 | AudioFormat targetFormat = new AudioFormat(
57 | AudioFormat.Encoding.PCM_SIGNED,
58 | sourceFormat.getSampleRate(),
59 | 16,
60 | sourceFormat.getChannels(),
61 | sourceFormat.getChannels() * 2,
62 | sourceFormat.getSampleRate(),
63 | true);
64 | audioInputStream = AudioSystem.getAudioInputStream(targetFormat, audioInputStream);
65 | }
66 |
67 | currentClip.open(audioInputStream);
68 | currentClip.setFramePosition(0);
69 | currentClip.start();
70 | updateCurrentClip();
71 | } catch (LineUnavailableException e) {
72 | logger.error("Line Unavailable",e);
73 | } catch (UnsupportedAudioFileException e) {
74 | logger.error("Unsupported Audio File", e);
75 | } catch (IOException e) {
76 | logger.error("IO Exception",e);
77 | } catch (IllegalStateException e) {
78 | logger.error("Illegal State",e);
79 | }
80 |
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/main/javaFlacEncoder/CRC16.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 Preston Lacey http://javaflacencoder.sourceforge.net/
3 | * All Rights Reserved.
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | package javaFlacEncoder;
21 |
22 | /**
23 | * Class to calculate a CRC16 checksum.
24 | * @author Preston Lacey
25 | */
26 | public class CRC16 {
27 | /** For Debugging: Higher level equals more debug statements */
28 | public static int DEBUG_LEV = 0;
29 |
30 | /** CRC Divisor: 0x8005(implicit 1 at MSB for 0x18005) */
31 | static final int divisorCRC16 = 0x8005;
32 |
33 | /** working checksum stored between calls to update(..) */
34 | protected int workingCRC;
35 |
36 | private static final short xorTable[] = generateTable();
37 | /**
38 | * Constructor. Creates a CRC16 object that is ready to be used. Next step
39 | * would be to call update(...) with appropriate data.
40 | */
41 | public CRC16() {
42 | reset();
43 | }
44 |
45 | /**
46 | * Resets stored data, preparing object for a new checksum.
47 | */
48 | public void reset() {
49 | workingCRC = 0;
50 | }
51 |
52 | public short checksum() {
53 | return (short)(workingCRC & 0xFFFF);
54 | }
55 |
56 | public int update(byte input) {
57 | workingCRC = (workingCRC << 8)^xorTable[((workingCRC >>> 8)^input) & 0xFF];
58 | return workingCRC;
59 | }
60 |
61 | public int update(byte[] input, int start, int stop) {
62 | for(int i = start; i < stop; i++) {
63 | byte b = input[i];
64 | workingCRC = (workingCRC << 8) ^ xorTable[((workingCRC >>> 8)^b) & 0xFF];
65 | }
66 | return workingCRC;
67 | }
68 |
69 | private static short[] generateTable() {
70 | short[] table = new short[256];
71 | for(int i = 0; i < table.length; i++) {
72 | int polynomial = divisorCRC16;
73 | int xorVal = i << 8;
74 | int topmask = 1 << 16;
75 | for(int x = 0; x < 8; x++ ) {
76 | xorVal = xorVal << 1;
77 | if( (xorVal & topmask) > 0) xorVal = (xorVal) ^ polynomial;
78 | }
79 | table[i] = (short)(xorVal & 0xFFFF);
80 | }
81 | return table;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/griffon-app/conf/webstart/application.jnlp:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 | @griffon.application.title@
10 | @griffon.application.vendor@
11 |
12 |
13 | @griffon.application.description.complete@
14 | @griffon.application.description.oneline@
15 | @griffon.application.description.minimal@
16 | @griffon.application.description.tooltip@
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | @jnlpJars@
45 |
46 | @jnlpExtensions@
47 | @jnlpProperties@
48 |
49 | @jnlpResources@
50 |
51 |
52 |
53 |
54 | @applet.tag.params@
55 |
56 |
57 |
--------------------------------------------------------------------------------
/src/main/javaFlacEncoder/BlockEncodeRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 Preston Lacey http://javaflacencoder.sourceforge.net/
3 | * All Rights Reserved.
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | package javaFlacEncoder;
21 | /**
22 | * BlockEncodeRequests are used to store a full block and necessary information
23 | * to encode such block. It is assumed member variables will be accessed
24 | * directly(for speed considerations). This Class simply gathers all values
25 | * into a single object, but handles no encoding logic itself.
26 | * @author Preston Lacey
27 | */
28 | public class BlockEncodeRequest {
29 | /* Sample data, may be interleaved if multiple channels exist.*/
30 | volatile int[] samples;
31 | /* Number of valid samples in this request */
32 | volatile int count;
33 | /* Index of samples[] where the first valid sample exists */
34 | volatile int start;
35 | /* Number of indices to skip between valid samples */
36 | volatile int skip;
37 | /* Frame-number this block is assigned */
38 | volatile long frameNumber;
39 | /* Location to store results to. For safety, use an empty element*/
40 | volatile EncodedElement result;
41 | /* Stores whether the result should be valid */
42 | volatile boolean valid;
43 | /* Number of elements actually encoded. */
44 | volatile int encodedSamples;
45 |
46 | /**
47 | * Set all values, preparing this object to be sent to an encoder. Member
48 | * variable "valid" is set to false by this call.
49 | *
50 | * @param samples Sample data, interleaved if multiple channels are used
51 | * @param count Number of valid samples
52 | * @param start Index of first valid sample
53 | * @param skip Number of samples to skip between samples(this should be
54 | * equal to number-of-channels minus 1.
55 | * @param frameNumber Framenumber assigned to this block.
56 | * @param result Location to store result of encode.
57 | */
58 | synchronized public void setAll(int[] samples, int count, int start, int skip,
59 | long frameNumber, EncodedElement result) {
60 | this.samples = samples;
61 | this.count = count;
62 | this.start = start;
63 | this.skip = skip;
64 | this.frameNumber = frameNumber;
65 | this.result = result;
66 | valid = false;
67 | this.encodedSamples = 0;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/griffon-app/conf/webstart/applet.jnlp:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 | @griffon.application.title@
10 | @griffon.application.vendor@
11 |
12 |
13 | @griffon.application.description.complete@
14 | @griffon.application.description.oneline@
15 | @griffon.application.description.minimal@
16 | @griffon.application.description.tooltip@
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | @jnlpJars@
45 |
46 | @jnlpExtensions@
47 | @jnlpProperties@
48 |
49 | @jnlpResources@
50 |
56 |
57 |
58 |
59 | @applet.tag.params@
60 |
61 |
62 |
--------------------------------------------------------------------------------
/resources/packaging/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleName
6 | Sample Map Builder
7 | CFBundleIdentifier
8 | com.relivethefuture.SampleMapBuilder
9 | CFBundleVersion
10 | 100.0
11 | CFBundleAllowMixedLocalizations
12 | true
13 | CFBundleExecutable
14 | JavaApplicationStub
15 | CFBundleDevelopmentRegion
16 | English
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 0.4
21 | CFBundleSignature
22 | ????
23 | CFBundleGetInfoString
24 | Sample Map Builder
25 | CFBundleInfoDictionaryVersion
26 | 6.0
27 | CFBundleIconFile
28 | icon-256x256.icns
29 | Java
30 |
31 | WorkingDirectory
32 | $APP_PACKAGE/Contents/Resources/Java
33 | MainClass
34 | griffon.swing.SwingApplication
35 | JVMVersion
36 | 1.6+
37 | ClassPath
38 |
39 | $JAVAROOT/SampleMapBuilder.jar
40 | $JAVAROOT/glazedlists_java15-1.9.0.jar
41 | $JAVAROOT/griffon-glazedlists-runtime-2.0.0.jar
42 | $JAVAROOT/griffon-lookandfeel-pgslaf-runtime-1.0.0.jar
43 | $JAVAROOT/griffon-lookandfeel-runtime-1.0.0.jar
44 | $JAVAROOT/griffon-miglayout-runtime-1.0.0.jar
45 | $JAVAROOT/griffon-rt-1.3.0.jar
46 | $JAVAROOT/griffon-silkicons-runtime-1.0.0.jar
47 | $JAVAROOT/griffon-swing-runtime-1.3.0.jar
48 | $JAVAROOT/griffon-tasks-runtime-0.1.jar
49 | $JAVAROOT/groovy-all-2.1.3.jar
50 | $JAVAROOT/jcl-over-slf4j-1.7.3.jar
51 | $JAVAROOT/jul-to-slf4j-1.7.3.jar
52 | $JAVAROOT/log4j-1.2.17.jar
53 | $JAVAROOT/miglayout-core-4.2.jar
54 | $JAVAROOT/miglayout-swing-4.2.jar
55 | $JAVAROOT/PgsLookAndFeel-1.1.1.jar
56 | $JAVAROOT/PgsLookAndFeel-jide-1.1.1.jar
57 | $JAVAROOT/silk-1.3.jar
58 | $JAVAROOT/slf4j-api-1.7.3.jar
59 | $JAVAROOT/slf4j-log4j12-1.7.3.jar
60 | $JAVAROOT/swing-worker-1.1.jar
61 | $JAVAROOT/swingx-action-1.6.4.jar
62 | $JAVAROOT/swingx-autocomplete-1.6.4.jar
63 | $JAVAROOT/swingx-beaninfo-1.6.4.jar
64 | $JAVAROOT/swingx-common-1.6.4.jar
65 | $JAVAROOT/swingx-core-1.6.4.jar
66 | $JAVAROOT/swingx-graphics-1.6.4.jar
67 | $JAVAROOT/swingx-painters-1.6.4.jar
68 | $JAVAROOT/swingx-plaf-1.6.4.jar
69 | $JAVAROOT/swingxbuilder-0.3.jar
70 | $JAVAROOT/timingframework-1.0.jar
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/src/main/com/relivethefuture/generic/BasicInstrument.java:
--------------------------------------------------------------------------------
1 | package com.relivethefuture.generic;
2 |
3 | import com.relivethefuture.kitbuilder.model.FolderOfSamples;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | import java.io.File;
8 | import java.util.ArrayList;
9 | import java.util.List;
10 |
11 | /**
12 | * Created by martin on 08/01/12 at 15:02
13 | */
14 | public class BasicInstrument implements Instrument {
15 |
16 | private static Logger logger = LoggerFactory.getLogger(BasicInstrument.class);
17 |
18 | protected List zones;
19 | private String name;
20 | private Integer fixedRoot;
21 | private Boolean looping;
22 |
23 | private ZoneFactory zoneFactory;
24 | private SampleFactory sampleFactory;
25 | private FolderOfSamples sourceFolderOfSamples;
26 |
27 | public BasicInstrument(String name) {
28 | this.name = name;
29 | zones = new ArrayList();
30 | looping = false;
31 | }
32 |
33 | void addZone(Zone zone) {
34 | zones.add(zone);
35 | }
36 |
37 | public void setZones(List zones) {
38 | this.zones = zones;
39 | }
40 |
41 | public List getZones() {
42 | return zones;
43 | }
44 |
45 | public void setName(String name) {
46 | this.name = name;
47 | }
48 |
49 | public String getName() {
50 | return name;
51 | }
52 |
53 | public void setSamples(List samples) {
54 | int lowkey = 0;
55 |
56 | for (Sample sample : samples) {
57 | Zone zone = zoneFactory.createZone();
58 | zone.setSample(sample);
59 | zone.setKeyRange(lowkey, lowkey);
60 |
61 | if (fixedRoot != null) {
62 | sample.setRoot(fixedRoot);
63 | } else {
64 | sample.setRoot(lowkey);
65 | }
66 |
67 | lowkey++;
68 |
69 | addZone(zone);
70 | }
71 | }
72 |
73 | public void setFixedRoot(Integer root) {
74 | fixedRoot = root;
75 | }
76 |
77 | public void loopAll(Boolean loop) {
78 | looping = loop;
79 | }
80 |
81 |
82 | public ZoneFactory getZoneFactory() {
83 | return zoneFactory;
84 | }
85 |
86 | public void setZoneFactory(ZoneFactory zoneFactory) {
87 | this.zoneFactory = zoneFactory;
88 | }
89 |
90 | @Override
91 | public File getSamplesDirectory() {
92 | return sourceFolderOfSamples.getDirectory();
93 | }
94 |
95 | public File getSourceDirectory() {
96 | return sourceFolderOfSamples.getSourceDirectory();
97 | }
98 |
99 | @Override
100 | public void setSource(FolderOfSamples fos) {
101 | sourceFolderOfSamples = fos;
102 | }
103 |
104 | @Override
105 | public FolderOfSamples getSource() {
106 | return sourceFolderOfSamples;
107 | }
108 |
109 | public SampleFactory getSampleFactory() {
110 | return sampleFactory;
111 | }
112 |
113 | public void setSampleFactory(SampleFactory sampleFactory) {
114 | this.sampleFactory = sampleFactory;
115 | }
116 |
117 | public Boolean getLooping() {
118 | return looping;
119 | }
120 |
121 | public void setLooping(Boolean looping) {
122 | this.looping = looping;
123 | }
124 |
125 | }
126 |
--------------------------------------------------------------------------------
/src/main/com/relivethefuture/formats/sfz/SFZWriter.java:
--------------------------------------------------------------------------------
1 | package com.relivethefuture.formats.sfz;
2 |
3 | import com.relivethefuture.ResourceUtils;
4 | import com.relivethefuture.generic.Instrument;
5 | import com.relivethefuture.generic.MidiRange;
6 | import com.relivethefuture.generic.Zone;
7 | import com.relivethefuture.kitbuilder.writers.BasicInstrumentWriter;
8 | import com.relivethefuture.kitbuilder.output.OutputConfig;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | import java.io.File;
13 | import java.io.FileWriter;
14 | import java.io.IOException;
15 | import java.io.PrintWriter;
16 |
17 | public class SFZWriter extends BasicInstrumentWriter {
18 |
19 | private final Logger logger = LoggerFactory.getLogger(SFZWriter.class);
20 |
21 | private OutputConfig outputConfig;
22 |
23 | private File instrumentFile;
24 |
25 | public SFZWriter(OutputConfig sfzConfig) {
26 | super();
27 | outputConfig = sfzConfig;
28 | }
29 |
30 | /**
31 | *
32 | * Alchemy Format :
33 | *
34 | *
35 |
36 | lokey=36
37 | hikey=36
38 | pitch_keycenter=36
39 | ampeg_decay=0.5
40 | ampeg_release=0.3
41 |
42 | sample=Ambient-Kick1.wav
43 | lovel=1
44 | hivel=127
45 |
46 | *
47 | * @param instrument
48 | * @param outputDirectory
49 | */
50 | public void write(Instrument instrument, File outputDirectory) {
51 |
52 | FileWriter outFile = null;
53 | PrintWriter printWriter = null;
54 | instrumentFile = new File(outputDirectory,instrument.getName());
55 |
56 | try {
57 | outFile = new FileWriter(instrumentFile);
58 | printWriter = new PrintWriter(outFile);
59 | for (Zone zone : instrument.getZones()) {
60 | writeZone(printWriter, zone);
61 | }
62 |
63 | } catch (IOException e1) {
64 | logger.error("IO Exception",e1);
65 | } finally {
66 | if (printWriter != null) {
67 | printWriter.close();
68 | }
69 | }
70 |
71 | }
72 |
73 | private void writeZone(PrintWriter printWriter, Zone zone) {
74 | printWriter.println("");
75 | MidiRange noteRange = zone.getNoteRange();
76 | printWriter.println("lokey=" + noteRange.getLow().toString());
77 | printWriter.println("hikey=" + noteRange.getHigh().toString());
78 | printWriter.println("pitch_keycenter=" + noteRange.getLow().toString());
79 | printWriter.println("ampeg_decay=0.5");
80 | printWriter.println("ampeg_release=0.3");
81 | printWriter.println("");
82 |
83 | String relative = ResourceUtils.getRelativePath(instrumentFile, zone.getSample().getFile());
84 |
85 | // The SFZ spec says that sample paths *must* be relative, although some software handles absolute paths
86 | printWriter.println(" sample=" + relative);
87 | printWriter.println("lovel=" + zone.getVelocityRange().getLow().toString());
88 | printWriter.println("hivel=" + zone.getVelocityRange().getHigh().toString());
89 | if(zone.getSample().getLooping()) {
90 | printWriter.println("loop_mode=loop_sustain");
91 | } else {
92 | printWriter.println("loop_mode=one_shot");
93 | }
94 |
95 | printWriter.println("");
96 | printWriter.println("");
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/main/javaFlacEncoder/FrameThread.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 Preston Lacey http://javaflacencoder.sourceforge.net/
3 | * All Rights Reserved.
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | package javaFlacEncoder;
21 | import java.util.concurrent.locks.ReentrantLock;
22 |
23 | /**
24 | * The FrameThread class provides threading support for a Frame object, allowing
25 | * multi-threaded encodings of FLAC frames. It's job is to repeatedly get a
26 | * BlockEncodeRequest from a BlockThreadManager, and encode it.
27 | *
28 | * @author Preston Lacey
29 | */
30 | public class FrameThread implements Runnable{
31 | Frame frame = null;
32 | ReentrantLock runLock = null;
33 | BlockThreadManager manager = null;
34 | /**
35 | * Constructor. Private to prevent it's use, as a Frame must be provided for
36 | * this FrameThread to be of any use.
37 | */
38 | private FrameThread() {}
39 |
40 | /**
41 | * Constructor. Sets the Frame object that this FrameThread will use for
42 | * encodings.
43 | *
44 | * @param f Frame object to use for encoding.
45 | * @param manager BlockThreadManager to use as the BlockEncodeRequest source
46 | * and destination.
47 | */
48 | public FrameThread(Frame f, BlockThreadManager manager) {
49 | super();
50 | if(f == null)
51 | System.err.println("Frame is null. Error.");
52 | frame = f;
53 | runLock = new ReentrantLock();
54 | this.manager = manager;
55 | }
56 |
57 | /**
58 | * Run method. This FrameThread will get a BlockEncodeRequest from the
59 | * BlockThreadManager, encode the block, return it to the manager, then
60 | * repeat. If no BlockEncodeRequest is available, or if it recieves a
61 | * request with the "frameNumber" field set to a negative value, it will
62 | * break the loop and end, notifying the manager it has ended.
63 | *
64 | */
65 | public void run() {
66 | boolean process = true;
67 | synchronized(this) {
68 | BlockEncodeRequest ber = manager.getWaitingRequest();
69 | if(ber != null && ber.frameNumber < 0)
70 | ber = null;
71 | while(ber != null && process) {
72 | if(ber.frameNumber < 0) {
73 | process = false;
74 | }
75 | else {//get available BlockEncodeRequest from manager
76 | ber.encodedSamples = frame.encodeSamples(ber.samples, ber.count,
77 | ber.start, ber.skip, ber.result, ber.frameNumber);
78 | ber.valid = true;
79 | manager.returnFinishedRequest(ber);
80 | ber = manager.getWaitingRequest();
81 | }
82 | }
83 | manager.notifyFrameThreadExit(this);
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/resources/formats/ShortCircuit/OneSample.scm:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/src/main/javaFlacEncoder/Subframe_Constant.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 Preston Lacey http://javaflacencoder.sourceforge.net/
3 | * All Rights Reserved.
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | package javaFlacEncoder;
21 |
22 | /**
23 | * Implements the Subframe abstract class, providing encoding support for the
24 | * FLAC Constant Subframe.
25 | *
26 | * @author Preston Lacey
27 | */
28 | public class Subframe_Constant extends Subframe {
29 | /** For debugging: Higher values equals greater output, generally by
30 | * increments of 10. */
31 | public static int DEBUG_LEV = 0;
32 | /** Subframe type supported by this implementation. */
33 | public static final EncodingConfiguration.SubframeType type =
34 | EncodingConfiguration.SubframeType.VERBATIM;
35 | int sampleSize = 0;
36 |
37 | /**
38 | * Constructor. Sets StreamConfiguration to use. If the StreamConfiguration
39 | * must later be changed, a new Subframe object must be created as well.
40 | *
41 | * @param sc StreamConfiguration to use for encoding.
42 | */
43 | public Subframe_Constant(StreamConfiguration sc) {
44 | super(sc);
45 | sampleSize = sc.getBitsPerSample();
46 | }
47 |
48 | /**
49 | * This method is used to set the encoding configuration.
50 | * @param ec encoding configuration to use.
51 | * @return true if configuration was changed, false otherwise
52 | */
53 | @Override
54 | public boolean registerConfiguration(EncodingConfiguration ec) {
55 | super.registerConfiguration(ec);
56 |
57 | return true;
58 | }
59 |
60 |
61 | public int encodeSamples(int[] samples, int count, int start, int skip,
62 | EncodedElement data, int offset, int bitsPerSample ) {
63 | if(DEBUG_LEV > 0) {
64 | System.err.println("Subframe_Verbatim::encodeSamples(...)");
65 | }
66 | int encodedSamples = count;
67 | int bits = bitsPerSample+offset+8;
68 | int bytesNeeded = bits/8;
69 | if(bits%8 != 0)
70 | bytesNeeded++;
71 | data.clear(bytesNeeded, offset);
72 | data.addInt(0,1);
73 | data.addInt(0,6);
74 | data.addInt(0,1);
75 |
76 | int value = samples[start];
77 | int increment = skip+1;
78 | int end = start+increment*count;
79 | int lastValid = end-increment;//assume all were the same
80 | for(int i = start; i < end; i+= increment) {
81 | if(samples[i] != value) {
82 | lastValid = i-increment;//if one differed, find where
83 | break;
84 | }
85 | }
86 | encodedSamples = (lastValid-start)/increment+1;
87 | data.addInt(value,bitsPerSample);
88 | lastEncodedSize = bits - offset;
89 | System.out.flush();
90 | if(DEBUG_LEV > 0)
91 | System.err.println("Subframe_Verbatim::encodeSamples(...): End");
92 | if(DEBUG_LEV > 10) {
93 | System.err.println("--: bitsUsed : "+bits+" : Bytes : "+bytesNeeded);
94 | }
95 | return encodedSamples;
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/resources/formats/Live/Simpler/SimplerSampleRef.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | 44003A005C00730061006D0070006C00650073005C004D0044004B005C006400720075006D007300
19 | 5C004B00690063006B0073005C0053006F006C00690064002E007700610076000000
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 | 44003A005C00730061006D0070006C00650073005C004D0044004B005C006400720075006D007300
58 | 5C004B00690063006B0073005C000000
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 | 44003A005C00730061006D0070006C00650073005C004D0044004B005C006400720075006D007300
89 | 5C004B00690063006B0073005C0053006F006C00690064002E007700610076000000
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------