نمایش نتایج 1 تا 8 از 8

نام تاپیک: ادغام دو یا چند فایل wav

  1. #1
    کاربر دائمی آواتار babak_delphi
    تاریخ عضویت
    اردیبهشت 1384
    محل زندگی
    آستارا
    پست
    634

    Post ادغام دو یا چند فایل wav

    در این مقاله قصد دارم به طور خلاصه نحوه ادغام دو یا چند فایل wav را (مثلا برای پخش روی خط در نرم افزار های تلفن گویا) آموزش دهم
    این مقاله را در پاسخ به سوال یکی از دوستان که در تاپیکی با آدرس زیر پرسیده بودند نوشتم
    درصورتی که سوالی داشتید مباحث مربوطه را در آن تاپیک مطرح فرمایید
    ضمنا خوشحال می شوم اگر دوستان برای بهتر شدن این روش راهنمایی های لازم را مبذول بدارند

    https://barnamenevis.org/showthread.php?t=103294


    ================================================== ===

    ابتدا یک متغیر سراسری از نوع Integer به نام fp تعریف کنید
    سپس یک فایل با نام دلخواه و در مسیر دلخواه ایجاد کنید
    من در این مثال نام فایل را base1_1.wav و مسیر آن را :C در نظر گرفته ام
    حال با دستور زیر یک فایل ایجاد می کنیم


    fp:=FileCreate('c:\base1_1.wav');


    یک متغیر سراسری دیگر به نام len از نوع Integer تعریف می کنیم
    در ابتدای فایلی که ایجاد کرده ایم Header فایل را که 58 بایت تول دارد قرار می دهیم



    FileWrite(fp,file_header,58);



    file_header را در قسمت Const بصورت زیر تعریف می کنیم


    file_header : array[0..100]of char =
    chr($52)+chr($49)+chr($46)+chr($46)+chr($26)+chr(H 0)+chr(H0)+chr(H0)+chr($57)+chr($41)+chr($56)+chr( $45)+chr($66)+chr($6D)+chr($74)+chr($20)+chr($12)+ chr(H0)+chr(H0)+chr(H0)+chr(H1)+chr(H0)+chr(H1)+ch r(H0)+chr($40)+chr($1F)+chr(H0)+chr(H0)+chr($80)+c hr($3E)+chr(H0)+chr(H0)+chr($02)+chr(H0)+chr($10)+ chr(H0)+chr(H0)+chr(H0)+chr($66)+chr($61)+chr($63) +chr($74)+chr($04)+chr(H0)+chr(H0)+chr(H0)+chr($63 )+chr($E8)+chr(H0)+chr(H0)+chr($64)+chr($61)+chr($ 74)+chr($61)+chr($C6)+chr($D0)+chr(H1)+chr(H0);


    این Header در حقیقت فضایی است که برای Header اصلی رزرو کرده ایم
    حال تابعی بصورت زیر با نام Merg_file_Wav ایجاد می کنیم


    merg_file_wav(fp: Integer; filename: String);


    در این تابع fp اشاره گر به فایلی است که ایجاد کرده ایم
    filename نام فایلی است که باید به این فایل اضافه شود
    کد این تابع نیز بصورت زیر است



    procedure merg_file_wav(fp: Integer; filename: String);
    var
    bufx,buf:array[0..100] of char;
    i,fi:Integer;
    newlen,lenx:Integer;
    Begin
    fi:=FileOpen(filename,0);
    FileSeek(fi,16,0);
    FileRead(fi,buf,4);
    lenx:=ord(buf[3]);
    lenx:=lenx*256+ord(buf[2]);
    lenx:=lenx*256+ord(buf[1]);
    lenx:=lenx*256+ord(buf[0]);
    FileSeek(fi,lenx,1);
    FileRead(fi,bufx,4);
    FileRead(fi,buf,4);
    //************************************************** **************
    buf[0] := chr(ord(buf[0]));
    buf[1] := chr(ord(buf[1]));
    buf[2] := chr(ord(buf[2]));
    buf[3] := chr(ord(buf[3]));
    //************************************************** **************
    lenx:=ord(buf[3]);
    lenx:=lenx*256+ord(buf[2]);
    lenx:=lenx*256+ord(buf[1]);
    lenx:=lenx*256+ord(buf[0]);
    if strpas(bufx)='fact' then
    Begin
    FileSeek(fi,lenx,1);
    FileRead(fi,bufx,4);
    FileRead(fi,buf,4);
    lenx:=ord(buf[3]);
    lenx:=lenx*256+ord(buf[2]);
    lenx:=lenx*256+ord(buf[1]);
    lenx:=lenx*256+ord(buf[0]);
    End;
    i:=0;
    while i<lenx do
    Begin
    if (i+100)<lenx then
    Begin
    FileRead(fi,buf,100);
    FileWrite(fp,buf,100);
    i:=i+100;
    len:=len+100;
    End
    Else
    Begin
    FileRead(fi,buf,lenx-i);
    FileWrite(fp,buf,lenx-i);
    i:=lenx;
    len:=len+(lenx-i);
    End;
    End;
    FileClose(fi);
    end;




    ------------------------------------------------------------------------------------------------
    در نهایت تابعی به نام set_header بصورت زیر می سازیم



    procedure TForm1.set_header;
    var
    filename,str,strx:String;
    cnt,fi,i,i1,i2,ix:Integer;
    buf:array[0..100]of char;
    b1:Boolean;
    begin
    b1:=True;
    i1:=0;
    i2:=i;
    FileSeek(fp,54,0);
    buf[0]:=chr(len mod 256);
    i:=len div 256;
    buf[1]:=chr(i mod 256);
    i:=i div 256;
    buf[2]:=chr(i mod 256);
    i:=i div 256;
    buf[3]:=chr(i mod 256);
    FileWrite(fp,buf,4);
    len:=len+50;
    FileSeek(fp,4,0);
    buf[0]:=chr(len mod 256);
    i:=len div 256;
    buf[1]:=chr(i mod 256);
    i:=i div 256;
    buf[2]:=chr(i mod 256);
    i:=i div 256;
    buf[3]:=chr(i mod 256);
    buf[0] := chr(ord(buf[0]));
    buf[1] := chr(ord(buf[1]));
    buf[2] := chr(ord(buf[2]));
    buf[3] := chr(ord(buf[3]));
    FileWrite(fp,buf,4);
    end;



    با این تابع header نهایی را ایجاد می کنیم
    خب کار تمام است و شما با استفاده از این روش و طی این مراحل می توانید چند فایل wav را باهم ادغام کنید و مثلا در نرم افزار تلفن گویای خود بکار ببرید
    یک بار دیگر این مراحل را مرور می کنیم
    ابتدا دو متغیر سراسری از نوع integer با نام های Len و fp ایجاد می کنیم
    با استفاده از FileCreate یک فایل خالی در مسیر دلخواه ایجاد می کنیم
    با استفاده از Filewrite یک header به طول 58 بایت به ابتدای آن اضافه می کنیم
    حال با استفاده از تابع merg_file_wav به ترتیب فایلهایی را که می خواهیم با هم ادغام کنیم ، به فایل جدیدی که ساخته ایم اضافه می کنیم
    در نهایت با تابع set_header ، هیدر فایل را ایجاد می کنیم
    ************************************************** ****************
    شما می توانید فایلهایتان را در دیتابیس نگهداری کنید و در مواقع لزوم به ترتیب روی هارد لود کنید و عمل ادغام را انجام دهید
    یا اگر فایلهای شما بزرگ هستند و نیاز به سرعت دارید ، می توانید یک بار در ابتدای برنامه فایلها را در RAM بار گذاری کرده و به هر کدام یک نام اختصاص دهید
    =================================================
    موفق باشید.

  2. #2
    با تشکر از شما.

    فایلهای wav دیگه مثل قدیم فقط با یک فرمت PCM ساده نیستند، تو فایلهای wave اطلاعات فشرده شده به روش Mp3 هم نوشته میشه. علاوه بر اون اگر فقط فرکانس نمونه برداری یا تعداد کانال های موجود تو فایل فرق کنه، نمیشه اطلاعات خام رو کنار هم گذاشت و فقط اندازه هدر رو اصلاح کرد.

    اگه میخواید روشتون کلی باشه و یا واضح تر بشه، از msacm و از Windows Multimedia استفاده کنید. یک نمونه کامل با لیسانس آزاد از آقای خجسته تو waveaudio.zip هست که در دلفی قابل استفاده است.

    برای منظور خاص مخلوط کردن دو فایل wave سورس WaveStorage.pas رو ببینید.

  3. #3
    کاربر دائمی آواتار ali_mohamadi8928
    تاریخ عضویت
    آبان 1386
    محل زندگی
    تهران
    پست
    161
    سلام

    من کد رو توی پرژه پیاده سازی کردم ... بعد از اداغام دو فایل و ساخت هدر وقتی اومدم فایل رو پخش کنم پخش نشد ....

    اقای B-Vedadian من این کامپوننتی که معرفی کردین نصب کردم ... هر چقدر تلاش کردم نتونستم با ابزارهاش دو فایل رو ادغام کنم ... اگه امکانش هست خودتون یک لطفی کنید و یک نمونه با همین کامپوننت درست کنید و همین جا بزارید ... تا به حال چندین مبحث در این رابطه در بخش دلفی ایجاد شده که هیچ کدوم به جواب نرسیده ... اگه شما یک نمونه درست کنید طلسم این کار شکسته میشه ...

  4. #4
    کاربر دائمی آواتار babak_delphi
    تاریخ عضویت
    اردیبهشت 1384
    محل زندگی
    آستارا
    پست
    634
    من که گفتم
    برای پخش روی خط تلفن
    با مدیا پلیر پخش نمیشه
    با recordere ویندوز یا cooledit امتحان کنید جواب میده
    من دقیقا با همین روش نرم افزار نوشتم و همین الان هم کار میکنه

  5. #5
    ارسال یک کار آماده الآن برام میسر نیست. اگه با توضیحی که میدم نتونستید کار رو انجام بدید بگید یک مثال کامل بذارم.

    var
    Wave1, Wave2: TWave;
    .
    .
    .
    begin
    .
    .
    .
    Wave1.LoadFromFile(...);
    Wave2.LoadFromFile(...);
    Wave1.ConvertToPCM(Mono16bit44100Hz); // این میتونه هر فرمت دیگه ای باشه
    Wave2.ConvertToPCM(Mono16bit44100Hz);
    Wave2.Insert(0, Wave1);
    Wave2.SaveToFile(...);
    .
    .
    .
    end;


  6. #6
    کاربر دائمی آواتار ali_mohamadi8928
    تاریخ عضویت
    آبان 1386
    محل زندگی
    تهران
    پست
    161
    سلام دوست عزیز . خوشحالم که توجه داشتی به این مبحث ...

    من شیء TWaveStorage رو از اون کامپوننت گذاشتم رو صفحه و یک دکمه ایجاد کردم و کدها رو به صورت زیر توش نوشتم ... برنامه بدون هیچ خطایی اجرا شد ولی وقتی روی دکمه کلیک کردم تا عملیات انجام بشه از اون خطی که قرمزش کردم خطا گرفت و برنامه متوقف شد ... ایا روش دیگری باید به کار ببرم ... ؟ اگه لطف کنید خدتون یک مثال در این زمینه بزارید خیلی خوب میشه ...


  7. #7
    مومن خدا!
    باید اشیایی که تو دلفی تعریف میکنی حتما بسازیشون:

    // ابتدا
    w1 := TWave.Create;
    w2 := TWave.Create;
    .
    .
    .

    // انتها
    w1.Free;
    w2.Free;


    برای همین سه نقطه گذاشته بودم.

  8. #8
    کاربر دائمی آواتار ali_mohamadi8928
    تاریخ عضویت
    آبان 1386
    محل زندگی
    تهران
    پست
    161
    سلام ... خیلی ممنونم دوست عزیز ...

    باور کن اصلا حواسم نبود .... واقعا اشتباه بیخودی بود ... وقتی این پستت رو دیدم یه لحظه جا خوردم و برگشتم اون عکس رو دیدم بعد تازه دوزاریم افتاد که چه اشتباهی کرده بودم ...

    ممنونم

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •