Запись WAV в Adobe AIR / Actionscript 3.0 - ** Проблемы ** - PullRequest
1 голос
/ 07 января 2012

Я пытаюсь выполнить запись с порта наушников непосредственно в порт микрофона (с помощью вспомогательного кабеля) в Adobe Flash Builder / AIR, но у меня возникла пара проблем:

1. Запись никогда не звучит "полностью" по сравнению с оригинальным файлом MP3, который я воспроизводю в iTunes. PCM должен быть в несжатом формате, поэтому качество должно быть без потерь.

2. Сохраненная запись (WAV) всегда вдвое меньше той, что я записал. (Пример: если я сделаю запись в течение минуты, я получу файл wav 0:30, а вторая половина записи отсутствует)

Это код, который я использую. Есть идеи, почему я могу столкнуться с этими проблемами?

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);
}      

PS: я использую стандартный класс WavWriter AS: http://ghostcat.googlecode.com/svn-history/r424/trunk/ghostcatfp10/src/ghostcat/media/WAVWriter.as

1 Ответ

0 голосов
/ 09 января 2012

Да, проблема с наушниками в микрофоне. Вы отправляете только часть данных через разъем для наушников. Он был продезинфицирован, реструктурирован, уменьшен или ограничен, чтобы опыт прослушивания работал без перерывов (критический фактор опыта). Для записи это даст вам кучу грязи. Чтобы записать идеальный звук, вы должны работать с самими аудиоданными, а не полагаться на вывод программ, которые (искренне) работают для достижения иных целей, чем идеальное цифровое воспроизведение.

Не уверен, почему звук только наполовину.

...