Обновить
179
0.5

Человек

Отправить сообщение

И какое это отношение имеет ко мне и к обсуждаемой теме?

Наверно такое, что вы сами же эту тему и начали. А статья так-то про рисование.

Да, потому что гитарные мелодии оформляют в виде гитарных же аккордов

Нет, не бывает гитарных аккордов, бывает только аппликатуры аккордов для гитар с конкретным строем. Сами же последовательности аккордов описывают не мелодию, а гармонию. Под одну и ту же гармонию существуют тысячи разных мелодий.

А почему именно эта задача для вас является показательной?

Потому что лунную сонату неоднократно слышал каждый - помимо того, что это просто популярная тема, она входит в общеобразовательную школьную программу. Если человек действительно достаточно талантлив, чтобы не иметь потребности уметь читать и писать - то должен суметь легко сыграть её просто по памяти.

И я не программист

А берётесь рассуждать о том, что ООП не нужен. Не музыкант, а берётесь рассуждать о том, что нотная грамота не нужна.

Ваш родственник может сыграть конкретно "лунную сонату"? Ваша жена сможет опубликовать мелодию своей песни в книжке, чтобы её смогли другие, незнакомые лично с ней люди исполнить? А переложить на другой инструмент или аранжировать для банды/оркестра? Вы сам, как программист, сможете запрограммировать эту мелодию в программе?

P.S. Я - да.

Я в принципе не понимаю зачем мне знать ноты для игры на гитаре например.

Ноты нужны для того, чтобы играть на гитаре музыку, а не петь дворовые песни под аккомпанемент боем. И не обязательно классику уровня "Лунная соната" - это могут быть инструментальные версии рок/поп/диско/техно/... песен, узнаваемая музыка из фильмов типа "Star Wars", "Terminator", "Mortal Combat", и даже из компьютерных игр вроде "Super Mario".

0 - это ноль герц, постоянная составляющая и заодно центр оси. Просто поскольку дискретное преобразование Фурье периодическое, вводить туда отрицательную координату необязательно. А вот в непрерывном преобразовании она уже есть, есть частота со знаком плюс, и есть та же самая частота со знаком минус. Контринтуитивно, да.

Я первый раз в жизни вижу человека, который вот прямо настолько заморачивается на придумывание оправданий, вместо того, чтобы 40 лет назад просто сказать самому себе "мне это не надо", закрыть этот вопрос и не вспоминать никогда.

А для тех, кто в противоположном танке, я тоже повторю свою тезис: если мне на что-то надо 40 лет, и мне это действительно надо - я положу на это 40 лет без всякого сожаления. И вообще неинтересно, сколько лет на это понадобилось каким-то другим людям. И если кто-то что-то осваивает быстрее - это ещё вовсе не значит, что он добьётся в этом большего успеха.

В Mathematica индексация с 1 вполне обоснована - в индексе 0 хранится тип.

{1, 2, 3}[[0]]
List
{1, 2, 3}[[1]]
1

Ну и в целом, 1 - это порядковый номер, а 0 - смещение относительно какого-то адреса.

Ну то есть таблицу умножения вы освоили, а считать до 5 (именно столько линеек в стандартном нотном стане) почему-то вызывает непреодолимые сложности. Цифр 10, а нот всего 7. Букв 33, а нот всего 7 (ну или 12, если брать полную хроматическую гамму. 12-ричная система тоже стандарт, для времени используется повсеместно). Нет надписей на клавишах или грифе - так можно сделать, нормальная практика для начинающих. Не понимаете "до ре ми.." - пишите 0,1,2..., конкретные значения частот в логарифмической шкале. Не получается что-то освоить самостоятельно - надо идти заниматься с преподавателем, тоже вполне нормальная практика, абсолютно в любой сфере деятельности. Который заодно и объяснит, зачем нужно знать ноты и гаммы.

Кто хочет, ищет возможности, кто не хочет - ищет оправдания. Банальная истина, которая из-за своей банальности не перестала быть менее истинной.

Передавать звук по радио в наушники с костной проводимостью? Да не, бред какой-то. Давайте лучше направленным ультразвуком высокой мощности фигачить.

Сам по себе ООП ничего не решает. Решает декомпозиция и построение архитектуры, которая может быть как удачной и снижающей сложность, так и прямо наоборот.

Вот например есть стандарт для написания аудио-плагинов VST, SDK для готового сделан в типичном процедурном стиле. И вот пример плагина для задержки звука непосредственно из документации:

adelaymain.cpp
//-------------------------------------------------------------------------------------------------------
// VST Plug-Ins SDK
// Version 2.4		$Date: 2005/11/30 13:04:21 $
//
// Category     : VST 2.x SDK Samples
// Filename     : adelaymain.cpp
// Created by   : Steinberg Media Technologies
// Description  : Simple Delay plugin (Mono->Stereo)
//
// © 2005, Steinberg Media Technologies, All Rights Reserved
//-------------------------------------------------------------------------------------------------------

#ifndef __adelay__
#include "adelay.h"
#endif

//-------------------------------------------------------------------------------------------------------
AudioEffect* createEffectInstance (audioMasterCallback audioMaster)
{
	return new ADelay (audioMaster);
}

adelay.h
//-------------------------------------------------------------------------------------------------------
// VST Plug-Ins SDK
// Version 2.4		$Date: 2005/12/06 09:09:26 $
//
// Category     : VST 2.x SDK Samples
// Filename     : adelay.h
// Created by   : Steinberg Media Technologies
// Description  : Simple Delay plugin (Mono->Stereo)
//
// © 2005, Steinberg Media Technologies, All Rights Reserved
//-------------------------------------------------------------------------------------------------------

#ifndef __adelay__
#define __adelay__

#include "public.sdk/source/vst2.x/audioeffectx.h"

#pragma comment(linker, "/OPT:NOWIN98")

enum
{
	// Global
	kNumPrograms = 16,

	// Parameters Tags
	kDelay = 0,
	kFeedBack,
	kOut,

	kNumParams
};

class ADelay;

//------------------------------------------------------------------------
class ADelayProgram
{
friend class ADelay;
public:
	ADelayProgram ();
	~ADelayProgram () {}

private:	
	float fDelay;
	float fFeedBack;
	float fOut;
	char name[24];
};

//------------------------------------------------------------------------
class ADelay : public AudioEffectX
{
public:
	ADelay (audioMasterCallback audioMaster);
	~ADelay ();

	virtual void processReplacing (float **inputs, float **outputs, VstInt32 sampleFrames);

	virtual void setProgram (long program);
	virtual void setProgramName (char *name);
	virtual void getProgramName (char *name);
	virtual bool getProgramNameIndexed (VstInt32 category, VstInt32 index, char* text);
	
	virtual void setParameter (VstInt32 index, float value);
	virtual float getParameter (VstInt32 index);
	virtual void getParameterLabel (VstInt32 index, char *label);
	virtual void getParameterDisplay (VstInt32 index, char *text);
	virtual void getParameterName (VstInt32 index, char *text);

	virtual void resume ();

	virtual bool getEffectName (char* name);
	virtual bool getVendorString (char* text);
	virtual bool getProductString (char* text);
	virtual VstInt32 getVendorVersion () { return 1000; }
	
	virtual VstPlugCategory getPlugCategory () { return kPlugCategEffect; }

protected:
	void setDelay (float delay);

	ADelayProgram *programs;
	
	float *buffer;
	float fDelay, fFeedBack, fOut;
	
	
	long delay;
	long size;
	long cursor;
};

#endif

adelay.cpp
//-------------------------------------------------------------------------------------------------------
// VST Plug-Ins SDK
// Version 2.4		$Date: 2005/11/30 13:04:21 $
//
// Category     : VST 2.x SDK Samples
// Filename     : adelay.cpp
// Created by   : Steinberg Media Technologies
// Description  : Simple Delay plugin (Mono->Stereo)
//
// © 2005, Steinberg Media Technologies, All Rights Reserved
//-------------------------------------------------------------------------------------------------------

#include <stdio.h>
#include <string.h>

#ifndef __adelay__
#include "adelay.h"
#endif

//----------------------------------------------------------------------------- 
ADelayProgram::ADelayProgram ()
{
	// default Program Values
	fDelay = 0.5;
	fFeedBack = 0.5;
	fOut = 0.75;

	strcpy (name, "Init");
}

//-----------------------------------------------------------------------------
ADelay::ADelay (audioMasterCallback audioMaster)
	: AudioEffectX (audioMaster, kNumPrograms, kNumParams)
{
	// init
	size = 44100;
	cursor = 0;
	delay = 0;
	buffer = new float[size];
	
	programs = new ADelayProgram[numPrograms];
	fDelay = fFeedBack = fOut = 0;

	if (programs)
		setProgram (0);

	setNumInputs (1);	// mono input
	setNumOutputs (2);	// stereo output

	setUniqueID (*ADly*);

	resume ();		// flush buffer
}

//------------------------------------------------------------------------
ADelay::~ADelay ()
{
	if (buffer)
		delete[] buffer;
	if (programs)
		delete[] programs;
}

//------------------------------------------------------------------------
void ADelay::setProgram (long program)
{
	ADelayProgram* ap = &programs[program];

	curProgram = program;
	setParameter (kDelay, ap->fDelay);	
	setParameter (kFeedBack, ap->fFeedBack);
	setParameter (kOut, ap->fOut);
}

//------------------------------------------------------------------------
void ADelay::setDelay (float fdelay)
{
	fDelay = fdelay;
	programs[curProgram].fDelay = fdelay;
	cursor = 0;
	delay = (long)(fdelay * (float)(size - 1));
}

//------------------------------------------------------------------------
void ADelay::setProgramName (char *name)
{
	strcpy (programs[curProgram].name, name);
}

//------------------------------------------------------------------------
void ADelay::getProgramName (char *name)
{
	if (!strcmp (programs[curProgram].name, "Init"))
		sprintf (name, "%s %d", programs[curProgram].name, curProgram + 1);
	else
		strcpy (name, programs[curProgram].name);
}

//-----------------------------------------------------------------------------------------
bool ADelay::getProgramNameIndexed (VstInt32 category, VstInt32 index, char* text)
{
	if (index < kNumPrograms)
	{
		strcpy (text, programs[index].name);
		return true;
	}
	return false;
}

//------------------------------------------------------------------------
void ADelay::resume ()
{
	memset (buffer, 0, size * sizeof (float));
	AudioEffectX::resume ();
}

//------------------------------------------------------------------------
void ADelay::setParameter (VstInt32 index, float value)
{
	ADelayProgram* ap = &programs[curProgram];

	switch (index)
	{
		case kDelay :    setDelay (value);					break;
		case kFeedBack : fFeedBack = ap->fFeedBack = value; break;
		case kOut :      fOut = ap->fOut = value;			break;
	}
}

//------------------------------------------------------------------------
float ADelay::getParameter (VstInt32 index)
{
	float v = 0;

	switch (index)
	{
		case kDelay :    v = fDelay;	break;
		case kFeedBack : v = fFeedBack; break;
		case kOut :      v = fOut;		break;
	}
	return v;
}

//------------------------------------------------------------------------
void ADelay::getParameterName (VstInt32 index, char *label)
{
	switch (index)
	{
		case kDelay :    strcpy (label, "Delay");		break;
		case kFeedBack : strcpy (label, "FeedBack");	break;
		case kOut :      strcpy (label, "Volume");		break;
	}
}

//------------------------------------------------------------------------
void ADelay::getParameterDisplay (VstInt32 index, char *text)
{
	switch (index)
	{
		case kDelay :    int2string (delay, text, kVstMaxParamStrLen);			break;
		case kFeedBack : float2string (fFeedBack, text, kVstMaxParamStrLen);	break;
		case kOut :      dB2string (fOut, text, kVstMaxParamStrLen);			break;
	}
}

//------------------------------------------------------------------------
void ADelay::getParameterLabel (VstInt32 index, char *label)
{
	switch (index)
	{
		case kDelay :    strcpy (label, "samples");	break;
		case kFeedBack : strcpy (label, "amount");	break;
		case kOut :      strcpy (label, "dB");		break;
	}
}

//------------------------------------------------------------------------
bool ADelay::getEffectName (char* name)
{
	strcpy (name, "Delay");
	return true;
}

//------------------------------------------------------------------------
bool ADelay::getProductString (char* text)
{
	strcpy (text, "Delay");
	return true;
}

//------------------------------------------------------------------------
bool ADelay::getVendorString (char* text)
{
	strcpy (text, "Steinberg Media Technologies");
	return true;
}

//---------------------------------------------------------------------------
void ADelay::processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames)
{
	float* in = inputs[0];
	float* out1 = outputs[0];
	float* out2 = outputs[1];

	while (--sampleFrames >= 0)
	{
		float x = *in++;
		float y = buffer[cursor];
		buffer[cursor++] = x + y * fFeedBack;
		if (cursor >= delay)
			cursor = 0;
		*out1++ = x;
		*out2++ = y;
	}
}

А вот тот же самый по функциональности плагин из моего SDK, построенного на ООП:

Delay.cs
using System;
using ES.Dsp.Modules.Core;

namespace ES.Dsp.Modules
{
    [Serializable]
    public class Delay : Module
    {
        [NonSerialized] double[] delayline;
        [NonSerialized] int readpos = 0;
        [NonSerialized] int writepos = 0;

        private int maxDelay = 48000;
        public int MaxDelaySamples
        {
            get { return maxDelay; }
            set { lock (GlobalLocker) { maxDelay = Math.Max(1, value); Init(); } }
        }

        // конструктор
        public Delay() : base(3, 1) // количество входов и выходов
        {
            CommentIn[0] = "in";
            CommentIn[1] = "dly";
            CommentIn[2] = "feedback";
            CommentOut[0] = "out";
            Input[1].Value = maxDelay; // задержка по-умолчанию
            Input[2].Value = 0.5; // резонанс по-умолчанию
            Init();
        }

        // инициализация несохраняемых полей
        public override void Init()
        {
            if (delayline == null)
                delayline = new double[maxDelay + 1];
            if (delayline.Length != maxDelay + 1)
                delayline = new double[maxDelay + 1];
        }

        // сброс параметров 
        public override void Reset()
        {
            Array.Clear(delayline, 0, delayline.Length);
            readpos = 0;
            writepos = 0;
            Output[0].Value = 0.0;
        }

        // обработка потока
        public override void Process()
        {
            int delay = Math.Max(0, Math.Min(MaxDelaySamples, (int)Input[1].Value));
            readpos = (writepos - delay + delayline.Length) % delayline.Length;
            double feedback = Input[2].Value;
            double sample = Input[0].Value + feedback * delayline[readpos];
            delayline[writepos] = sample;
            Output[0].Value = sample;
            writepos = (writepos + 1) % delayline.Length;
        }
    }
}

Даже чисто по объёму кода в 5 раз меньше.

Про ненормальность никто и не говорил. ООП, как парадигма программирования, позволяет преодолеть уровень сложности, который обычное процедурное не позволяет. И мне оно тоже далось не просто, и не за 15 минут и даже не за 5 лет - хотя в институте был отдельный курс, ему посвящённый. А мой любимый язык программирования до сих пор - это ассемблер, и даже плагин для вижуал студии для него писал (в ООП парадигме, разумеется). А любимая парадигма программирования - dataflow, хорошо известная схемотехникам и программистам промышленных контроллеров.

Говорю глупости я, но проблемы с гитарой, математикой и пониманием ООП - таки у вас, а не у меня. Может, не такие это и глупости?

Просто автор и вы планку сдвигаете произвольно, на ваше усмотрение, завышая требования

Правило "10 000 часов" придумано не мной, а 10 лет обучения в школе даже является стандартом в стране где я живу. Я не вижу здесь никаких завышенных требований.

Комментарии - это и не общение, а просто обсуждение идей. "10 лет тратить на освоение гитары я точно не стану ) это бред" - это же ваши слова?

Научиться играть кузнечика на гитаре тоже может каждый за 15 минут, вот что я хотел сказать. И если для кого-то этот уровень окажется достаточным, чтобы считать, что он освоил инструмент - ну значит ему этого действительно достаточно. А вот делать выводы о талантах и предрасположенности к чему-либо всё-таки рановано.

Какая связь между "научиться ездить" и "свободная езда"?

Ну а что значить тогда "научиться ездить"? Проехать 5 метров и не упасть?

Никогда не ездил дальше 5 км, поэтому не знаю что вам об этом сказать. Но мои слова про освоение велосипеда за 15 минут с вашими 50 км никак не связаны.

Связаны также, как и "никогда не играл ничего сложнее кузнечика, но считаю, что гитару освоил".

Где я сказал что я хочу всё и сразу?

Про 15 минут на велосипеде, и что именно примерно столько надо для освоения чего угодно. Ну а мне 2 года понадобилась для свободной езды и 50-км заездов без перерывов. Ну да, все люди разные, и то что одним даётся легко, другим даётся лишь ценой невероятных усилий. Но если бросать любую деятельность спустя 15 минут как ничего не получилось - так ничего никогда и не получится.

У меня тоже многие знакомые осваивали гитару в разы быстрее. Вот только как быстро освоили - так же быстро и забросили и дальше стандартных дворовых песен 30-летней давности не продвинулись. "Научиться играть" вообще невозможно - всегда есть куда развиваться, и в технике, и в репертуаре, и в композиции, и в эмоциональной отдаче.

10 лет тратить на освоение гитары я точно не стану ) это бред. на велосипеде я научился кататься за 15 минут, на коньках за 30 минут, на машине за 2 занятия

Ну так о чём и речь. Вы хотели всё и сразу, но всё и сразу не получилось. А читать, писать, и высшую математику вы тоже самостоятельно за 15 минут освоили?

я точно знаю что я не могу освоить музыку

А вы занимались с настоящим (живым) преподавателем с настоящим (высшим) музыкальным образованием или как? Чтобы играть на муз.инструменте особый талант не нужен, миллионы выпускников музыкальных школ тому подтверждение. Нужно терпение и труд сквозь боль, пот, слёзы и удары палкой по голове. А так ситуация довольно распространённая - играть на гитаре хотят многие, а вот учиться играть, задрачивая гаммы и упражнения (и под метроном) по вечерам вместо залипания в тиктоки/интернеты/компьютерные игры - не хочет примерно никто.

P.S. моя путь с этого и начался - в 16 лет знакомая тётенька с муз.образованием меня прослушала и вынесла вердикт - слуха нет, чувства ритма нет, шансов ноль. Но поскольку она сама продемонстрировать виртуозное исполнение тоже не смогла, её вердикт я пропустил мимо ушей. А спустя 10 лет уже сам мог делать переложения той музыки, которая нравится, и папка с собственноручно набранными и распечатанными нотами перевалила за несколько сотен.

удовольствия не меньше доставляет

Удовольствия тебе или слушателю? Это принципиальный вопрос, и рисования тоже касается. Статей подобного рода на пикабу навалом, и как эта на пробралась на хабр непонятно, поскольку художественной ценностью представленные здесь изображения не обладают. Уровень - это когда твою картинку увидели и захотели забрать (про купить даже и не говорю), без какой-либо предварительной рекламы.

У нас в одном из ТЦ художники устраивают еженедельные встречи и рисуют с натуры случайных людей (с их согласия). После модель может забрать одну работу, которая понравилась больше всех. Вот такой формат более объективно показывает разницу между было-стало.

Информация

В рейтинге
2 068-й
Откуда
Россия
Работает в
Зарегистрирован
Активность