Copy link to clipboard
Copied
I extended the File class as AudioFile. I only added one new property "category". I intend to filter files out of a directory structure and keep the AudioFile objects in a simple indexed array. I also want to add category info to the AudioFile object's "category" property. The error is thrown after I call getDirectoryListing, assign the returned File objects to "content:Array", and then I iterate through "content" assinging each File object to an AudioFile object. I thought that sense AudioFile is an extension of File that this would not be a problem. The heart of the issue is how getDirectoryListing returns File objects but I need AudioFile objects. My next instinct is to override the getDirectoryListing method but I can not find the class declaration for File.
Is there a way to cast the File objects as AudioFile objects? Should I be using a different strategy for assigning category info to the File objects? Maybe I should not be extending File class at all. I am kind of stuck. Any help would be greatly appreciated.
Here is my code. Please note that this is my first flex/air/actionscript I ever wrote. I am using Flash Builder 4.5 and my target is Air Desktop. The extended class AudioFile is in AudioFile.as.
package
{
import flash.filesystem.File;
public class AudioFile extends File
{
public function AudioFile()
{
}
public var category:String;
}
}
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:samples="samples.*"
applicationComplete="init()" width="386" height="581"
initialize="initData()">
<s:layout>
<s:VerticalLayout paddingTop="6" paddingLeft="6" paddingRight="6" paddingBottom="6"/>
</s:layout>
<fx:Script>
<![CDATA[
import AudioFile;
import flash.events.Event;
import flash.filesystem.File;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
private var audioObj:AudioFile = new AudioFile();
protected function init():void
{
// Center main AIR app window on the screen
nativeWindow.x = (Capabilities.screenResolutionX - nativeWindow.width) / 2;
nativeWindow.y = (Capabilities.screenResolutionY - nativeWindow.height) / 2;
// Get notified when minimize/maximize occurs
addEventListener(NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, onDisplayStateChange);
}
// Handles when the app is minimized/maximized
protected function onDisplayStateChange(e:NativeWindowDisplayStateEvent):void
{
trace("Display State Changed from " + e.beforeDisplayState + " to " + e.afterDisplayState);
}
private var masterList:ArrayCollection = new ArrayCollection();
private var dgArray:Array = new Array();
[Bindable]
private var initDG:ArrayCollection;
public function initData():void {
var initDG:ArrayCollection = new ArrayCollection(dgArray);
}
private function analyze():void {
// ActionScript file
var sourceDir:AudioFile = getSourceDir();
var fileList:Array = new Array();
var dirList:Array = new Array();
function transverseDirStructure(sourceDir:AudioFile):Array {
var flag:Boolean = false;
var dirList:Array = new Array();
var fileList:Array = new Array();
do {
var contents:Array = sourceDir.getDirectoryListing();
for(var i:int=0;i < contents.length; i++) {
// test for isDirectory
var file:AudioFile = contents;
if (file.isDirectory == true) {
dirList.push(file);
}
else {
fileList.push(file);
}
}
if (dirList.length == 0)
flag = false;
else {
// recursion
fileList = fileList.concat(transverseDirStructure(dirList,fileList));
}
} while (flag == false)
return fileList;
}
function filterExtensions(fileList:Array):Array {
var cleanExtensionsList:Array = new Array();
for each (var i:AudioFile in fileList) {
if (i.extension == ".wav" || ".aiff") {
cleanExtensionsList.push(i);
}
}
return cleanExtensionsList;
}
function filterSize(fileList:Array):Array {
var cleanSizeList:Array = new Array();
var maxFileSize:int = 350000;
for each (var i:AudioFile in fileList) {
if (i.size < maxFileSize) {
cleanSizeList.push(i);
}
}
return cleanSizeList;
}
function categorizeAudioFiles(fileList:Array):Array {
var masterList:Array = new Array();
var flag:Boolean = true;
var categories:Array = new Array();
categories.push("kick","snare","hat","crash","clap");
for each (var i:AudioFile in fileList) {
for each (var x:String in categories) {
if (i.name.search(x) > 0) {
// Add name of category to the extended property.
i.category = x;
masterList.push(i);
}
}
}
return masterList;
}
fileList = transverseDirStructure(fileList);
fileList = filterSize(fileList);
fileList = filterExtensions(fileList);
fileList = categorizeAudioFiles(fileList);
}
private function generateRandom():void {
}
private function setDestination():void {
var file:AudioFile = new AudioFile();
file.addEventListener(Event.SELECT, dirSelected);
file.browseForDirectory("Select a directory");
function dirSelected(e:Event):void {
txtDestination.text = file.nativePath;
}
}
private function getDestination():AudioFile {
var destinationDir:AudioFile = new AudioFile();
destinationDir.nativePath = txtDestination.text;
return destinationDir;
}
private function getSourceDir():AudioFile {
var sourceDir:AudioFile = new AudioFile();
sourceDir.nativePath = txtBrowse1.text;
return sourceDir;
}
private function setSourceDir():void {
var file:AudioFile = new AudioFile();
file.addEventListener(Event.SELECT, dirSelected);
file.browseForDirectory("Select a directory");
function dirSelected(e:Event):void {
txtBrowse1.text = file.nativePath;
}
}
// Control logic
]]>
</fx:Script>
<mx:Form width="373" height="113" id="formChooseDirectory1">
<mx:FormHeading label="1. Choose A Source Directory..." width="315" fontSize="13" fontFamily="Verdana" color="#CF71FF"/>
<s:Button label="Browse..." fontFamily="Verdana" fontSize="13" color="#CF71FF" id="btnBrowse1" enabled="true" click="setSourceDir()"/>
<s:TextInput width="333" id="txtBrowse1" enabled="false" text="C:\Users\RokaMic\Bangin Beats"/>
</mx:Form>
<mx:Form width="373" height="231" id="formAnalyze">
<mx:FormHeading label="2. Analyze Samples..." fontFamily="Verdana" fontSize="13" color="#00D8FF" width="245"/>
<s:Button label="Analyze" fontFamily="Verdana" color="#00D8FF" id="btnAnalyze" enabled="true" click="analyze()"/>
<mx:DataGrid editable="false" enabled="true" fontFamily="Verdana" color="#00D8FF" width="337" dataProvider="{initDG}">
<mx:columns>
<mx:DataGridColumn headerText="File name" dataField="filename" color="#00D8FF" fontFamily="Verdana"/>
<mx:DataGridColumn headerText="Category" dataField="category" color="#00D8FF" fontFamily="Verdana"/>
</mx:columns>
</mx:DataGrid>
</mx:Form>
<mx:Form width="374" height="173" id="formGenerate">
<s:Button label="Generate Drum Kits" width="342" height="52" fontSize="18" fontFamily="Verdana" color="#00FF06" id="btnGenerate1" enabled="true" click="generateRandom()"/>
<mx:FormItem label="How Many?" fontFamily="Verdana" fontSize="13" color="#00FF00" width="340">
<s:HSlider width="206" stepSize="1" value="1" minimum="1" maximum="25" id="sliderHowMany" liveDragging="true"/>
</mx:FormItem>
<s:Button label="Destination..." color="#00FF00" id="btnDestination" enabled="true" click="setDestination()"/>
<s:TextInput width="332" id="txtDestination" enabled="false"/>
</mx:Form>
</s:WindowedApplication>
traversing a directory structure sounds like you're going to iterate through everything in the directory. if you encounter another (sub)directory, i imagined you were going to iterate through everything in that (sub)directory etc. so, you could end up not being able to use a return statement correctly. i gather that's not the problem so you don't need to deal with that issue.
Copy link to clipboard
Copied
which line of code triggers the error. and what's the complete error?
Copy link to clipboard
Copied
The error is triggered here:
fileList = transverseDirStructure(fileList);
I think the lines in question are: (inside the transverseDirStructure function)
do {
var contents:Array = sourceDir.getDirectoryListing();
for(var i:int=0;i < contents.length; i++) {
// test for isDirectory
var file:AudioFile = contents; <----- I think this is the problem. contents returns a File object
if (file.isDirectory == true) {
dirList.push(file);
}
else {
fileList.push(file);
}
}
The complete error message is: (from Flash Builder 4.5 debug mode)
TypeError: Error #1034: Type Coercion failed: cannot convert []@921f101 to AudioFile.
at DrumKitGenerator/analyze()
at DrumKitGenerator/__btnAnalyze_click()
Line 129 is the call to the transverseDirStructure function.
Copy link to clipboard
Copied
is transverseDirStructure() returning an AudioFile instance?
if yes, this is probably something asynchronous occuring in transverseDirStructure().
(and, is transverseDirStructure supposed to be traverseDirStructure?)
Copy link to clipboard
Copied
yes transverseDirStructure is supposed to be traverseDirStructure. I thought someone might call me on that. thank you
Copy link to clipboard
Copied
a name is just a name. but traverse sounds like an asynchronous operation.
Copy link to clipboard
Copied
transverseDirStructure() is returning a indexed array of AudioFile objects.
I think the problem is when I call
var contents:Array = sourceDir.getDirectoryListing();
getDirectoryListing() returns File objects. At this point I need to iterate through the contents:Array. Using the a for loop I pull each File object out of the array and try to assign them to a AudioFile object. I suspect this is what triggers the Type coercion error.
I could simply not use the AudioFile object until later but I will run into the same error eventually. Or I may need to use a different strategy than extending the File class with addition of my own custom property.
Copy link to clipboard
Copied
you know what I just thought of this. I probably could just use the nativePath property of the File object and create a new AudioFile object.
What I was orginally trying to do was this:
class File { ... }
class AudioFile extends File {
var category:String;
}
var fileObj:File = new File(url);
var audioObj:AudioFile = new AudioFile();
audioObj = fileObj; // File Coercion error!
Instead maybe I could do this:
var fileObj:File = new File(url);
var audioObj:AudioFile = new AudioFile(fileObj.nativepath);
Copy link to clipboard
Copied
the flash compiler will tell you exact line of code causing the problem. you've mentioned 2 different lines of code and that makes it sound like you don't know which line of code is causing the problem.
Copy link to clipboard
Copied
The error occurs on line 129, which is as follows:
fileList = transverseDirStructure(fileList);
The compiler is only telling me that the error is occuring on line 129.
here is the error message:
TypeError: Error #1034: Type Coercion failed: cannot convert []@921f101 to AudioFile.
at DrumKitGenerator/analyze()
at DrumKitGenerator/__btnAnalyze_click()
Copy link to clipboard
Copied
i copied this from your code:
function categorizeAudioFiles(fileList:Array):Array {
var masterList:Array = new Array();
var flag:Boolean = true;
var categories:Array = new Array();
categories.push("kick","snare","hat","crash","clap");
for each (var i:AudioFile in fileList) {
for each (var x:String in categories) {
if (i.name.search(x) > 0) {
// Add name of category to the extended property.
i.category = x;
masterList.push(i);
}
}
}
return masterList;
}
fileList = transverseDirStructure(fileList);
fileList = filterSize(fileList);
fileList = filterExtensions(fileList);
fileList = categorizeAudioFiles(fileList);
}
does that contain line 129? if so, where are those last 5 lines?
they don't appear to be part of the categorizeAudioFiles() function so there should be a compiler error about that last }. or, you've nested a named function somewhere.
Copy link to clipboard
Copied
I see whats wrong now.
I was calling transverseDirStructure() with an array as an arguement like so:
filename = transverseDirStructure(filename);
But I had defined the function with a File object as the arguement, like:
function transverseDirStructure(sourceDir:File):Array { ... }
So i was tring to pass the function an array but what it needs is a File object.
Serious NOOB mistake.
Sorry to have wasted your time. And I thank you very kindly.
On a sidenote:
previously you had mentioned that I named the function as if it my asynchronous. Could you explain about that naming convention a little bit?
Copy link to clipboard
Copied
traversing a directory structure sounds like you're going to iterate through everything in the directory. if you encounter another (sub)directory, i imagined you were going to iterate through everything in that (sub)directory etc. so, you could end up not being able to use a return statement correctly. i gather that's not the problem so you don't need to deal with that issue.