Flash 在AdobeAIR/Actionscript 3.0中录制WAV-**问题**

Flash 在AdobeAIR/Actionscript 3.0中录制WAV-**问题**,flash,actionscript-3,audio,air,wav,Flash,Actionscript 3,Audio,Air,Wav,我试图在Adobe Flash Builder/AIR中从耳机端口直接录制到麦克风端口(使用aux电缆),但我遇到了几个问题: 1.与我在iTunes中播放的原始MP3文件相比,这段录音听起来从未“满”。PCM应该是未压缩格式,因此质量应该是无损的 2.保存的录制(WAV)长度始终是我录制的长度的一半。 (例如:如果我录制一分钟,我将得到一个0:30的wav文件,而录制的后半部分不在那里) 这是我正在使用的代码。你知道我为什么会遇到这些问题吗 import com.adobe.audio.for

我试图在Adobe Flash Builder/AIR中从耳机端口直接录制到麦克风端口(使用aux电缆),但我遇到了几个问题:

1.与我在iTunes中播放的原始MP3文件相比,这段录音听起来从未“满”。PCM应该是未压缩格式,因此质量应该是无损的

2.保存的录制(WAV)长度始终是我录制的长度的一半。 (例如:如果我录制一分钟,我将得到一个0:30的wav文件,而录制的后半部分不在那里)

这是我正在使用的代码。你知道我为什么会遇到这些问题吗

import com.adobe.audio.format.WAVWriter;

import flash.display.NativeWindowSystemChrome;
import flash.events.Event;
import flash.events.SampleDataEvent;
import flash.events.TimerEvent;
import flash.filters.BitmapFilterQuality;
import flash.filters.DropShadowFilter;
import flash.media.Microphone;
import flash.media.Sound;
import flash.system.Capabilities;
import flash.utils.Timer;

import mx.controls.Alert;
import mx.core.UIComponent;
import mx.core.Window;
import mx.events.CloseEvent;

import ui.AudioVisualization;

private var shadowFilter:DropShadowFilter;
private var newWindow:Window;

// MICROPHONE STUFFZ
[Bindable] private var microphoneList:Array = Microphone.names; // Set up list of microphones
protected var microphone:Microphone;                            // Initialize Microphone
protected var isRecording:Boolean = false;                      // Variable to check if we're recording or not
protected var micRecording:ByteArray;                           // Variable to store recorded audio data

public var file:File = File.desktopDirectory;
public var stream:FileStream = new FileStream();

public var i:int = 0;
public var myTimer:Timer;


// [Start] Recording Function
protected function startMicRecording():void
{
    if(isRecording == true) stopMicRecording();
    else
    {
        consoleTA.text += "\nRecording started...";
        consoleTA.scrollToRange(int.MAX_VALUE, int.MAX_VALUE);

        isRecording = true;
        micRecording = new ByteArray();
        microphone = Microphone.getMicrophone(comboMicList.selectedIndex);
        microphone.gain = 50;
        microphone.rate = 44;      
        microphone.setUseEchoSuppression(false); 
        microphone.setLoopBack(false);  

        // Start timer to measure duration of audio clip (runs every 1 seconds)
        myTimer = new Timer(1000);
        myTimer.start();

        // Set amount of time required to register silence
        var userSetSilence:int;
        if(splitCB.selected == true){
            userSetSilence = splitNS.value; // if checkbox is checked, use the value from the numeric stepper
        }
        else{
            userSetSilence = 2;
        }
        userSetSilence *= 100;
        microphone.setSilenceLevel(0.5, userSetSilence); // 2 seconds of silence = Register silence with onActivity (works for itunes skip)
        microphone.addEventListener(SampleDataEvent.SAMPLE_DATA, gotMicData);
        microphone.addEventListener(ActivityEvent.ACTIVITY, this.onMicActivity);
    }
}

// [Stop] Recording Function
protected function stopMicRecording():void
{
    myTimer.stop(); // Stop timer to get final audio clip duration

    consoleTA.text += "\nRecording stopped. (" + myTimer.currentCount + "s)";
    consoleTA.scrollToRange(int.MAX_VALUE, int.MAX_VALUE); 

    isRecording = false;
    if(!microphone) return;
    microphone.removeEventListener(SampleDataEvent.SAMPLE_DATA, gotMicData);
}

private function gotMicData(micData:SampleDataEvent):void
{
    this.visualization.drawMicBar(microphone.activityLevel,0xFF0000);
    if(microphone.activityLevel <= 5) 
    {
        consoleTA.text += "\nNo audio detected"; //trace("no music playing");
        consoleTA.scrollToRange(int.MAX_VALUE, int.MAX_VALUE); 
    }
    // micData.data contains a ByteArray with our sample. 
    //Old: micRecording.writeBytes(micData.data);
    while(micData.data.bytesAvailable) { 
        var sample:Number = micData.data.readFloat(); 
        micRecording.writeFloat(sample); 
    }
}

protected function onMicActivity(event:ActivityEvent):void
{
    //trace("activating=" + event.activating + ", activityLevel=" + microphone.activityLevel);
    consoleTA.text += "\nactivating=" + event.activating + ", activityLevel=" + microphone.activityLevel;
    consoleTA.scrollToRange(int.MAX_VALUE, int.MAX_VALUE); 

    // Mic started recording...
    if(event.activating == true)
    {
        try{
            //fs.open(file, FileMode.WRITE);
            //fs.writ
        }catch(e:Error){
            trace(e.message);
        }
    }
    // Mic stopped recording...
    if(event.activating == false)
    {
        if(file)
        {
            i++;
            myTimer.stop();
            stopMicRecording();

            if(deleteCB.selected == true)
            {

                if(myTimer.currentCount < deleteNS.value)
                {
                    consoleTA.text += "\nAudio deleted. (Reason: Too short)";
                    consoleTA.scrollToRange(int.MAX_VALUE, int.MAX_VALUE); 
                }
                else
                {
                    writeWav(i);
                }
            }
            else
            {
                writeWav(i);
            }

            startMicRecording();
        }
    }

}

private function save():void
{
    consoleTA.text += "\nSaving..."; //trace("file saved!");
    consoleTA.scrollToRange(int.MAX_VALUE, int.MAX_VALUE); 

    file = new File( );
    file.browseForSave( "Save your wav" );
    file.addEventListener( Event.SELECT, writeWav );
}

public function writeWav(i:int):void
{
    var wavWriter:WAVWriter = new WAVWriter();

    // Set settings
    micRecording.position = 0;
    wavWriter.numOfChannels = 2;
    wavWriter.sampleBitRate = 16; //Audio sample bit rate: 8, 16, 24, 32
    wavWriter.samplingRate = 44100;   

    var file:File = File.desktopDirectory.resolvePath("SoundSlug Recordings/"+sessionTA.text+"_"+i+".wav");
    var stream:FileStream = new FileStream();
    //file = file.resolvePath("/SoundSlug Recordings/testFile.wav");
    stream.open( file, FileMode.WRITE );

    // convert ByteArray to WAV
    wavWriter.processSamples( stream, micRecording, 44100, 1 ); //change to 1?
    stream.close();

    consoleTA.text += "\nFile Saved: " + file.exists; //trace("saved: " + file.exists);
    consoleTA.scrollToRange(int.MAX_VALUE, int.MAX_VALUE);
}      
import com.adobe.audio.format.WAVWriter;
导入flash.display.nativeWindowsSystemChrome;
导入flash.events.Event;
导入flash.events.SampleDataEvent;
导入flash.events.TimerEvent;
导入flash.filters.BitmapFilterQuality;
导入flash.filters.DropShadowFilter;
导入flash.media.microscope;
导入flash.media.Sound;
导入flash.system.Capabilities;
导入flash.utils.Timer;
导入mx.controls.Alert;
导入mx.core.ui组件;
导入mx.core.Window;
导入mx.events.CloseEvent;
导入ui.AudioVisualization;
私有var阴影过滤器:DropShadowFilter;
私有窗口:窗口;
//麦克风玩偶
[Bindable]专用var麦克风列表:数组=麦克风.names;//设置麦克风列表
受保护的var话筒:话筒;//初始化麦克风
受保护的变量isRecording:Boolean=false;//变量来检查我们是否正在录制
受保护的var记录:ByteArray;//用于存储录制的音频数据的变量
public var file:file=file.desktopDirectory;
公共变量流:FileStream=newfilestream();
公共变量i:int=0;
公共var myTimer:Timer;
//[启动]记录功能
受保护的函数startMicRecording():void
{
如果(isRecording==true)stopMicRecording();
其他的
{
consoleTA.text+=“\n录制已开始…”;
控制台滚动范围(int.MAX\u值,int.MAX\u值);
isRecording=true;
micRecording=newbytearray();
麦克风=麦克风。获取麦克风(comboMicList.selectedIndex);
麦克风增益=50;
麦克风频率=44;
麦克风。设置使用回声抑制(错误);
麦克风。设置环回(错误);
//启动计时器以测量音频剪辑的持续时间(每1秒运行一次)
myTimer=新定时器(1000);
myTimer.start();
//设置注册静默所需的时间量
var userSetSilence:int;
if(splitCB.selected==true){
userSetSilence=splitNS.value;//如果选中复选框,则使用数值步进器中的值
}
否则{
userSetSilence=2;
}
userSetSilence*=100;
麦克风.setSilenceLevel(0.5,userSetSilence);//2秒静默=使用onActivity注册静默(适用于itunes skip)
麦克风.addEventListener(SampleDataEvent.SAMPLE_数据,gotMicData);
mirror.addEventListener(ActivityEvent.ACTIVITY,this.onMicActivity);
}
}
//[停止]记录功能
受保护的函数stopMicRecording():void
{
myTimer.stop();//停止计时器以获取最终音频剪辑的持续时间
consoleTA.text+=“\n记录已停止。(“+myTimer.currentCount+”s)”;
控制台滚动范围(int.MAX\u值,int.MAX\u值);
isRecording=false;
如果(!麦克风)返回;
麦克风.removeEventListener(SampleDataEvent.SAMPLE_数据,gotMicData);
}
私有函数gotMicData(micData:SampleDataEvent):void
{
这个.visualization.drawMicBar(麦克风.activityLevel,0xFF0000);

如果(micro.activityLevel是的,那么耳机到麦克风就是问题所在。您只通过耳机插孔发送了一小部分数据。数据经过消毒、重组、缩减或节流,以使听力体验不受干扰地工作(一个关键的体验因素)。要录制,会给你带来一堆烂泥。为了录制完美的音频,你必须处理音频数据本身,而不是依赖(真诚地)为完美数字复制以外的其他目标而工作的节目的输出

不过,我不知道为什么音频只有一半