On-line: гостей 0. Всего: 0 [подробнее..]
АвторСообщение



Пост N: 70
Зарегистрирован: 05.06.07
ссылка на сообщение  Отправлено: 26.08.08 03:23. Заголовок: Поговорим о музыке?


задумал вставить фоновую музыку.
исходник музыки - ~1Mb mp3
Стал изучать возможные варианты.

1. PLAY WAVE <cWaveName> [ FROM RESOURCE ]
играет только wav.
Преобразовал 1Мб mp3 в 11Мб wav. Включил в ресурсы.
Компилитор ругается.
>Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
>Fatal: Access violation. Link terminated.
Похоже на ограничение на размер ресурса, т.к. короткий Wav ~50kb съел без вопросов.
Это не преодолимо? Не хочется иметь отдельный файл.
Можно ли скормить команде PLAY WAVE не имя файла или ресурса, а memo-переменную
(которую загрузить BLOB-ом из базы данных)?

2.мысли - Использовать PLAYER в невидимом режиме.
Он играет mp3?
Можно ли задать ему имя ресурса или memo-переменную?
И хотя нет такого типа ресурса как mp3, можно попробовать обмануть - сказать wav, а подсунуть mp3.
Или есть тип AVI. Создать avi из одного mp3. А PLAYER играет avi?



Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 5 [только новые]


модератор




Пост N: 835
Зарегистрирован: 25.05.05
ссылка на сообщение  Отправлено: 26.08.08 16:29. Заголовок: SADSTAR2 пишет: зад..


SADSTAR2 пишет:

 цитата:
задумал вставить фоновую музыку.
исходник музыки - ~1Mb mp3



Попробуй следующий класс для проигрывания MP3-файлов:


 цитата:

/******************************************************************************
Programa: TMp3 class
Vesion: 1.0 (c) Cristobal Molla [cemese@terra.es]
******************************************************************************/

#include "hbclass.ch"
#include "directry.ch"

#define BUFFER 200
#define CRLF hb_OsNewLine()
#define TRUE .T.
#define FALSE .F.
#define MCI_MODE_UNKNOW 0
#define MCI_MODE_NOTREADY 1
#define MCI_MODE_PAUSED 2
#define MCI_MODE_PLAYING 3
#define MCI_MODE_STOPPED 4



CLASS TMp3

DATA nId INIT 0
DATA nStatus INIT 0
DATA lOpened INIT FALSE

METHOD ERROR( nError, cMetodo )
METHOD New()
METHOD Open( cFile )
METHOD Close()
METHOD Status()
METHOD Play()
METHOD Stop()

ENDCLASS



METHOD ERROR( nError, cMetodo ) CLASS TMp3

// Declaracion de variables.-------------------------------------------
LOCAL cError as character
LOCAL cTexto as character

// Inicializacion de variables.----------------------------------------
cError := Space( BUFFER )

// Muestra el mensaje de error.----------------------------------------
MCIGetErrorString( nError, @cError )
IF Empty( cError )
cTexto := "Error desconocido al ejecutar el comando "
cTexto += cMetodo + " del dispositivo MP3 " + CRLF
cTexto += CRLF
cTexto += "Cуdigo de Error: "
cTexto += hb_ValtoStr( nError )
ELSE
cTexto := "Error al ejecutar el comando "
cTexto += cMetodo + " del dispositivo MP3 " + CRLF
cTexto += CRLF
cTexto += "Cуdigo de Error: "
cTexto += hb_ValtoStr( nError ) + CRLF
cTexto += "Error: " + cError + " " + CRLF
CTexto += "Llamado desde: " + ProcName( 2 )
ENDIF
MsgInfo( cTexto, "Atenciуn" )

RETURN NIL



METHOD New() CLASS TMp3

::nId := 0
::nStatus := MCI_MODE_UNKNOW
::lOpened := FALSE

RETURN self



METHOD Open( cFile ) CLASS TMp3

// Declaracion de variables.-------------------------------------------
LOCAL cFileName as character
LOCAL nError as numeric
LOCAL cComando as character
LOCAL cReturn as character

// Control de parametros.----------------------------------------------
IF !File( cFile )
MsgInfo( "No existe el archivo " + cFile, "TMp3 Class" )
RETURN ::lOpened
ENDIF

// Inicializacion de variables.----------------------------------------
cFileName := _GetShortPathName( cFile )
cComando := "OPEN " + cFileName + " TYPE MPEGVIDEO ALIAS MP3"
cReturn := Space( BUFFER )

// Abre el fichero especificado.---------------------------------------
nError := MCISendString( cComando, @cReturn, GetActiveWindow() )
IF nError > 0
::ERROR( nError, "TMp3:Open()" )
ELSE
::nId := MCIGetDeviceId( "MP3" )
::nStatus := ::Status()
::lOpened := TRUE
ENDIF

RETURN ::lOpened



METHOD Close() CLASS TMp3

// Declaracion de variables.-------------------------------------------
LOCAL nError as numeric
LOCAL cComando as character
LOCAL cReturn as character

// Inicializacion de variables.----------------------------------------
cComando := "CLOSE MP3"
cReturn := Space( BUFFER )

// Obtiene el modo.----------------------------------------------------
nError := MCISendString( cComando, @cReturn, GetActiveWindow() )
IF nError > 0
::ERROR( nError, "TMp3:Close()" )
ELSE
::lOpened := FALSE
ENDIF

RETURN ::lOpened



METHOD Status() CLASS TMp3

// Declaracion de variables.-------------------------------------------
LOCAL nError AS NUMERIC
LOCAL cComando AS CHARACTER
LOCAL cReturn AS CHARACTER

// Inicializacion de variables.----------------------------------------
cComando := "STATUS MP3 MODE "
cReturn := Space( BUFFER )

// Obtiene el modo.----------------------------------------------------
nError := MCISendString( cComando, @cReturn, GetActiveWindow() )
IF nError > 0
::ERROR( nError, "TMp3:Status()" )
ELSE
DO CASE
CASE cReturn == "not ready"
::nStatus := MCI_MODE_NOTREADY
CASE cReturn == "paused"
::nStatus := MCI_MODE_PAUSED
CASE cReturn == "playing"
::nStatus := MCI_MODE_PLAYING
CASE cReturn == "stopped"
::nStatus := MCI_MODE_STOPPED
OTHERWISE
::nStatus := MCI_MODE_UNKNOW
ENDCASE
ENDIF

RETURN cReturn



METHOD Play() CLASS TMp3

// Declaracion de variables.-------------------------------------------
LOCAL nError
LOCAL cComando
LOCAL cReturn

// Inicializacion de variables.----------------------------------------
cComando := "PLAY MP3 FROM 1"
cReturn := Space( BUFFER )

// Obtiene el modo.----------------------------------------------------
nError := MCISendString( cComando, @cReturn, GetActiveWindow() )
IF nError > 0
::ERROR( nError, "TMp3:Play()" )
ELSE
ENDIF

RETURN NIL



METHOD Stop() CLASS TMp3

// Declaracion de variables.-------------------------------------------
LOCAL nError
LOCAL cComando
LOCAL cReturn

// Inicializacion de variables.----------------------------------------
cComando := "STOP MP3"
cReturn := Space( BUFFER )

// Obtiene el modo.----------------------------------------------------
nError := MCISendString( cComando, @cReturn, GetActiveWindow() )
IF nError > 0
::ERROR( nError, "TMp3:Stop()" )
ELSE
ENDIF

RETURN NIL


#pragma BEGINDUMP

// Ficheros de definiciones de C.
#include <windows.h>
#include <mmsystem.h>
#include <commctrl.h>
#include <winuser.h>

// Ficheros de definiciones de Harbour.
#include "hbapi.h"

/******************************************************************************
Procedimiento: MCISendString( cComando, cBuffer )
Parametros: cComando - Caracter. Comando a ejecutar.
cBuffer - Caracter. Buffer para almacenar la respuesta
del comando.
Devuelve:
Notas:
Prototipo C: MCIERROR mciSendString(
LPCTSTR lpszCommand,
LPTSTR lpszReturnString,
UINT cchReturn,
HANDLE hwndCallback
);

The mciSendString function sends a command string to an MCI
device. The device that the command is sent to is specified
in the command string.

Parameters
----------
lpszCommand
Address of a null-terminated string that specifies an MCI
command string. For more information about the command strings,
see Command Strings.

lpszReturnString
Address of a buffer that receives return information. If no
return information is needed, this parameter can be NULL.

cchReturn
Size, in characters, of the return buffer specified by the
lpszReturnString parameter.

hwndCallback
Handle of a callback window if the “notify” flag was
specified in the command string.

Return Values
-------------
Returns zero if successful or an error otherwise. The low-order
word of the returned doubleword value contains the error return
value. If the error is device-specific, the high-order word of
the return value is the driver identifier; otherwise, the
high-order word is zero. For a list of possible error values,
see Constants: MCIERR Return Values. To retrieve a text
description of mciSendString return values, pass the return
value to the mciGetErrorString function.
******************************************************************************/
HB_FUNC ( MCISENDSTRING )
{

// Declaracion de variables.-------------------------------------------
DWORD nError;
//HWND hWindow := hb_parnl( 3 );

// Envio del comando.--------------------------------------------------
nError = mciSendString( hb_parc( 1 ),
hb_parc( 2 ),
hb_parcsiz( 2 ),
(HWND) hb_parnl( 3 ) );

// Control de error.---------------------------------------------------
hb_retni( nError );

}



/******************************************************************************
Procedimiento: MCIGetErrorString( nError, @cError )
Parametros: nError - Numerico. Numero del error devuelto por
mciSendCommand() o mciSendString().
cError - Cadena de caracteres con el texto
descriptivo del error. Inicializada. Pasada
por referencia.
Devuelve: lError - Logico. Verdadero si se encontro la
descripcion del error, falso en caso
contrario
Notas: Devuelve la descripcion de error al enviar un comando MCI.
Prototipo C: BOOL mciGetErrorString(
DWORD fdwError,
LPTSTR lpszErrorText,
UINT cchErrorText
);

The mciGetErrorString function retrieves a string that
describes the specified MCI error code.

Parameters
----------
fdwError
Error code returned by the mciSendCommand or mciSendString
function.

lpszErrorText
Address of a buffer that receives a null-terminated string
describing the specified error.

cchErrorText
Length of the buffer, in characters, pointed to by the
lpszErrorText parameter.

Return Values
-------------
Returns TRUE if successful or FALSE if the error code is not
known.
******************************************************************************/
HB_FUNC ( MCIGETERRORSTRING )
{

// Devuelve la descripcion del error.----------------------------------
hb_retl( mciGetErrorString( hb_parni( 1 ), hb_parc( 2 ), hb_parcsiz( 2 ) ) );

}



/******************************************************************************
Procedimiento: MCIGetDeviceID()
Parametros: cDispositivo - Caracter. Nombre del dispositivo o del alias
abierto satisfactoriamente.
Devuelve: El identificador con el nombre del dispositivo o su
alias o cero si no esta abierto.
Notas: Obtiene el identifiacdor de un dispositivo MCI.
Prototipo C: MCIDEVICEID mciGetDeviceID(
LPCTSTR lpszDevice
);

The mciGetDeviceID function retrieves the device identifier
corresponding to the name of an open device.

Parameters
----------
lpszDevice
Address of a null-terminated string that specifies the device
name or the alias name by which the device is known.

Return Values
-------------
Returns the device identifier assigned to the device when it
was opened if successful. The identifier is used in the
mciSendCommand function. If the device name is not known, if
the device is not open, or if there was not enough memory to
complete the operation, the return value is zero.
******************************************************************************/
HB_FUNC ( MCIGETDEVICEID )
{

// Obtiene el ID del dispositivo o alias MCI.
hb_retni( mciGetDeviceID( hb_parc( 1 ) ) );

}

#pragma ENDDUMP



Тестовый пример для этого класса:


 цитата:
#include "minigui.ch"

Set Proc To tmp3.prg

PROCEDURE Main()

LOCAL oMp3 := TMp3():New()

DEFINE window wndMain ;
at 0, 0 ;
width getdesktopwidth() ;
height getdesktopheight() - 27 ;
title "MP3 Test" ;
main

DEFINE main menu
DEFINE popup "&Test MP3"
menuitem " Open MP3 file and device" ;
action {|| if( !oMp3:lOpened, ;
oMp3:Open( getFile( { { "MP3", "*.mp3" } }, "Select File", CurDir(), FALSE, TRUE ) ), ) }
menuitem " oMp3:Status()" ;
action {|| if( oMp3:lOpened, MsgInfo( oMp3:Status() ), ) }
menuitem " oMp3:Play()" ;
action {|| if( oMp3:lOpened, oMp3:Play(), ) }
menuitem " oMp3:Stop()" ;
action {|| if( oMp3:lOpened, oMp3:Stop(), ) }
menuitem " oMp3:Close()" ;
action {|| if( oMp3:lOpened, oMp3:Close(), ) }
END popup
END menu
END window

activate window wndMain

RETURN




Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 71
Зарегистрирован: 05.06.07
ссылка на сообщение  Отправлено: 27.08.08 06:23. Заголовок: Большое спасибо. Игр..


Большое спасибо. Играет.
Обычный PLAYER тоже играет mp3. И в режиме HIDE - как я и расчитывал.
Но музыку берут оба из файла на диске.
А я хотел из памяти.

Нашел страницу с решением похожей задачи.
http://www.firststeps.ru/mfc/mci/r.php?8

Но я практически не секу в Си.
Может ты сможешь переложить это на Харборовский язык?


Спасибо: 0 
ПрофильЦитата Ответить
модератор




Пост N: 836
Зарегистрирован: 25.05.05
ссылка на сообщение  Отправлено: 27.08.08 11:56. Заголовок: SADSTAR2 пишет: пер..


SADSTAR2 пишет:

 цитата:
переложить это на Харборовский язык?



SADSTAR2 пишет:

 цитата:
Обычный PLAYER тоже играет mp3.



Изменения, которые можно внести в source\c_media.c

HB_FUNC( C_PLAYWAVE )
{
int Style = SND_ASYNC;
HMODULE hmod = NULL;
if( hb_parl(2) )
{
Style = Style | SND_MEMORY;
}
else
{
Style = Style | SND_FILENAME;
}

if( hb_parl(3) )
{
Style = Style | SND_SYNC;
}

if( hb_parl(4) )
{
Style = Style | SND_NOSTOP;
}

if( hb_parl(5) )
{
Style = Style | SND_LOOP;
}

if( hb_parl(6) )
{
Style = Style | SND_NODEFAULT;
}

hb_retl( PlaySound(hb_parc(1), hmod, Style) );
}

и затем использовать стандартную команду

SADSTAR2 пишет:

 цитата:
PLAY WAVE <cWaveName> FROM RESOURCE



Также не забудь загрузить весь проигрываемый файл в память
Например, с помощью функции MemoRead()

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 72
Зарегистрирован: 05.06.07
ссылка на сообщение  Отправлено: 29.08.08 03:42. Заголовок: Ок. Отладочный вариа..


Ок.
Отладочный вариант работает.
Загрузил wav-ы в базу sqlite. Извлекаю. Запускаю проигрывание. Останавливаю.

Огорчает то, что база с примерно 2.5 МегБ распухла до 17.
И ведь в ней большей частью - "воздух".

Рассматривал идею сжать wav-ы zip-ом и разжимать перед воспроизведением.
Но все zip-ы работают только через файлы на диске.
А нужно чтобы только в памяти из одной переменной в другую перекодировал.

Склоняюсь к мысли, что меньший размер важнее чистоты алгоритма.
Т.е. хранить в базе mp3 и играть обычным плэйером из временного файла.

Или может кто сгенерирует идею как подсунуть обычному PLAYER-у не файл а memo-переменную для проигрывания содержимого?


Спасибо: 0 
ПрофильЦитата Ответить



Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 30.08.08 18:08. Заголовок: Использование ресурса


В ресурс можно включать любые файлы. Размер файла до 1 Mb.
Извлечь ресурс в файл можно мспользуя функции API.
Ниже пример.


// RESTOFILE(cFileExe, cNameRes, cTypeRes, cFileOut)
// cFileExe - файл с ресурсом
// cNameRes - имя ресурса
// cTypeRes - тип ресурса
// cFileOut - выходн. файл

// RESTOFILE( , "MP3_1", "MP3DATA", "1.mp3")


#include <windows.h>
#include "hbapi.h"

HB_FUNC(RESTOFILE)

{
HRSRC hResLoad;
HANDLE hExe;
HRSRC hRes;
HANDLE File ;
LPVOID pData;
DWORD dwSize;
DWORD Written;
int iRet=0;

if(hb_parc( 1 ) == NULL)
{
hExe = GetModuleHandle(NULL);
}
else
{
hExe = LoadLibrary(hb_parc( 1 ));
if(hExe == NULL)
{
iRet=1;
}
}
if(iRet==0)
{
hRes = FindResource(hExe, hb_parc( 2 ), hb_parc( 3 ));
if (hRes == NULL)
{
iRet=2;
}
}

if(iRet==0)
{
hResLoad = LoadResource(hExe, hRes);
if (hResLoad == NULL)
{
iRet=3;
}
}

if(iRet==0)
{
dwSize = SizeofResource(hExe,hRes);
if(dwSize == NULL)
{
iRet=4;
}
}

if(iRet==0)
{
pData = LockResource(hResLoad);
if(pData == NULL)
{
iRet=5;
}
}

if(iRet==0)
{
File = CreateFile(hb_parc( 4 ),GENERIC_WRITE,FILE_SHARE_WRITE,0,OPEN_ALWAYS,0,0);
if(File == INVALID_HANDLE_VALUE)
{
iRet=6 ;
}
}

if(iRet==0)
{
Written=0;
if(WriteFile(File,pData,dwSize,&Written,0)==NULL)
{
iRet=7;
}
}

CloseHandle(File);
FreeLibrary(hExe);
hb_retni(iRet);

}



Спасибо: 0 
Цитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 30
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет